JujuでKubernetesをデプロイする方法については以前、次のように書きました。
では、今回は「Jujuで構築するKubernetesでGPUを使うには」と言う話を書きたいと思います。 と言っても割と簡単で、Kubernetes WorkerノードにNVIDIAのGPUを挿して、juju deploy kubernetesでドーンで終了です。
JujuでGPU対応Kubernetes環境を作る
前回の記事でも書いた通り、Jujuはアプリケーション単体の設定などが定義されているCharm、それを一つにまとめたBundleがあります。Kubernetes WorkerのCharmの設定一覧を見ると簡単に導入できる理由がわかると思います。
現在のKubernetes Workerのリビジョンは106が安定版なので、その設定は次のURLで確認できます(平成30年3月28日現在)。
https://api.jujucharms.com/charmstore/v5/~containers/kubernetes-worker-106/archive/config.yaml
該当の部分を抜き出すとこれです。install-cudaのパラメーターがデフォルトでtrueになっています。このため、Kubernetes WorkerのホストにNVIDIAのGPUカードが接続されていると必要なGPUドライバーやCUDAなどがインストールされるわけです。
"install-cuda": "type": "boolean" "default": !!bool "true" "description": | Install the CUDA binaries if capable hardware is present.
[平成30年5月24日 追記]
最近のJuju Charmでは、install-cudaというオプションは無くなっています。NVIDIA GPUがスロットに接続されている場合、デフォルトで必要なドライバーがホストにインストールされます。
さて、DockerコンテナーでGPUを使うと言うと「NVIDIA Docker」を想像すると思います。実はKubernetesでGPUを取り扱う場合、NVIDIA Dockerは必須ではありません。JujuでKubernetesの環境を作った場合はGPU DriverとCUDAがインストールされるだけで、NVIDIA Dockerは自動的にインストールはされません。アプリケーションの要件でNVIDIA Dockerが必要な場合はGPUが載ったKubernetes Workerノードにログインしてインストールする必要があります。juju sshコマンドでログインして、セットアップします。
[平成30年5月24日 追記]
必須ではありませんが、いれた方が色々と便利なので、今回は入れる方向でセットアップします。
最近のJuju Charmでは、GPUをコンテナーで利用するために必要なパッケージは自動でインストールされます。
NVIDIA Docker 2をインストール
[平成30年5月24日 追記] 最近のJujuを使った場合は自動インストールされますので、この項はスキップしてください。
GitHubサイトを確認すると、NVIDIA Dockerにはバージョン1と2が存在するのがわかります。バージョン1は開発終了しており、新しく導入するのであればバージョン2の導入をおススメします。
ところがQuick Startに従ってインストールしようとすると「docker-ceがインストールされていないので無理」といわれて詰みます。
% sudo apt-get install -y nvidia-docker2
JujuでKubernetes Workerを構築した場合、Ubuntuアーカイブのdocker.ioパッケージがインストールされます。nvidia-docker2をインストールするときに導入済み済みのDockerバージョンを指定するとうまくいきます。方法は次のページに書かれています。
まず、公開されているnvidia-docker2とnvidia-container-runtimeのバージョンを確認します。現在はnvidia-docker2はバージョン2.0.3、nvidia-container-runtimeは2.0.0が最新版のようです。
出力結果を見ればわかるように、Dockerのバージョンによって導入すべきパッケージが分かれていることがわかると思います。
% apt list -a nvidia-docker2 nvidia-container-runtime Listing... Done nvidia-container-runtime/xenial 2.0.0+docker18.03.0-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.12.1-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.12.0-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.09.1-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.09.0-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.06.2-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker17.03.2-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker1.13.1-1 amd64 nvidia-container-runtime/xenial 2.0.0+docker1.12.6-1 amd64 ... nvidia-docker2/xenial 2.0.3+docker18.03.0-1 all nvidia-docker2/xenial 2.0.3+docker17.12.1-1 all nvidia-docker2/xenial 2.0.3+docker17.12.0-1 all nvidia-docker2/xenial 2.0.3+docker17.09.1-1 all nvidia-docker2/xenial 2.0.3+docker17.09.0-1 all nvidia-docker2/xenial 2.0.3+docker17.06.2-1 all nvidia-docker2/xenial 2.0.3+docker17.03.2-1 all nvidia-docker2/xenial 2.0.3+docker1.13.1-1 all nvidia-docker2/xenial 2.0.3+docker1.12.6-1 all
Ubuntu 16.04.4でインストールされるdocker.ioは次のように実行すると1.13.1であることがわかります。
% apt list -a docker.io Listing... Done docker.io/xenial-updates,now 1.13.1-0ubuntu1~16.04.2 amd64 [installed] docker.io/xenial 1.10.3-0ubuntu6 amd64
というわけで、次のようにバージョンを指定してインストールすれば良いわけです。
% sudo apt install -y nvidia-docker2=2.0.3+docker1.13.1-1 nvidia-container-runtime=2.0.0+docker1.13.1-1
ついでに関連するパッケージのバージョンを固定しておくと良いでしょう。
% sudo apt-mark hold docker.io nvidia-docker2 nvidia-container-runtime
GPU Podを作ろう
それでは早速、GPUが使えるPodを作ってみます。KubernetesのGPU Scheduleについては次のページにまとまっています。
ここに書かれているサンプルファイルをちょっと書き換えて、次のようなYAMLを書いてみます。この後の旧方式のYAMLと比べてシンプルであるのがわかると思います。ちなみにnvidia.com/gpu
を使った場合はドライバーやライブラリーのパスの指定などは自動でやってくれるので、DockerのCUDAイメージを使わないで(例えばcentos:7とかubuntu:18.04などを指定して)も、PodにGPUを割り当てることができます。
apiVersion: v1 kind: Pod metadata: name: testpod-cuda91 spec: restartPolicy: OnFailure containers: - name: testpod-cuda91 image: nvidia/cuda:9.1-base tty: true resources: limits: nvidia.com/gpu: 1
なお、Kubernetes 1.9,1.10では、Kubernetes 1.6や1.7の頃のYAMLの書き方でもGPU Podを作ることができます。
GPUドライバーなどのパスを指定していたり、alpha.kubernetes.io/nvidia-gpu
を指定していたりする点が異なります。
この形式はKubernetes 1.10までサポートされますが、いずれサポートを終了するとのことです。
apiVersion: v1 kind: Pod metadata: name: testpod spec: restartPolicy: OnFailure containers: - name: nvidia-cuda image: nvidia/cuda:9.1-base tty: true resources: limits: alpha.kubernetes.io/nvidia-gpu: 1 # requesting 1 GPU volumeMounts: - name: bin mountPath: /usr/local/nvidia/bin - name: lib mountPath: /usr/local/nvidia/lib volumes: - hostPath: path: /usr/lib/nvidia-390/bin name: bin - hostPath: path: /usr/lib/nvidia-390 name: lib
旧形式の記述ではvolumesでは、Kubernetes Workerホストにインストール済みのNVIDIAツールの実行ファイルと関連ライブラリーを指定しています(当然ながらバージョンを指定していますので、バージョンが変わればここの記述も変える必要があります。)。これを上のcontainersのvolumeMountsでマウントしています。
いずれかのYAMLをfirst-gpupod.ymlという名前で保存して、次のように実行しましょう。 GPU Podが作成できます。
% kubectl create -f first-gpupod.yml % kubectl get pod testpod NAME READY STATUS RESTARTS AGE testpod 1/1 Running 0 2m % kubectl exec -it testpod nvidia-smi Wed Mar 28 01:33:02 2018 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 390.30 Driver Version: 390.30 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 1080 Off | 00000000:01:00.0 Off | N/A | | 27% 29C P8 11W / 180W | 0MiB / 8119MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
作成したPodは次のコマンドで削除できます。
% kubectl delete -f first-gpupod.yml
こんな形です。本日は以上です。 次回はChainerでGPUを使ってなにかやってみたいと思います。