Ubuntu Weekly Recipe

第642回 仮想マシン上のmicrok8sからGPUを利用する

この記事を読むのに必要な時間:およそ 7 分

microk8sでGPUを有効化する

前回と同じようにmicrok8sをインストールしましょう。

$ lxc exec kubeflow -- snap install microk8s --classic --channel=1.19
microk8s (1.19/stable) v1.19.2 from Canonical✓ installed
$ lxc exec kubeflow -- usermod -a -G microk8s ubuntu

GPUの有効化もコマンド一発です。

$ lxc exec kubeflow -- microk8s enable gpu
Enabling NVIDIA GPU
NVIDIA kernel module detected
Enabling DNS
Aispplying manifest
serviceaccount/coredns created
configmap/coredns created
deployment.apps/coredns created
service/kube-dns created
clusterrole.rbac.authorization.k8s.io/coredns created
clusterrolebinding.rbac.authorization.k8s.io/coredns created
Restarting kubelet
DNS is enabled
Applying manifest
daemonset.apps/nvidia-device-plugin-daemonset created
NVIDIA  enabled

いろいろ準備するためにそれなりに時間がかかります。気長に待ちましょう。無事にセットアップが完了したら,kube-system名前空間において,NVIDIAデバイスプラグインのPodが動いていることが確認できます。

$ lxc exec kubeflow -- microk8s kubectl get pods -A | grep nvidia
kube-system   pod/nvidia-device-plugin-daemonset-k6ps7      1/1     Running   0          16m

試しにmicrok8sのドキュメントにもあるcuda-vector-addを使ってみましょう。これは単にCUDAのAPIを使ってSIMD演算するだけのPodです。

$ cat <<'EOF' > gpu-sample.yaml
apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: cuda-vector-add
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
EOF

あとはPodを作成して,状態を確認してみます。

$ cat gpu-sample.yaml | lxc exec kubeflow -- microk8s kubectl create -f -
pod/cuda-vector-add created

$ lxc exec kubeflow -- microk8s kubectl get pod
NAME              READY   STATUS      RESTARTS   AGE
cuda-vector-add   0/1     Completed   0          9s

cube-vector-addはいわゆるデーモンなどではなくCUDAの演算をして終了するだけのコマンドです。kubectl createしたあとはイメージのダウンロードなどでしばらく時間がかかりますが,最終的に「Completed」で完了します。完了したら削除しておきましょう。

$ lxc exec kubeflow microk8s kubectl delete pod cuda-vector-add

たとえば意図的にGPUを削除した上で実行すると,⁠Pendig」で停止します。

GPUを削除する:
$ lxc stop kubeflow
$ lxc config device remove kubeflow nv
$ lxc start kubeflow

もう一度Podを作成する:
$ cat gpu-sample.yaml | lxc exec kubeflow -- microk8s kubectl create -f -

ペンディングになっていることがわかる:
$ lxc exec kubeflow -- microk8s kubectl get pod
NAME              READY   STATUS    RESTARTS   AGE
cuda-vector-add   0/1     Pending   0          22s

kubectl decribeで確認すると,GPUを確保しようとして待っていることがわかります。

$ lxc exec kubeflow -- microk8s kubectl describe pod cuda-vector-add
(中略)
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  56s (x2 over 56s)  default-scheduler  0/1 nodes are available: 1 Insufficient nvidia.com/gpu.

YAMLファイルの中でnvidia.com/gpu: 1と書いているため,当然と言えば当然です。さらにこの部分をコメントアウトしてGPUがなくても強制的に実行しようとすると,次のようにエラー終了します。

$ lxc exec kubeflow -- microk8s kubectl get pod
NAME              READY   STATUS              RESTARTS   AGE
cuda-vector-add   0/1     RunContainerError   2          23s

kubectl describeを実行すれば,CUDA関連のエラーが残っているはずです。

以上のように正しく設定してあるときちんとGPUがコンテナから見えて,CUDAも使えることがわかりました。

ここから先はGPUが使えるKubernetes環境なので,好きなコンテナイメージで,インスタンス代を気にすることなく好きなだけたくさんGPUを動かして,寒い冬を乗り切りましょう!※3

※3
電気代については考慮しないものとします。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。