LabHub

블로그

Kubernetes DRA(Dynamic Resource Allocation)로 GPU 워크로드 스케줄링 최적화 가이드

한국어English日本語

Kubernetes DRA GPU Scheduling

들어가며

Kubernetes에서 GPU 같은 하드웨어 가속기를 스케줄링하는 것은 오랫동안 운영자들에게 난제였습니다. 기존 Extended Resource 모델은 nvidia.com/gpu: 1처럼 단순한 정수 카운트 방식으로 GPU를 할당했기 때문에, GPU의 세부 속성(VRAM 용량, MIG 파티션, 특정 모델)을 기준으로 스케줄링하는 것이 근본적으로 불가능했습니다.

이 문제를 해결하기 위해 Kubernetes 1.26에서 알파로 도입되고, 1.31에서 대폭 재설계되어 1.32에서 베타로 승격된 DRA(Dynamic Resource Allocation)는 GPU/FPGA/네트워크 장치 등 복잡한 하드웨어 리소스를 구조화된 방식으로 요청하고 할당할 수 있는 프레임워크입니다.

기존 Extended Resource 모델의 한계

기존 모델에서 GPU 할당은 다음과 같이 이루어졌습니다:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-training-legacy
spec:
  containers:
    - name: trainer
      image: nvcr.io/nvidia/pytorch:24.01-py3
      resources:
        limits:
          nvidia.com/gpu: 2

이 방식은 몇 가지 근본적인 한계가 있습니다:

DRA는 이 모든 한계를 해소하여 GPU 워크로드의 스케줄링 품질을 근본적으로 개선합니다. 이 글에서는 DRA의 아키텍처부터 실전 배포, 운영 트러블슈팅까지 체계적으로 다룹니다.

DRA 아키텍처 개요

DRA는 Kubernetes의 resource.k8s.io/v1beta1 (1.32 기준) API 그룹에 속하며, 다음 네 가지 핵심 리소스로 구성됩니다.

핵심 리소스 구조

DeviceClass: 디바이스의 유형을 정의합니다. GPU 모델별로 DeviceClass를 생성하여 워크로드가 특정 GPU 타입을 요청할 수 있게 합니다. 스토리지의 StorageClass와 유사한 역할을 합니다.

ResourceClaim: 실제 디바이스 할당 요청을 나타냅니다. PersistentVolumeClaim이 스토리지를 요청하듯, ResourceClaim은 특정 DeviceClass의 디바이스를 요청합니다. Pod의 라이프사이클과 독립적으로 존재할 수 있어 디바이스를 여러 Pod 간에 공유하거나, Pod 재시작 시에도 동일 디바이스를 유지할 수 있습니다.

ResourceClaimTemplate: Pod 생성 시 자동으로 ResourceClaim을 생성하기 위한 템플릿입니다. Pod마다 전용 ResourceClaim이 필요한 경우에 사용합니다.

ResourceSlice: 노드에 설치된 DRA 드라이버가 API 서버에 보고하는 디바이스 목록입니다. 스케줄러는 ResourceSlice를 참조하여 어떤 노드에 어떤 디바이스가 사용 가능한지 파악합니다.

스케줄링 플로우

DRA 기반 스케줄링은 다음과 같은 단계로 진행됩니다:

  1. Pod 제출: 사용자가 ResourceClaim을 참조하는 Pod를 생성합니다.
  2. 스케줄러 필터링: kube-scheduler가 ResourceSlice 정보를 기반으로 요청된 DeviceClass의 디바이스가 사용 가능한 노드를 필터링합니다.
  3. 구조화된 파라미터 매칭: 스케줄러가 ResourceClaim의 요구 사항과 각 노드의 사용 가능한 디바이스를 직접 매칭합니다. 이것이 DRA의 "Structured Parameters" 모델의 핵심입니다.
  4. 할당 결정: 스케줄러가 특정 노드의 특정 디바이스를 ResourceClaim에 할당합니다.
  5. 디바이스 준비: 해당 노드의 DRA 드라이버(kubelet 플러그인)가 할당된 디바이스를 컨테이너가 사용할 수 있도록 준비합니다 (CDI 디바이스 설정 등).
  6. 컨테이너 시작: kubelet이 준비된 디바이스와 함께 컨테이너를 시작합니다.

기존 Device Plugin 방식과 달리, DRA에서는 스케줄러가 직접 디바이스 속성을 이해하고 최적의 배치를 결정합니다. 이는 Device Plugin이 단순히 "가용 개수"만 보고하던 것과 근본적으로 다른 접근입니다.

DRA 드라이버 설치와 설정

사전 요구사항

DRA를 사용하려면 Kubernetes 1.32 이상이 필요하며, DynamicResourceAllocation 피처 게이트가 활성화되어야 합니다. Kubernetes 1.32에서는 베타 상태이므로 기본적으로 활성화되어 있습니다.

# 클러스터 버전 확인
kubectl version --short

# DRA 피처 게이트 활성화 확인 (kube-apiserver, kube-scheduler, kubelet 모두 필요)
# kubeadm 기반 클러스터의 경우 ClusterConfiguration에서 설정
kubectl get configmap -n kube-system kubeadm-config -o yaml | grep -A 5 "featureGates"

# DRA 관련 API 리소스 확인
kubectl api-resources | grep resource.k8s.io
# 출력 예시:
# deviceclasses              resource.k8s.io/v1beta1   false   DeviceClass
# resourceclaims             resource.k8s.io/v1beta1   true    ResourceClaim
# resourceclaimtemplates     resource.k8s.io/v1beta1   true    ResourceClaimTemplate
# resourceslices             resource.k8s.io/v1beta1   false   ResourceSlice

NVIDIA DRA 드라이버 설치

NVIDIA는 공식 DRA 드라이버인 nvidia-dra-driver를 제공합니다. 기존 k8s-device-plugin과는 별도의 프로젝트이며, DRA의 구조화된 파라미터 모델을 완전히 지원합니다.

# NVIDIA DRA 드라이버 Helm 차트 저장소 추가
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

# nvidia-dra-driver 설치
# 기존 NVIDIA GPU Operator가 설치되어 있다면 device-plugin은 비활성화해야 합니다
helm install nvidia-dra-driver nvidia/nvidia-dra-driver \
  --namespace nvidia-dra-driver \
  --create-namespace \
  --set controller.enabled=true \
  --set kubeletPlugin.enabled=true \
  --version v0.8.0

# 설치 확인
kubectl get pods -n nvidia-dra-driver
# NAME                                              READY   STATUS    RESTARTS   AGE
# nvidia-dra-driver-controller-7d8f9b6c4d-k2xvn    1/1     Running   0          2m
# nvidia-dra-driver-kubelet-plugin-node1-abcde      1/1     Running   0          2m
# nvidia-dra-driver-kubelet-plugin-node2-fghij      1/1     Running   0          2m

# ResourceSlice 생성 확인 - 드라이버가 노드의 GPU 정보를 보고
kubectl get resourceslices -o wide
# NAME                              DRIVER               NODE    POOL        DEVICES
# gpu-node1-nvidia-gpu-slice-0      gpu.nvidia.com       node1   nvidia-gpu  4
# gpu-node2-nvidia-gpu-slice-0      gpu.nvidia.com       node2   nvidia-gpu  8

ResourceSlice 상세 확인

드라이버가 정상적으로 설치되면, 각 GPU 노드의 디바이스 정보가 ResourceSlice로 보고됩니다. 이를 통해 스케줄러는 각 GPU의 세부 속성을 파악할 수 있습니다.

# 특정 노드의 ResourceSlice 상세 보기
kubectl get resourceslice gpu-node1-nvidia-gpu-slice-0 -o yaml

출력 예시를 보면 각 GPU에 대해 모델명, VRAM, UUID, 아키텍처, MIG 지원 여부 등 풍부한 속성이 보고되는 것을 확인할 수 있습니다. 이러한 속성들이 바로 DeviceClass와 ResourceClaim에서 필터링 조건으로 활용됩니다.

DeviceClass 정의와 GPU 티어 관리

GPU 모델별 DeviceClass 정의

DeviceClass는 StorageClass와 유사하게 디바이스의 "클래스"를 정의합니다. 클러스터 관리자가 미리 정의해두면, 워크로드 개발자는 단순히 DeviceClass 이름만 참조하여 원하는 GPU를 요청할 수 있습니다.

# gpu-deviceclasses.yaml
apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
metadata:
  name: gpu.nvidia.com-a100
spec:
  selectors:
    - cel:
        expression: "device.driver == 'gpu.nvidia.com' && device.attributes['gpu.nvidia.com'].productName == 'NVIDIA A100 80GB PCIe'"
  config:
    - opaque:
        driver: gpu.nvidia.com
        parameters:
          apiVersion: gpu.nvidia.com/v1alpha1
          kind: GpuConfig
          sharing:
            strategy: TimeSlicing
            timeSlicingConfig:
              interval: Long
---
apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
metadata:
  name: gpu.nvidia.com-h100
spec:
  selectors:
    - cel:
        expression: "device.driver == 'gpu.nvidia.com' && device.attributes['gpu.nvidia.com'].productName == 'NVIDIA H100 80GB HBM3'"
  config:
    - opaque:
        driver: gpu.nvidia.com
        parameters:
          apiVersion: gpu.nvidia.com/v1alpha1
          kind: GpuConfig
          sharing:
            strategy: TimeSlicing
            timeSlicingConfig:
              interval: Short
---
apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
metadata:
  name: gpu.nvidia.com-a100-mig-3g20gb
spec:
  selectors:
    - cel:
        expression: >-
          device.driver == 'gpu.nvidia.com' &&
          device.attributes['gpu.nvidia.com'].productName == 'NVIDIA A100 80GB PCIe' &&
          device.attributes['gpu.nvidia.com'].migProfile == '3g.20gb'

위 예시에서 세 가지 DeviceClass를 정의했습니다:

MIG 파티셔닝 전략

NVIDIA A100/H100에서 MIG를 활용하면 하나의 물리 GPU를 여러 독립 인스턴스로 분할하여 활용도를 극대화할 수 있습니다. DRA에서는 MIG 프로파일별로 DeviceClass를 정의하여 세밀한 GPU 자원 관리가 가능합니다.

MIG 프로파일컴퓨트 슬라이스VRAM최대 인스턴스(A100 기준)주요 용도
1g.5gb1/75GB7개추론(소형 모델), 개발/테스트
1g.10gb1/710GB7개추론(중형 모델)
2g.10gb2/710GB3개소규모 학습, 배치 추론
3g.20gb3/720GB2개중규모 학습, 파인튜닝
4g.40gb4/740GB1개대규모 학습
7g.80gb7/780GB1개전체 GPU (MIG 미사용과 동일)

A100 vs H100 스펙 비교

DeviceClass를 설계할 때 GPU 모델의 특성을 정확히 이해하는 것이 중요합니다.

항목NVIDIA A100 80GBNVIDIA H100 80GB
아키텍처AmpereHopper
FP16 성능312 TFLOPS989 TFLOPS
FP8 성능지원 안 함1,979 TFLOPS
VRAM80GB HBM2e80GB HBM3
메모리 대역폭2 TB/s3.35 TB/s
NVLink 대역폭600 GB/s900 GB/s
MIG 최대 인스턴스7개7개
TDP300W700W
DRA 드라이버 지원nvidia-dra-driver v0.6+nvidia-dra-driver v0.7+

H100은 FP8 연산과 Transformer Engine을 통해 LLM 학습/추론 성능이 A100 대비 3배 이상 향상되므로, LLM 워크로드에는 H100 DeviceClass를 우선 할당하는 정책을 수립하는 것이 좋습니다.

ResourceClaim 기반 Pod 스케줄링

기본 ResourceClaim 사용

ResourceClaim을 직접 생성하고 Pod에서 참조하는 방식입니다. 디바이스를 Pod 라이프사이클과 독립적으로 관리하거나, 여러 Pod에서 공유해야 할 때 사용합니다.

# 독립적인 ResourceClaim 생성
apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaim
metadata:
  name: training-gpu-claim
  namespace: ml-workloads
spec:
  devices:
    requests:
      - name: gpu
        deviceClassName: gpu.nvidia.com-a100
        count: 4
    constraints:
      - requests: ['gpu']
        matchAttribute: 'gpu.nvidia.com/nvlinkInterconnect'
---
# ResourceClaim을 참조하는 Pod
apiVersion: v1
kind: Pod
metadata:
  name: distributed-training
  namespace: ml-workloads
spec:
  containers:
    - name: trainer
      image: nvcr.io/nvidia/pytorch:24.01-py3
      command: ['torchrun', '--nproc_per_node=4', 'train.py']
      resources:
        claims:
          - name: training-gpus
  resourceClaims:
    - name: training-gpus
      resourceClaimName: training-gpu-claim
  restartPolicy: Never

위 예시에서 주목할 점은 constraints 필드입니다. matchAttribute를 사용하여 4개의 A100 GPU가 NVLink로 상호 연결된 상태로 할당되도록 제약 조건을 설정했습니다. 이는 분산 학습 시 GPU 간 통신 성능에 결정적인 영향을 미칩니다.

ResourceClaimTemplate 사용

Job이나 Deployment처럼 여러 Pod를 생성하는 워크로드에서는 ResourceClaimTemplate을 사용하여 각 Pod마다 전용 ResourceClaim이 자동 생성되도록 합니다.

# MIG 기반 추론 서비스 배포
apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-inference-service
  namespace: ml-workloads
spec:
  replicas: 6
  selector:
    matchLabels:
      app: llm-inference
  template:
    metadata:
      labels:
        app: llm-inference
    spec:
      containers:
        - name: inference-server
          image: nvcr.io/nvidia/tritonserver:24.01-py3
          ports:
            - containerPort: 8000
              name: http
            - containerPort: 8001
              name: grpc
          resources:
            claims:
              - name: inference-gpu
      resourceClaims:
        - name: inference-gpu
          resourceClaimTemplateName: mig-inference-template
---
apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaimTemplate
metadata:
  name: mig-inference-template
  namespace: ml-workloads
spec:
  spec:
    devices:
      requests:
        - name: mig-gpu
          deviceClassName: gpu.nvidia.com-a100-mig-3g20gb
          count: 1

이 구성에서는 6개의 Triton Inference Server 레플리카가 각각 A100의 MIG 3g.20gb 슬라이스 1개를 할당받습니다. 물리 A100 2장으로 6개의 추론 인스턴스를 운영할 수 있어, 기존 Extended Resource 모델에서 GPU 2장을 통째로 할당해야 했던 것에 비해 자원 활용률이 크게 개선됩니다.

인라인 디바이스 요청

간단한 경우에는 별도의 ResourceClaim이나 ResourceClaimTemplate을 만들지 않고, Pod 스펙에서 직접 디바이스를 요청할 수도 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: quick-gpu-job
  namespace: ml-workloads
spec:
  containers:
    - name: compute
      image: nvcr.io/nvidia/cuda:12.3.1-runtime-ubuntu22.04
      command: ['python3', 'benchmark.py']
      resources:
        claims:
          - name: gpu-req
  resourceClaims:
    - name: gpu-req
      resourceClaimTemplateName: ''
      source:
        devices:
          requests:
            - name: gpu
              deviceClassName: gpu.nvidia.com-h100
              count: 1
  restartPolicy: Never

멀티 클라우드 DRA 비교 (AKS vs GKE vs EKS)

각 클라우드 프로바이더별 DRA 지원 현황과 GPU 인스턴스 옵션을 비교합니다.

항목AKS (Azure)GKE (Google)EKS (AWS)
Kubernetes 최소 버전1.31+ (Preview)1.32+ (Preview)1.32+ (Preview)
DRA 피처 게이트수동 활성화 필요GKE 채널별 자동 활성화EKS 애드온으로 관리
GPU 인스턴스 (A100)NC A100 v4a2-highgpu / a3-highgpup4d.24xlarge
GPU 인스턴스 (H100)ND H100 v5a3-ultragpu-8gp5.48xlarge
NVIDIA DRA 드라이버Helm 수동 설치GKE GPU Operator 통합EKS NVIDIA 애드온
MIG 지원지원 (수동 구성)지원 (GKE MIG 관리자)지원 (수동 구성)
노드 오토스케일링 연동Karpenter / Cluster AutoscalerNAP / KarpenterKarpenter
가격 (A100 80GB, 시간당)~$3.67~$3.67~$32.77 (8GPU 전체)
주요 제한사항Preview 기능, SLA 미보장Rapid 채널만 지원특정 리전만 가용

클라우드별 설정 차이점

GKE에서는 GPU 노드 풀 생성 시 DRA를 활성화할 수 있습니다:

# GKE에서 DRA 지원 GPU 노드 풀 생성
gcloud container node-pools create gpu-pool-h100 \
  --cluster=ml-cluster \
  --zone=us-central1-c \
  --machine-type=a3-highgpu-8g \
  --accelerator=type=nvidia-h100-80gb,count=8 \
  --num-nodes=2 \
  --enable-autoscaling \
  --min-nodes=0 \
  --max-nodes=4 \
  --node-labels="gpu-type=h100" \
  --metadata="install-nvidia-driver=True"

# DRA 피처 게이트 활성화 (GKE Rapid 채널)
gcloud container clusters update ml-cluster \
  --zone=us-central1-c \
  --release-channel=rapid \
  --enable-kubernetes-unstable-apis=resource.k8s.io/v1beta1

EKS에서는 EKS 매니지드 애드온을 통해 DRA 드라이버를 관리합니다:

# EKS 클러스터에 NVIDIA DRA 드라이버 애드온 설치
aws eks create-addon \
  --cluster-name ml-cluster \
  --addon-name nvidia-dra-driver \
  --addon-version v0.8.0-eksbuild.1 \
  --region us-east-1

# GPU 노드 그룹 생성 (Karpenter NodePool)
cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-h100-pool
spec:
  template:
    spec:
      requirements:
        - key: "node.kubernetes.io/instance-type"
          operator: In
          values: ["p5.48xlarge"]
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: gpu-nodes
  limits:
    cpu: "1000"
    memory: 4000Gi
    nvidia.com/gpu: "64"
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30m
EOF

각 클라우드 프로바이더마다 DRA의 안정성 수준과 통합 깊이가 다르므로, 프로덕션 배포 전에 반드시 해당 프로바이더의 DRA 지원 문서를 확인하고, 가능하면 Preview/Beta 기능에 대한 별도의 지원 계약을 검토해야 합니다.

기존 Extended Resource 모델에서 DRA로 마이그레이션

기존 Extended Resource 기반 GPU 할당에서 DRA로 마이그레이션하는 것은 클러스터 전체에 영향을 미치는 작업이므로 단계적으로 진행해야 합니다.

마이그레이션 단계

1단계 - 평가와 인벤토리 (1~2주)

현재 클러스터의 GPU 사용 현황을 파악합니다.

# 현재 Extended Resource 방식으로 GPU를 사용하는 모든 Pod 조회
kubectl get pods --all-namespaces -o json | \
  jq -r '.items[] |
    select(.spec.containers[].resources.limits["nvidia.com/gpu"] != null) |
    [.metadata.namespace, .metadata.name,
     (.spec.containers[].resources.limits["nvidia.com/gpu"] // "0")] |
    @tsv' | \
  column -t -s $'\t'

# 노드별 GPU 할당 현황
kubectl get nodes -l nvidia.com/gpu.present=true -o json | \
  jq -r '.items[] |
    [.metadata.name,
     .status.capacity["nvidia.com/gpu"],
     .status.allocatable["nvidia.com/gpu"]] |
    @tsv' | \
  column -t -s $'\t' -N "NODE,CAPACITY,ALLOCATABLE"

2단계 - DRA 인프라 준비 (1주)

  1. Kubernetes 버전을 1.32 이상으로 업그레이드합니다.
  2. DRA 피처 게이트가 활성화되었는지 확인합니다.
  3. NVIDIA DRA 드라이버를 설치합니다.
  4. 기존 NVIDIA Device Plugin은 아직 제거하지 않습니다 (공존 가능).

3단계 - DeviceClass 정의 (1~2일)

클러스터에 존재하는 GPU 모델별로 DeviceClass를 생성합니다. 앞서 설명한 YAML 예시를 참고하여, 운영 환경의 GPU 인벤토리에 맞게 DeviceClass를 정의합니다.

4단계 - 파일럿 워크로드 전환 (2~4주)

비핵심 워크로드부터 DRA 방식으로 전환합니다. 개발/스테이징 환경에서 먼저 검증한 후, 프로덕션의 낮은 우선순위 워크로드로 확장합니다.

5단계 - 전면 전환 (2~4주)

모든 GPU 워크로드를 DRA로 전환하고, 기존 NVIDIA Device Plugin을 제거합니다. 이 단계에서는 롤백 계획을 반드시 준비해야 합니다.

마이그레이션 시 주의사항

운영 시 주의사항과 모니터링

용량 계획 (Capacity Planning)

DRA 환경에서의 GPU 용량 계획은 기존보다 세밀해집니다. MIG를 활용하는 경우 물리 GPU 수뿐만 아니라 MIG 프로파일 조합도 고려해야 합니다.

권장 용량 계획 원칙:

모니터링 구성

DRA 환경에서는 다음 메트릭들을 모니터링해야 합니다:

# ResourceClaim 상태 모니터링
kubectl get resourceclaims --all-namespaces -o custom-columns=\
  'NAMESPACE:.metadata.namespace,'\
  'NAME:.metadata.name,'\
  'DEVICECLASS:.spec.devices.requests[0].deviceClassName,'\
  'ALLOCATED:.status.allocation.devices.results[0].device'

# Pending 상태의 ResourceClaim 확인 (할당 실패 감지)
kubectl get resourceclaims --all-namespaces \
  --field-selector="status.allocation=" \
  -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,AGE:.metadata.creationTimestamp'

# DeviceClass별 사용률 확인
kubectl get resourceslices -o json | \
  jq -r '[.items[].spec.devices[] |
    {driver: .basic.attributes["gpu.nvidia.com"].productName.stringValue}] |
    group_by(.driver) |
    map({gpu_model: .[0].driver, total: length}) |
    .[] | [.gpu_model, .total] | @tsv'

Prometheus 메트릭 수집

NVIDIA DRA 드라이버는 Prometheus 메트릭을 노출합니다. 다음과 같은 주요 메트릭을 모니터링 대시보드에 포함하세요:

메트릭 이름설명알림 임계값
dra_resource_claims_total전체 ResourceClaim 수-
dra_resource_claims_pending대기 중인 ResourceClaim 수5분 이상 Pending 시 경고
dra_resource_claims_allocated할당 완료된 ResourceClaim 수-
dra_devices_availableDeviceClass별 가용 디바이스 수가용률 10% 미만 시 경고
dra_devices_allocated할당된 디바이스 수-
dra_allocation_duration_seconds할당 소요 시간p99가 30초 초과 시 경고
dra_plugin_errors_total드라이버 오류 횟수1분 내 5회 이상 시 긴급

실패 사례와 복구 절차

사례 1: ResourceClaim이 영구적으로 Pending 상태

증상: Pod가 Pending 상태에서 벗어나지 않고, kubectl describe pod에서 "waiting for ResourceClaim to be allocated" 메시지가 표시됩니다.

원인 분석:

복구 절차:

# 1. ResourceClaim 상태 확인
kubectl describe resourceclaim training-gpu-claim -n ml-workloads

# 2. 요청한 DeviceClass와 매칭되는 디바이스 존재 여부 확인
kubectl get resourceslices -o json | \
  jq '.items[].spec.devices[] |
    select(.basic.attributes["gpu.nvidia.com"].productName.stringValue == "NVIDIA A100 80GB PCIe")'

# 3. DRA 드라이버 상태 확인
kubectl get pods -n nvidia-dra-driver
kubectl logs -n nvidia-dra-driver -l app=nvidia-dra-driver-kubelet-plugin --tail=50

# 4. 스케줄러 로그에서 DRA 관련 오류 확인
kubectl logs -n kube-system -l component=kube-scheduler --tail=100 | grep -i "dra\|resourceclaim\|deviceclass"

# 5. 필요 시 ResourceClaim 삭제 후 재생성
kubectl delete resourceclaim training-gpu-claim -n ml-workloads
kubectl apply -f training-gpu-claim.yaml

사례 2: 노드 장애 시 GPU 디바이스 누수(Leak)

증상: 노드가 NotReady 상태가 된 후 복구되었지만, 해당 노드의 GPU가 ResourceSlice에서는 "할당됨"으로 표시되어 새로운 Pod에 할당되지 않습니다.

원인: 노드 장애로 DRA 드라이버의 kubelet 플러그인이 비정상 종료되면서 디바이스 해제 절차가 완료되지 않았습니다.

복구 절차:

  1. 해당 노드에서 실행 중이던 Pod의 ResourceClaim이 아직 존재하는지 확인합니다.
  2. 해당 Pod가 삭제되었다면 ResourceClaim도 함께 삭제되어야 하지만 (소유자 참조가 있는 경우), 그렇지 않으면 수동으로 삭제합니다.
  3. DRA 드라이버 kubelet 플러그인을 재시작합니다.
# 해당 노드의 DRA 드라이버 플러그인 Pod 재시작
kubectl delete pod -n nvidia-dra-driver -l app=nvidia-dra-driver-kubelet-plugin \
  --field-selector spec.nodeName=problematic-node

# ResourceSlice가 올바르게 업데이트되었는지 확인 (재시작 후 30초 대기)
sleep 30
kubectl get resourceslices --field-selector spec.nodeName=problematic-node -o yaml

사례 3: DRA 드라이버 업그레이드 중 기존 워크로드 중단

증상: DRA 드라이버를 Helm으로 업그레이드하는 과정에서 kubelet 플러그인 DaemonSet의 Pod가 재시작되면서, 해당 노드에서 실행 중이던 GPU 워크로드가 디바이스 접근 오류를 발생시킵니다.

예방 조치:

사례 4: CEL 표현식 오류로 DeviceClass 매칭 실패

증상: DeviceClass를 생성했지만 ResourceClaim이 할당되지 않습니다. kubectl describe 결과 매칭되는 디바이스가 없다고 표시됩니다.

원인: DeviceClass의 selectors.cel.expression에서 속성 이름이 잘못되었거나, 비교 값이 실제 디바이스가 보고하는 값과 다릅니다.

디버깅 방법:

# 실제 디바이스가 보고하는 속성 이름과 값 확인
kubectl get resourceslices -o json | \
  jq '.items[0].spec.devices[0].basic.attributes'

# 출력 예시:
# {
#   "gpu.nvidia.com": {
#     "driverVersion": {"stringValue": "550.54.15"},
#     "productName": {"stringValue": "NVIDIA A100 80GB PCIe"},
#     "architecture": {"stringValue": "Ampere"},
#     "cudaComputeCapability": {"versionValue": "8.0"},
#     "memory": {"quantityValue": "80Gi"}
#   }
# }
# DeviceClass의 CEL 표현식에서 사용하는 속성 이름이 위 출력과 정확히 일치하는지 확인합니다.

사례 5: ResourceClaim 쿼터 초과

증상: 네임스페이스의 ResourceQuota에 의해 ResourceClaim 생성이 거부됩니다.

DRA 환경에서는 네임스페이스별 ResourceClaim 수 제한을 설정할 수 있습니다. 특히 ResourceClaimTemplate을 사용하는 Deployment의 레플리카가 많으면 예상보다 빠르게 쿼터에 도달할 수 있으므로 주의가 필요합니다.

프로덕션 배포 체크리스트

DRA 기반 GPU 워크로드를 프로덕션에 배포하기 전에 다음 체크리스트를 확인하세요.

인프라 준비

DeviceClass 설계

워크로드 구성

RBAC과 보안

모니터링과 알림

장애 대응

성능 검증

참고자료

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다