AKS(Azure Kubernetes Service)에서 계산 집약적 워크로드에 GPU 사용

GPU(그래픽 처리 장치)는 그래픽 및 시각화 워크로드 같은 계산 집약적 워크로드에 자주 사용됩니다. AKS는 컴퓨팅 집약적인 Kubernetes 워크로드를 실행하기 위해 GPU 지원 Linux 노드 풀을 지원합니다.

이 문서는 신규 및 기존 AKS 클러스터에서 예약 가능한 GPU를 사용하여 노드를 프로비전하는 데 도움이 됩니다.

지원되는 GPU 지원 VM

지원되는 GPU 지원 VM을 보려면 Azure의 GPU 최적화 VM 크기를 참조하세요. AKS 노드 풀의 경우 권장하는 최소 크기는 Standard_NC6s_v3입니다. NVv4 시리즈(AMD GPU 기반)는 AKS에서 지원되지 않습니다.

참고 항목

GPU 지원 VM에는 더 높은 가격 및 지역 가용성에 맞는 특별한 하드웨어가 포함되어 있습니다. 자세한 내용은 가격 책정 도구 및 지역 가용성을 참조하세요.

제한 사항

  • Azure Linux GPU 지원 노드 풀을 사용하는 경우 자동 보안 패치가 적용되지 않으며 클러스터의 기본 동작은 ‘관리되지 않음’으로 설정됩니다. 자세한 내용은 자동 업그레이드를 참조하세요.
  • NVadsA10 v5 시리즈는 GPU VHD에 권장되는 SKU가 아닙니다.
  • GPU를 추가하도록 기존 노드 풀을 업데이트하는 것은 지원되지 않습니다.

시작하기 전에

  • 이 문서에서는 기존 AKS 클러스터가 있다고 가정합니다. 클러스터가 없으면 Azure CLI, Azure PowerShell 또는 Azure Portal을 사용하여 클러스터를 만듭니다.
  • Azure CLI 2.0.64 이상 버전을 설치하고 구성해야 합니다. az --version을 실행하여 버전을 찾습니다. 설치 또는 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.

클러스터의 자격 증명 가져오기

  • az aks get-credentials 명령을 사용하여 AKS 클러스터의 자격 증명을 가져옵니다. 다음 예에서는 myResourceGroup 리소스 그룹에서 myAKSCluster에 대한 자격 증명을 가져옵니다.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    

NVIDIA GPU 사용 옵션

NVIDIA GPU를 사용하려면 Kubernetes용 NVIDIA 디바이스 플러그 인, GPU 드라이버 설치 등과 같은 다양한 NVIDIA 소프트웨어 구성 요소를 설치해야 합니다.

GPU 드라이버 설치 건너뛰기(미리 보기)

AKS에는 기본적으로 자동 GPU 드라이버 설치가 사용하도록 설정되어 있습니다. 자체 드라이버를 설치하거나 NVIDIA GPU Operator를 사용하는 경우에는 GPU 드라이버 설치를 건너뛰는 것이 좋습니다.

Important

AKS 미리 보기 기능은 셀프 서비스에서 사용할 수 있습니다(옵트인 방식). 미리 보기는 "있는 그대로" 및 "사용 가능한 상태로" 제공되며 서비스 수준 계약 및 제한적 보증에서 제외됩니다. AKS 미리 보기의 일부는 고객 지원팀에서 최선을 다해 지원합니다. 따라서 이러한 기능은 프로덕션 용도로 사용할 수 없습니다. 자세한 내용은 다음 지원 문서를 참조하세요.

  1. az extension add 또는 az extension update 명령을 사용하여 aks-preview 확장을 등록하거나 업데이트합니다.

    # Register the aks-preview extension
    az extension add --name aks-preview
    
    # Update the aks-preview extension
    az extension update --name aks-preview
    
  2. --skip-gpu-driver-install 플래그와 함께 az aks nodepool add 명령을 사용하여 노드 풀을 만들어 자동 GPU 드라이버 설치를 건너뜁니다.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --skip-gpu-driver-install \
        --node-vm-size Standard_NC6s_v3 \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    노드 풀을 만드는 동안 --skip-gpu-driver-install 플래그를 추가하면 자동 GPU 드라이버 설치를 건너뜁니다. 기존 노드는 변경되지 않습니다. 노드 풀을 0으로 스케일링한 다음 백업하여 변경 내용이 적용되도록 할 수 있습니다.

NVIDIA 디바이스 플러그 인 설치

AKS에서 GPU를 사용하는 경우 NVIDIA 디바이스 플러그 인 설치가 필요합니다. NVIDIA GPU Operator 또는 AKS GPU 이미지(미리 보기)를 사용하는 경우와 같이 설치가 자동으로 처리되는 경우도 있습니다. 또는 NVIDIA 디바이스 플러그 인을 수동으로 설치할 수 있습니다.

NVIDIA 디바이스 플러그 인 수동 설치

GPU에 필요한 드라이버를 제공하기 위해 각 노드에서 Pod를 실행하는 NVIDIA 디바이스 플러그 인용 DaemonSet를 배포할 수 있습니다. 이것은 Azure Linux에 GPU 지원 노드 풀을 사용할 때 권장되는 방법입니다.

기본 OS SKU를 사용하려면 OS SKU를 지정하지 않고 노드 풀을 만듭니다. 노드 풀은 클러스터의 Kubernetes 버전을 기반으로 기본 운영 체제로 설정됩니다.

  1. az aks nodepool add 명령을 사용하여 클러스터에 노드 풀을 추가합니다.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --node-taints sku=gpu:NoSchedule \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    이 명령은 myResourceGroupmyAKSClustergpunp라는 노드 풀을 추가하고 매개 변수를 사용하여 다음 노드 풀 설정을 구성합니다.

    • --node-vm-size: 노드 풀에 있는 노드의 VM 크기를 Standard_NC6s_v3로 설정합니다.
    • --node-taints: 노드 풀에 sku=gpu:NoSchedule 테인트를 지정합니다.
    • --enable-cluster-autoscaler: 클러스터 자동 크기 조정기를 사용하도록 설정합니다.
    • --min-count: 노드 풀에서 최소 1개의 노드를 유지하도록 클러스터 자동 크기 조정기를 구성합니다.
    • --max-count: 노드 풀에서 최대 3개의 노드를 유지하도록 클러스터 자동 크기 조정기를 구성합니다.

    참고 항목

    taint 및 VM 크기는 노드 풀을 만드는 동안에만 노드 풀에 대해 설정할 수 있지만 자동 크기 조정기 설정은 언제든지 업데이트할 수 있습니다.

  1. kubectl create namespace 명령을 사용하여 네임스페이스를 만듭니다.

    kubectl create namespace gpu-resources
    
  2. nvidia-device-plugin-ds.yaml이라는 파일을 만들고 Kubernetes용 NVIDIA 디바이스 플러그 인 프로젝트의 일부로 제공된 다음 YAML 매니페스트를 붙여넣습니다.

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nvidia-device-plugin-daemonset
      namespace: gpu-resources
    spec:
      selector:
        matchLabels:
          name: nvidia-device-plugin-ds
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          # Mark this pod as a critical add-on; when enabled, the critical add-on scheduler
          # reserves resources for critical add-on pods so that they can be rescheduled after
          # a failure.  This annotation works in tandem with the toleration below.
          annotations:
            scheduler.alpha.kubernetes.io/critical-pod: ""
          labels:
            name: nvidia-device-plugin-ds
        spec:
          tolerations:
          # Allow this pod to be rescheduled while the node is in "critical add-ons only" mode.
          # This, along with the annotation above marks this pod as a critical add-on.
          - key: CriticalAddonsOnly
            operator: Exists
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
          containers:
          - image: mcr.microsoft.com/oss/nvidia/k8s-device-plugin:v0.14.1
            name: nvidia-device-plugin-ctr
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop: ["ALL"]
            volumeMounts:
              - name: device-plugin
                mountPath: /var/lib/kubelet/device-plugins
          volumes:
            - name: device-plugin
              hostPath:
                path: /var/lib/kubelet/device-plugins
    
  3. DaemonSet를 만들고 kubectl apply 명령을 사용하여 NVIDIA 디바이스 플러그 인이 성공적으로 만들어졌는지 확인합니다.

    kubectl apply -f nvidia-device-plugin-ds.yaml
    
  4. 이제 NVIDIA 디바이스 플러그 인을 성공적으로 설치했으므로 GPU가 예약 가능한지 확인하고 GPU 워크로드를 실행할 수 있습니다.

AKS에서 NVIDIA GPU Operator 사용

NVIDIA GPU Operator는 드라이버 설치, Kubernetes용 NVIDIA 디바이스 플러그 인, NVIDIA 컨테이너 런타임 등을 포함하여 GPU를 프로비전하는 데 필요한 모든 NVIDIA 소프트웨어 구성 요소의 관리를 자동화합니다. GPU Operator가 이러한 구성 요소를 처리하므로 NVIDIA 디바이스 플러그 인을 수동으로 설치할 필요가 없습니다. 이는 AKS에서 자동 GPU 드라이버 설치가 더 이상 필요하지 않다는 의미이기도 합니다.

  1. --skip-gpu-driver-install과 함께 az aks nodepool add 명령을 사용하여 노드 풀을 만들어 자동 GPU 드라이버 설치를 건너뜁니다. 노드 풀을 만드는 동안 --skip-gpu-driver-install 플래그를 추가하면 자동 GPU 드라이버 설치를 건너뜁니다. 기존 노드는 변경되지 않습니다. 노드 풀을 0으로 스케일링한 다음 백업하여 변경 내용이 적용되도록 할 수 있습니다.

  2. NVIDIA 설명서에 따라 GPU Operator를 설치합니다.

  3. 이제 GPU Operator를 성공적으로 설치했으므로 GPU가 예약 가능한지 확인하고 GPU 워크로드를 실행할 수 있습니다.

Warning

AKS GPU 이미지를 사용하여 클러스터와 함께 NVIDIA 디바이스 플러그 인 디먼 집합을 수동으로 설치하지 않는 것이 좋습니다.

AKS GPU 이미지 사용(미리 보기)

AKS는 Kubernetes용 NVIDIA 디바이스 플러그 인을 포함하는 완전히 구성된 AKS 이미지를 제공합니다. AKS GPU 이미지는 현재 Ubuntu 18.04에서만 지원됩니다.

Important

AKS 미리 보기 기능은 셀프 서비스에서 사용할 수 있습니다(옵트인 방식). 미리 보기는 "있는 그대로" 및 "사용 가능한 상태로" 제공되며 서비스 수준 계약 및 제한적 보증에서 제외됩니다. AKS 미리 보기의 일부는 고객 지원팀에서 최선을 다해 지원합니다. 따라서 이러한 기능은 프로덕션 용도로 사용할 수 없습니다. 자세한 내용은 다음 지원 문서를 참조하세요.

  1. az extension add 명령을 사용하여 aks-preview Azure CLI 확장을 설치합니다.

    az extension add --name aks-preview
    
  2. az extension update 명령을 사용하여 확장의 최신 버전으로 업데이트합니다.

    az extension update --name aks-preview
    
  3. az feature register 명령을 사용하여 GPUDedicatedVHDPreview 기능 플래그를 등록합니다.

    az feature register --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    

    상태가 Registered로 표시되는 데 몇 분 정도 걸립니다.

  4. 또한 az feature show 명령을 사용하여 등록 상태를 확인합니다.

    az feature show --namespace "Microsoft.ContainerService" --name "GPUDedicatedVHDPreview"
    
  5. 상태가 Registered(등록됨)를 반영하면 az provider register 명령을 사용하여 Microsoft.ContainerService 리소스 공급자의 등록을 새로 고칩니다.

    az provider register --namespace Microsoft.ContainerService
    

    이제 AKS GPU 이미지를 사용하도록 클러스터를 업데이트했으므로 GPU 노드에 대한 노드 풀을 클러스터에 추가할 수 있습니다.

  6. az aks nodepool add 명령을 사용하여 노드 풀을 추가합니다.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunp \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --node-taints sku=gpu:NoSchedule \
        --aks-custom-headers UseGPUDedicatedVHD=true \
        --enable-cluster-autoscaler \
        --min-count 1 \
        --max-count 3
    

    이전 명령 예는 myResourceGroupmyAKSClustergpunp라는 노드 풀을 추가하고 매개 변수를 사용하여 다음 노드 풀 설정을 구성합니다.

    • --node-vm-size: 노드 풀에 있는 노드의 VM 크기를 Standard_NC6s_v3로 설정합니다.
    • --node-taints: 노드 풀에 sku=gpu:NoSchedule 테인트를 지정합니다.
    • --aks-custom-headers: 특수 AKS GPU 이미지인 UseGPUDedicatedVHD=true를 지정합니다. GPU SKU에 2세대 VM이 필요한 경우 --aks-custom-headers UseGPUDedicatedVHD=true,usegen2vm=true를 대신 사용합니다.
    • --enable-cluster-autoscaler: 클러스터 자동 크기 조정기를 사용하도록 설정합니다.
    • --min-count: 노드 풀에서 최소 1개의 노드를 유지하도록 클러스터 자동 크기 조정기를 구성합니다.
    • --max-count: 노드 풀에서 최대 3개의 노드를 유지하도록 클러스터 자동 크기 조정기를 구성합니다.

    참고 항목

    taint 및 VM 크기는 노드 풀을 만드는 동안에만 노드 풀에 대해 설정할 수 있지만 자동 크기 조정기 설정은 언제든지 업데이트할 수 있습니다.

  7. 이제 GPU 이미지를 사용하여 노드 풀을 성공적으로 설치했으므로 GPU가 예약 가능한지 확인하고 GPU 워크로드를 실행할 수 있습니다.

GPU의 예약 가능 여부 확인

클러스터를 만든 후 Kubernetes에서 GPU를 예약할 수 있는지 확인합니다.

  1. kubectl get nodes 명령을 사용하여 클러스터의 노드를 나열합니다.

    kubectl get nodes
    

    출력은 다음 예제 출력과 비슷하게 됩니다.

    NAME                   STATUS   ROLES   AGE   VERSION
    aks-gpunp-28993262-0   Ready    agent   13m   v1.20.7
    
  2. kubectl describe node 명령을 사용하여 GPU를 예약할 수 있는지 확인합니다.

    kubectl describe node aks-gpunp-28993262-0
    

    용량 섹션에 GPU가 nvidia.com/gpu: 1으로 나열됩니다 출력은 다음과 같이 요약된 예제 출력과 비슷하게 됩니다.

    Name:               aks-gpunp-28993262-0
    Roles:              agent
    Labels:             accelerator=nvidia
    
    [...]
    
    Capacity:
    [...]
     nvidia.com/gpu:                 1
    [...]
    

GPU 지원 워크로드 실행

GPU가 작동하는 모습을 보려면 적절한 리소스 요청으로 GPU 지원 워크로드를 예약하면 됩니다. 이 예에서는 MNIST 데이터 세트에 대해 Tensorflow 작업을 실행합니다.

  1. samples-tf-mnist-demo.yaml이라는 파일을 만들고 nvidia.com/gpu: 1의 리소스 제한이 포함된 다음 YAML 매니페스트를 붙여넣습니다.

    참고 항목

    드라이버를 호출할 때 "CUDA 드라이버 버전이 CUDA 런타임 버전에 적합하지 않다"는 버전 불일치 오류가 발생하는 경우, NVIDIA 드라이버 행렬 호환성 차트를 검토합니다.

    apiVersion: batch/v1
    kind: Job
    metadata:
      labels:
        app: samples-tf-mnist-demo
      name: samples-tf-mnist-demo
    spec:
      template:
        metadata:
          labels:
            app: samples-tf-mnist-demo
        spec:
          containers:
          - name: samples-tf-mnist-demo
            image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
            args: ["--max_steps", "500"]
            imagePullPolicy: IfNotPresent
            resources:
              limits:
               nvidia.com/gpu: 1
          restartPolicy: OnFailure
          tolerations:
          - key: "sku"
            operator: "Equal"
            value: "gpu"
            effect: "NoSchedule"
    
  2. 매니페스트 파일을 구문 분석하고 정의된 Kubernetes 개체를 만드는 kubectl apply 명령을 사용하여 작업을 실행합니다.

    kubectl apply -f samples-tf-mnist-demo.yaml
    

GPU 지원 워크로드 상태 보기

  1. --watch 플래그와 함께 kubectl get jobs 명령을 사용하여 작업 진행률을 모니터링합니다. 처음으로 이미지를 끌어와서 데이터 세트를 처리하는 경우 몇 분 정도 걸릴 수 있습니다.

    kubectl get jobs samples-tf-mnist-demo --watch
    

    다음 출력 예에 표시된 것처럼 COMPLETIONS 열에 1/1이 표시되면 작업이 성공적으로 완료된 것입니다.

    NAME                    COMPLETIONS   DURATION   AGE
    
    samples-tf-mnist-demo   0/1           3m29s      3m29s
    samples-tf-mnist-demo   1/1   3m10s   3m36s
    
  2. Ctrl-C를 사용하여 kubectl --watch 프로세스를 종료합니다.

  3. kubectl get pods 명령을 사용하여 Pod 이름을 가져옵니다.

    kubectl get pods --selector app=samples-tf-mnist-demo
    
  4. kubectl logs 명령을 사용하여 GPU 지원 워크로드의 출력을 확인합니다.

    kubectl logs samples-tf-mnist-demo-smnr6
    

    Pod 로그의 다음 압축된 출력 예는 적절한 GPU 디바이스 Tesla K80이 발견되었음을 확인합니다.

    2019-05-16 16:08:31.258328: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
    2019-05-16 16:08:31.396846: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Found device 0 with properties: 
    name: Tesla K80 major: 3 minor: 7 memoryClockRate(GHz): 0.8235
    pciBusID: 2fd7:00:00.0
    totalMemory: 11.17GiB freeMemory: 11.10GiB
    2019-05-16 16:08:31.396886: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow device (/device:GPU:0) -> (device: 0, name: Tesla K80, pci bus id: 2fd7:00:00.0, compute capability: 3.7)
    2019-05-16 16:08:36.076962: I tensorflow/stream_executor/dso_loader.cc:139] successfully opened CUDA library libcupti.so.8.0 locally
    Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
    Extracting /tmp/tensorflow/input_data/train-images-idx3-ubyte.gz
    Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
    Extracting /tmp/tensorflow/input_data/train-labels-idx1-ubyte.gz
    Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-images-idx3-ubyte.gz
    Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
    Extracting /tmp/tensorflow/input_data/t10k-labels-idx1-ubyte.gz
    Accuracy at step 0: 0.1081
    Accuracy at step 10: 0.7457
    Accuracy at step 20: 0.8233
    Accuracy at step 30: 0.8644
    Accuracy at step 40: 0.8848
    Accuracy at step 50: 0.8889
    Accuracy at step 60: 0.8898
    Accuracy at step 70: 0.8979
    Accuracy at step 80: 0.9087
    Accuracy at step 90: 0.9099
    Adding run metadata for 99
    Accuracy at step 100: 0.9125
    Accuracy at step 110: 0.9184
    Accuracy at step 120: 0.922
    Accuracy at step 130: 0.9161
    Accuracy at step 140: 0.9219
    Accuracy at step 150: 0.9151
    Accuracy at step 160: 0.9199
    Accuracy at step 170: 0.9305
    Accuracy at step 180: 0.9251
    Accuracy at step 190: 0.9258
    Adding run metadata for 199
    [...]
    Adding run metadata for 499
    

Container Insights를 사용하여 GPU 사용량 모니터링

AKS를 사용한 컨테이너 인사이트는 다음 GPU 사용 현황 메트릭을 모니터링합니다.

메트릭 이름 메트릭 차원(태그) 설명
containerGpuDutyCycle container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor 과거 샘플 기간(60초) 대비 GPU가 컨테이너를 위해 사용 중/적극적으로 처리 중인 시간의 백분율입니다. 업무 주기는 1에서 100 사이의 숫자입니다.
containerGpuLimits container.azm.ms/clusterId, container.azm.ms/clusterName, containerName 각 컨테이너가 하나 이상의 GPU로 한도를 지정할 수 있습니다. GPU의 일부를 요청하거나 제한할 수는 없습니다.
containerGpuRequests container.azm.ms/clusterId, container.azm.ms/clusterName, containerName 각 컨테이너가 하나 이상의 GPU를 요청할 수 있습니다. GPU의 일부를 요청하거나 제한할 수는 없습니다.
containerGpumemoryTotalBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor 특정 컨테이너에 사용할 수 있는 GPU 메모리 크기(바이트)입니다.
containerGpumemoryUsedBytes container.azm.ms/clusterId, container.azm.ms/clusterName, containerName, gpuId, gpuModel, gpuVendor 특정 컨테이너에 사용 중인 GPU 메모리 크기(바이트)입니다.
nodeGpuAllocatable container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor Kubernetes에서 사용할 수 있는 한 노드의 GPU 수입니다.
nodeGpuCapacity container.azm.ms/clusterId, container.azm.ms/clusterName, gpuVendor 한 노드에 있는 총 GPU 수입니다.

리소스 정리

  • kubectl delete job 명령을 사용하여 이 문서에서 만든 연결된 Kubernetes 개체를 제거합니다.

    kubectl delete jobs samples-tf-mnist-demo
    

다음 단계