GPUのスケジューリング

クラスター内のノードのリソースとしてGPUを設定してスケジューリングします
FEATURE STATE: Kubernetes v1.10 [beta]

Kubernetesには、複数ノードに搭載されたAMDおよびNVIDIAのGPU(graphical processing unit)を管理するための実験的なサポートが含まれています。

このページでは、異なるバージョンのKubernetesを横断してGPUを使用する方法と、現時点での制限について説明します。

デバイスプラグインを使用する

Kubernetesでは、GPUなどの特別なハードウェアの機能にPodがアクセスできるようにするために、デバイスプラグインSoftware extensions to let Pods access devices that need vendor-specific initialization or setup が実装されています。

管理者として、ノード上に対応するハードウェアベンダーのGPUドライバーをインストールして、以下のような対応するGPUベンダーのデバイスプラグインを実行する必要があります。

上記の条件を満たしていれば、Kubernetesはamd.com/gpuまたはnvidia.com/gpuをスケジュール可能なリソースとして公開します。

これらのGPUをコンテナから使用するには、cpumemoryをリクエストするのと同じように<vendor>.com/gpuというリソースをリクエストするだけです。ただし、GPUを使用するときにはリソースのリクエストの指定方法にいくつか制限があります。

  • GPUはlimitsセクションでのみ指定されることが想定されている。この制限は、次のことを意味します。
    • Kubernetesはデフォルトでlimitの値をrequestの値として使用するため、GPUのrequestsを省略してlimitsを指定できる。
    • GPUをlimitsrequestsの両方で指定できるが、これら2つの値は等しくなければならない。
    • GPUのlimitsを省略してrequestsだけを指定することはできない。
  • コンテナ(およびPod)はGPUを共有しない。GPUのオーバーコミットは起こらない。
  • 各コンテナは1つ以上のGPUをリクエストできる。1つのGPUの一部だけをリクエストすることはできない。

以下に例を示します。

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1 # 1 GPUをリクエストしています

AMDのGPUデバイスプラグインをデプロイする

AMD公式のGPUデバイスプラグインには以下の要件があります。

  • Kubernetesのノードに、AMDのGPUのLinuxドライバーがあらかじめインストール済みでなければならない。

クラスターが起動して上記の要件が満たされれば、以下のコマンドを実行することでAMDのデバイスプラグインをデプロイできます。

kubectl create -f https://raw.githubusercontent.com/RadeonOpenCompute/k8s-device-plugin/v1.10/k8s-ds-amdgpu-dp.yaml

このサードパーティーのデバイスプラグインに関する問題は、RadeonOpenCompute/k8s-device-pluginで報告できます。

NVIDIAのGPUデバイスプラグインをデプロイする

現在、NVIDIAのGPU向けのデバイスプラグインの実装は2種類あります。

NVIDIA公式のGPUデバイスプラグイン

NVIDIA公式のGPUデバイスプラグインには以下の要件があります。

  • Kubernetesのノードに、NVIDIAのドライバーがあらかじめインストール済みでなければならない。
  • Kubernetesのノードに、nvidia-docker 2.0があらかじめインストール済みでなければならない。
  • KubeletはコンテナランタイムにDockerを使用しなければならない。
  • runcの代わりにDockerのデフォルトランタイムとして、nvidia-container-runtimeを設定しなければならない。
  • NVIDIAのドライバーのバージョンが次の条件を満たさなければならない ~= 384.81。

クラスターが起動して上記の要件が満たされれば、以下のコマンドを実行することでNVIDIAのデバイスプラグインがデプロイできます。

kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml

このサードパーティーのデバイスプラグインに関する問題は、NVIDIA/k8s-device-pluginで報告できます。

GCEで使用されるNVIDIAのGPUデバイスプラグイン

GCEで使用されるNVIDIAのGPUデバイスプラグインは、nvidia-dockerを必要としないため、KubernetesのContainer Runtime Interface(CRI)と互換性のある任意のコンテナランタイムで動作するはずです。このデバイスプラグインはContainer-Optimized OSでテストされていて、1.9以降ではUbuntu向けの実験的なコードも含まれています。

以下のコマンドを実行すると、NVIDIAのドライバーとデバイスプラグインをインストールできます。

# NVIDIAドライバーをContainer-Optimized OSにインストールする
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/daemonset.yaml

# NVIDIAドライバーをUbuntuにインストールする(実験的)
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/nvidia-driver-installer/ubuntu/daemonset.yaml

# デバイスプラグインをインストールする
kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes/release-1.14/cluster/addons/device-plugins/nvidia-gpu/daemonset.yaml

このサードパーティーのデバイスプラグインの使用やデプロイに関する問題は、GoogleCloudPlatform/container-engine-acceleratorsで報告できます。

Googleは、GKE上でNVIDIAのGPUを使用するための手順も公開しています。

異なる種類のGPUを搭載するクラスター

クラスター上の別のノードに異なる種類のGPUが搭載されている場合、NodeラベルとNodeセレクターを使用することで、Podを適切なノードにスケジューリングできます。

以下に例を示します。

# アクセラレーターを搭載したノードにラベルを付けます。
kubectl label nodes <node-with-k80> accelerator=nvidia-tesla-k80
kubectl label nodes <node-with-p100> accelerator=nvidia-tesla-p100

自動的なNodeラベルの付加

AMDのGPUデバイスを使用している場合、Node Labellerをデプロイできます。Node Labellerはコントローラークラスターの状態をAPIサーバーから取得、見張る制御ループで、現在の状態を望ましい状態に移行するように更新します。 の1種で、GPUデバイスのプロパティを持つノードに自動的にラベルを付けてくれます。

現在は、このコントローラーは以下のプロパティに基づいてラベルを追加できます。

  • デバイスID(-device-id)
  • VRAMのサイズ(-vram)
  • SIMDの数(-simd-count)
  • Compute Unitの数(-cu-count)
  • ファームウェアとフィーチャーのバージョン(-firmware)
  • 2文字の頭字語で表されたGPUファミリー(-family)
    • SI - Southern Islands
    • CI - Sea Islands
    • KV - Kaveri
    • VI - Volcanic Islands
    • CZ - Carrizo
    • AI - Arctic Islands
    • RV - Raven
kubectl describe node cluster-node-23
    Name:               cluster-node-23
    Roles:              <none>
    Labels:             beta.amd.com/gpu.cu-count.64=1
                        beta.amd.com/gpu.device-id.6860=1
                        beta.amd.com/gpu.family.AI=1
                        beta.amd.com/gpu.simd-count.256=1
                        beta.amd.com/gpu.vram.16G=1
                        beta.kubernetes.io/arch=amd64
                        beta.kubernetes.io/os=linux
                        kubernetes.io/hostname=cluster-node-23
    Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                        node.alpha.kubernetes.io/ttl: 0
    …

Node Labellerを使用すると、GPUの種類をPodのspec内で指定できます。

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100 # または nvidia-tesla-k80 など

これにより、指定した種類のGPUを搭載したノードにPodがスケジューリングされることを保証できます。

最終更新 July 27, 2020 at 1:27 PM PST: Remove unnecessary spaces (db0a6fc95)