동적 리소스 할당(DRA)은 파드와 컨테이너 전반에 걸쳐 희소한 리소스를 관리하기 위한 쿠버네티스 API입니다. 이는 단순히 N개의 장치를 할당하는 것을 넘어, 보다 세분화된 사용 시나리오를 지원하기 위한 유연한 리소스 요청을 가능하게 합니다. DRA를 통해 사용자는 속성에 기반하여 특정 유형의 장치를 요청하고, 워크로드에 맞춰 사용자 정의 구성을 정의하며, 심지어 동일한 리소스를 여러 컨테이너나 파드 간에 공유할 수도 있습니다.
이 블로그에서는 장치 공유 기능에 초점을 맞추고, 쿠버네티스 1.34에 도입된 새로운 기능인 'DRA 소비 가능한 용량'에 대해 자세히 살펴봅니다. 이는 DRA를 확장하여 더욱 세분화된 장치 공유를 지원합니다.
배경: ResourceClaim을 통한 장치 공유
DRA는 처음부터 여러 파드가 동일한 ResourceClaim을 참조하여 장치를 공유할 수 있는 기능을 도입했습니다. 이 설계는 리소스 할당을 특정 하드웨어로부터 분리하여, 더욱 동적이고 재사용 가능한 장치 프로비저닝을 가능하게 합니다.
쿠버네티스 1.33에서는 분할 가능한 장치에 대한 새로운 지원이 도입되어, 리소스 드라이버가 전체 장치를 전체 또는 전무(all-or-nothing)한 리소스로 노출하는 대신 사용 가능한 장치의 슬라이스를 광고할 수 있게 되었습니다. 이는 쿠버네티스가 공유 가능한 하드웨어를 더 정확하게 모델링할 수 있도록 했습니다.
하지만 여전히 빠진 조각이 있었습니다. 장치 드라이버가 사용자 수요에 따라 네트워크 대역폭과 같이 세분화되고 동적인 장치 리소스 부분을 관리하거나, 리소스클레임(ResourceClaim)의 스펙과 네임스페이스에 의해 제한되는 것과 독립적으로 해당 리소스를 공유하는 시나리오를 지원하지 못했습니다.
바로 이 지점에서 DRA의 소비 가능한 용량이 등장합니다.
DRA 소비 가능한 용량 지원의 이점
다음은 DRAConsumableCapacity 피처 게이트가 활성화된 클러스터에서 얻을 수 있는 이점들입니다.
여러 ResourceClaim 또는 DeviceRequest에 걸친 장치 공유
이제 리소스 드라이버는 동일한 장치(또는 장치의 슬라이스)를 여러 ResourceClaim이나 여러 DeviceRequest에 걸쳐 공유하는 것을 지원할 수 있습니다.
이는 서로 다른 네임스페이스의 파드도 특정 DRA 드라이버가 허용하고 지원한다면 동시에 동일한 장치를 공유할 수 있음을 의미합니다.
장치 리소스 할당
쿠버네티스는 스케줄러의 할당 알고리즘을 확장하여 capacity 필드에 정의된 장치 리소스의 일부를 할당하는 것을 지원합니다. 스케줄러는 여러 ResourceClaim이나 DeviceRequest에 걸쳐 공유되는 경우에도 모든 소비자에게 할당된 총 용량이 장치의 총 용량을 초과하지 않도록 보장합니다. 이는 스케줄러가 파드와 컨테이너가 노드의 할당 가능한 리소스를 공유하도록 허용하는 방식과 매우 유사합니다. 이 경우, 장치에서 할당 가능한(소비 가능한) 리소스를 공유하도록 허용하는 것입니다.
이 기능은 장치 드라이버가 장치 내부의 리소스를 프로세스별로 관리할 수 있는 시나리오에 대한 지원을 확장합니다. 예를 들어, 가상 GPU에서 특정 양의 메모리(예: 8GiB)를 할당하거나 특정 파드에 할당된 가상 네트워크 인터페이스에 대역폭 제한을 설정하는 경우 등이 있습니다. 이는 안전하고 효율적인 리소스 공유를 제공하는 것을 목표로 합니다.
DistinctAttribute 제약 조건
이 기능은 또한 새로운 제약 조건인 DistinctAttribute를 도입합니다. 이는 기존의 MatchAttribute 제약 조건의 보완적인 역할을 합니다.
DistinctAttribute의 주요 목표는 단일 ResourceClaim 내에서 동일한 기본 장치가 여러 번 할당되는 것을 방지하는 것입니다. 이는 장치의 공유 부분(또는 하위 집합)을 할당하기 때문에 발생할 수 있는 상황입니다. 이 제약 조건은 각 할당이 동일한 장치 클래스에 속하더라도 고유한 리소스를 참조하도록 보장합니다.
이는 커버리지를 확장하거나 장애 도메인 전반에 걸쳐 이중화를 제공하기 위해 서로 다른 서브넷에 연결된 네트워크 장치를 할당하는 것과 같은 사용 사례에 유용합니다.
소비 가능한 용량을 사용하는 방법?
DRAConsumableCapacity는 쿠버네티스 1.34에서 알파 기능으로 도입되었습니다. 피처 게이트 DRAConsumableCapacity는 kubelet, kube-apiserver, kube-scheduler 및 kube-controller-manager에서 활성화되어야 합니다.
--feature-gates=...,DRAConsumableCapacity=true
DRA 드라이버 개발자로서
Golang으로 코드를 작성하는 DRA 드라이버 개발자로서, AllowMultipleAllocations를 true로 설정하여 ResourceSlice 내의 장치를 여러 ResourceClaim(또는 devices.requests)에 할당 가능하도록 만들 수 있습니다.
Device {
...
AllowMultipleAllocations: ptr.To(true),
...
}
또한, DeviceCapacity 내의 RequestPolicy 필드를 정의하여 각 DeviceRequest가 각 장치의 Capacity를 어떻게 소비해야 하는지에 대한 정책을 제한할 수 있습니다. 아래 예시는 40GiB 메모리를 가진 GPU가 요청당 최소 5GiB를 할당하고, 각 할당이 5GiB의 배수로 이루어지도록 하는 정책을 정의하는 방법을 보여줍니다.
DeviceCapacity{
Value: resource.MustParse("40Gi"),
RequestPolicy: &CapacityRequestPolicy{
Default: ptr.To(resource.MustParse("5Gi")),
ValidRange: &CapacityRequestPolicyRange {
Min: ptr.To(resource.MustParse("5Gi")),
Step: ptr.To(resource.MustParse("5Gi")),
}
}
}
이는 아래에 부분적으로 표시된 것처럼 ResourceSlice에 게시됩니다.
apiVersion: resource.k8s.io/v1
kind: ResourceSlice
...
spec:
devices:
- name: gpu0
allowMultipleAllocations: true
capacity:
memory:
value: 40Gi
requestPolicy:
default: 5Gi
validRange:
min: 5Gi
step: 5Gi
지정된 소비 용량 부분이 있는 할당된 장치는 할당 상태에 ShareID 필드가 설정됩니다.
claim.Status.Allocation.Devices.Results[i].ShareID
이 ShareID는 드라이버가 동일한 장치 또는 동일하게 정적으로 분할된 슬라이스를 참조하지만 다른 ResourceClaim 요청에서 비롯된 여러 할당을 구분할 수 있도록 합니다. 이는 각 공유 슬라이스에 대한 고유 식별자 역할을 하여, 드라이버가 여러 소비자에게 걸쳐 독립적으로 리소스 제한을 관리하고 적용할 수 있도록 합니다.
소비자로서
소비자(또는 사용자)로서 장치 리소스는 다음과 같이 ResourceClaim을 통해 요청할 수 있습니다.
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
...
spec:
devices:
requests: # 장치에 대한 요청
- name: req0
exactly:
deviceClassName: resource.example.com
capacity:
requests: # 해당 장치에서 제공되어야 하는 리소스에 대한 요청
memory: 10Gi
이 구성은 요청된 장치가 최소 10GiB의 memory를 제공할 수 있도록 보장합니다.
주목할 점은 최소 10GiB의 메모리를 가진 어떤 resource.example.com 장치라도 할당될 수 있다는 것입니다. 만약 여러 할당을 지원하지 않는 장치가 선택된다면, 할당은 장치 전체를 소비하게 됩니다. 여러 할당을 지원하는 장치만 필터링하려면 다음과 같이 셀렉터를 정의할 수 있습니다.
selectors:
- cel:
expression: |-
device.allowMultipleAllocations == true
DRA 장치 상태와의 통합
장치 공유에서 일반적인 장치 정보는 리소스 슬라이스(ResourceSlice)를 통해 제공됩니다. 그러나 일부 세부 정보는 할당 후에 동적으로 설정됩니다. 이러한 정보는 ResourceClaim의 status.devices 필드를 사용하여 전달될 수 있습니다. 해당 필드는 DRAResourceClaimDeviceStatus 피처 게이트가 활성화된 클러스터에서만 게시됩니다.
만약 장치 상태 지원을 사용할 수 있다면, 드라이버는 ShareID 외에 추가적인 장치별 정보를 노출할 수 있습니다. 특히 유용한 사용 사례는 가상 네트워크에서 드라이버가 할당된 IP 주소를 상태에 포함시킬 수 있다는 점입니다. 이는 네트워크 서비스 운영과 문제 해결 모두에 유용합니다.
더 자세한 정보는 다음 녹화본을 시청하여 확인할 수 있습니다: KubeCon Japan 2025 - 클라우드 네이티브 네트워크 재구상: DRA의 중요 역할.
다음으로 무엇을 할 수 있을까요?
- **CNI DRA 드라이버 프로젝트**에서 쿠버네티스 네트워킹의 DRA 통합 예시를 확인해 보세요.
macvlan,ipvlan, 스마트 NIC와 같은 네트워크 리소스와 통합을 시도해 보세요. DRAConsumableCapacity피처 게이트를 활성화하고 가상화되거나 분할 가능한 장치로 실험을 시작해 보세요. 워크로드를 소비 가능한 용량(예: 분수 대역폭 또는 메모리)으로 지정해 보세요.- 의견을 알려주세요:
- ✅ 잘 작동한 부분은 무엇이었나요?
- ⚠️ 잘 작동하지 않은 부분은 무엇이었나요? 수정할 문제나 개선할 기회를 발견하셨다면, 새로운 이슈를 제기하고 KEP-5075를 참조하거나, Slack (#wg-device-management)을 통해 연락 주세요.
결론
소비 가능한 용량 지원은 네임스페이스 간, 클레임 간에 효과적인 장치 공유를 가능하게 하고 각 파드의 실제 요구에 맞춰 장치 공유 기능을 향상시킵니다. 또한 드라이버가 용량 제한을 적용하고, 스케줄링 정확도를 개선하며, 대역폭 인지 네트워킹 및 다중 테넌트 장치 공유와 같은 새로운 사용 사례를 가능하게 합니다.
직접 사용해 보고, 소비 가능한 리소스로 실험해 보며, 쿠버네티스에서 동적 리소스 할당의 미래를 만들어가는 데 기여해 주세요!