Kubernetes GPU 스케줄링의 한계와 DRA의 등장
Kubernetes 위에서 GPU 자원을 운영해본 팀이라면 공통된 불편함을 경험했을 것이다. 기존 K8s의 리소스 모델은 nvidia.com/gpu: 1처럼 단순한 정수 카운팅 방식으로 GPU를 할당한다. B200, H100, B300 등 서로 다른 세대와 성능 특성을 가진 GPU가 혼재하는 클러스터에서는 이 방식이 금방 한계를 드러낸다. 워크로드마다 요구하는 GPU 메모리, 연산 능력, 상호 연결 토폴로지가 다름에도 불구하고, 스케줄러는 "GPU 1개"라는 단순한 기준으로만 자원을 배분한다. 결과적으로 플랫폼 팀은 노드 레이블링, NodeSelector, Taint/Toleration 등의 우회 기법을 조합해 복잡한 운영 규칙을 직접 관리해야 했다.
DRA(Dynamic Resource Allocation)가 해결하는 것
DRA는 Kubernetes 1.26부터 알파로 도입되어 점진적으로 성숙해온 메커니즘으로, 기존의 정적 리소스 모델을 근본적으로 대체하려는 시도다. 핵심 아이디어는 GPU처럼 복잡한 하드웨어 자원을 드라이버 플러그인이 직접 관리하고, 스케줄러는 그 플러그인이 제공하는 정보를 바탕으로 동적으로 할당 결정을 내리게 하는 것이다.
실무적으로 중요한 변화는 다음과 같다.
- 이기종 GPU 구분 가능: 단순한 수량이 아닌 GPU 모델, 메모리 크기, NVLink 연결 여부 등 세밀한 속성 기반으로 자원을 요청할 수 있다.
- 자원 공유 및 파티셔닝 지원: MIG(Multi-Instance GPU)나 vGPU처럼 하나의 물리 GPU를 논리적으로 분할하는 시나리오를 스케줄러 레벨에서 표현할 수 있다.
- 준비 상태 기반 할당: 자원이 실제로 준비되었는지 확인한 뒤 Pod를 바인딩하므로, 할당 후 초기화 실패로 인한 재스케줄링 비용을 줄인다.
apiVersion: resource.k8s.io/v1alpha3
kind: ResourceClaim
metadata:
name: gpu-claim
spec:
devices:
requests:
- name: gpu
deviceClassName: gpu.nvidia.com
selectors:
- cel:
expression: device.attributes["memory"].isGreaterThan(quantity("40Gi"))
위 예시처럼 CEL(Common Expression Language) 기반 셀렉터로 "40GB 이상 메모리를 가진 GPU"를 명시적으로 요청하는 것이 가능해진다.
플랫폼 팀 운영 관점에서의 실질적 이점
기존 방식에서는 B200 전용 노드풀, H100 전용 노드풀을 별도로 구성하고 각각에 Taint를 걸어두는 식으로 이기종 환경을 관리했다. 새로운 GPU 모델이 추가될 때마다 레이블 체계와 스케줄링 정책을 업데이트해야 했고, 이 과정에서 휴먼 에러가 발생할 여지도 컸다.
DRA 모델에서는 드라이버 플러그인이 각 GPU의 속성을 자동으로 노출하고, 워크로드는 필요한 특성을 선언적으로 기술한다. B300이 클러스터에 추가되더라도 플랫폼 팀이 별도의 레이블 작업 없이 드라이버가 자동으로 자원을 등록하고 스케줄러가 이를 인식한다. 운영 복잡도의 증가 속도가 하드웨어 확장 속도를 따라가지 못하는 문제를 구조적으로 해소할 수 있다.
다만 DRA는 아직 프로덕션 전면 적용보다는 신중한 검토가 필요한 단계다. 드라이버 성숙도, 버전 호환성, 기존 device plugin 기반 워크로드와의 공존 전략을 함께 고려해야 한다.
정리
- 기존 K8s GPU 스케줄링은 단순 정수 카운팅 방식으로, 이기종 하드웨어 혼재 환경에서 운영 복잡도가 급격히 증가한다.
- DRA는 드라이버 플러그인 기반의 동적 자원 할당으로, 세밀한 속성 기반 GPU 요청과 자원 파티셔닝을 스케줄러 레벨에서 지원한다.
- 플랫폼 팀은 DRA 도입을 통해 하드웨어 확장 시 수작업 정책 업데이트 부담을 줄일 수 있으나, 드라이버 성숙도와 기존 워크로드 호환성을 사전에 검토해야 한다.