第641回では
ホスト側でGPUパススルーの準備
第641回ではLXDの仮想マシンインスタンスの上にmicrok8sをインストールしました。つまりホストマシンのGPUを使うには、
この方法の注意点はふたつあります。まず、
それに対してフィーチャーリリースは、
もうひとつの注意点はGPUが仮想マシンに占有されてしまうことです。仮想マシンの場合、
よってまずはLXDをフィーチャーリリースに変更します。新規にインストールする際はsnap install
」--channel=latest/
」
$ sudo snap refresh --channel=latest/stable lxd lxd 4.7 from Canonical✓ refreshed $ lxd --version 4.7
これでLXD側の準備は整いました。次にカーネル側の準備を行います。Intelの場合、
「/etc/
」GRUB_
を次のように変更してください。
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"
あとはGRUBの変更を反映します。
$ sudo update-grub
またNVIDIAのGPUを利用している場合、
$ echo "blacklist nouveau" | sudo tee -a /etc/modprobe.d/blacklist-nouveau.conf
ここまで実行したら、IOMMU enabled
」
$ dmesg | grep IOMMU [ 0.114164] DMAR: IOMMU enabled [ 0.217696] DMAR-IR: IOAPIC id 2 under DRHD base 0xfed91000 IOMMU 1
もし表示されない場合、
仮想マシンインスタンスからGPUを見えるようにする
GPUを使うための仮想マシンインスタンスを用意します。このあたりは第641回とほぼ同じです。
$ lxc launch ubuntu:20.04 kubeflow --vm -c limits.cpu=4 -c limits.memory=16GiB $ lxc exec kubeflow -- sed -i 's/archive.ubuntu/jp.archive.ubuntu/' /etc/apt/sources.list $ lxc exec kubeflow -- timedatectl set-timezone Asia/Tokyo $ lxc exec kubeflow -- sh -c 'apt update && apt full-upgrade -y'
インスタンス名が
次に一度インスタンスを停止して、
$ lxc stop kubeflow $ lxc config device override kubeflow root size=150GiB $ lxc config set kubeflow security.secureboot=false $ lxc config device add kubeflow nv gpu vendorid=10de $ echo -n '-cpu host,kvm=off' | lxc config set kubeflow raw.qemu - $ lxc start kubeflow
ストレージを増やしていますが、
まずsecurity.
」lxc console
」
次にlxc config device add
」nv
」
$ lspci -nn | grep -i nvidia 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1) 01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
他にもproductid
」
最後は仮想マシンの中でNVIDIAのGPUを使うためのオプションとなります。raw.
」-cpu host,kvm=off
」raw.
に任意の文字列を設定することで、kvm=off
」
どんな仮想マシンシステムもゲストの中からhypervisor guest status = true
」hypervisor_
」kvm=off
」
設定後にインスタンスを起動したら、
$ lxc exec kubeflow -- lspci -nn | grep -i nvidia 06:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1) 06:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
サーバー向けNVIDAドライバーのインストール
インスタンスの中からGPUデバイスが見えるようになったので適切なデバイスドライバーをインストールします。AMD系であれば標準のドライバーで問題ないはずですし、
具体的なインストール方法は第454回の
では、
- nvidia-driver-440:nvidia-driver-450に依存するだけの移行用ダミーパッケージ
- nvidia-driver-440-server:NVIDA Driver 440.
95. 01をインストールする - nvidia-driver-450:NVIDA Driver 450.
80. 02をインストールする - nvidia-driver-450-server:NVIDA Driver 450.
80. 02をインストールする
つまり
さらにサーバー向けとして
ここからはNVIDIAのGPU前提で話を進めます。まずはドライバーのインストールです。次のコマンドでインストールできるバージョンを確認して、
インストール可能なバージョンを確認する: $ lxc exec kubeflow -- apt search "^nvidia-headless-[0-9]" 最新もしくは必要なバージョンをインストールする: $ lxc exec kubeflow -- apt install -y nvidia-headless-450 => 今回はバージョンアップを許容して「-server」がついていない方を選択 念のため再起動する: $ lxc restart kubeflow ロードされていることを確認する: $ lxc exec kubeflow lsmod | grep nvidia nvidia_uvm 847872 0 nvidia_modeset 1060864 0 nvidia 18190336 18 nvidia_uvm,nvidia_modeset nvidia_drm 12288 0
ちなみに実機にNVIDIAドライバーをインストールしたときと比べるとDRMやKMS関連のドライバーがロードされていないことに気がつくかもしれません。これはLXDの仮想マシンインスタンスで使用しているカーネルCONFIG_
などサーバーで使うことが少ないコンフィグを軒並み無効化しているためです。もし、
$ lxc exec kubeflow -- sh -c 'apt install -y linux-generic' $ lxc exec kubeflow -- sh -c 'apt remove -y ~nlinux-.*kvm' => 実行中のカーネルパッケージを削除することになるので、 削除を中断するか(Abort kernel removal?)という問い合わせが表示される。 消すのが正しいのでNoを選択する。 GRUBメニューから通常のカーネルで起動したあとに消しても良い。 $ lxc restart kubeflow
恒例のnvidia-smi
コマンドで動作確認しましょう。
$ lxc exec kubeflow -- apt install nvidia-utils-450 $ lxc exec kubeflow nvidia-smi Sat Nov 14 20:52:25 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 450.80.02 Driver Version: 450.80.02 CUDA Version: 11.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 GeForce GTX 105... Off | 00000000:06:00.0 Off | N/A | | 0% 49C P0 N/A / 72W | 0MiB / 4040MiB | 1% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
もしUnable to determine the device handle for GPU 0000:06:00.
」raw.
設定に-cpu host,kvm=off
」ps -fe | grep kvm=off
」
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
いろいろ準備するためにそれなりに時間がかかります。気長に待ちましょう。無事にセットアップが完了したら、
$ 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
したあとはイメージのダウンロードなどでしばらく時間がかかりますが、
$ lxc exec kubeflow microk8s kubectl delete pod cuda-vector-add
たとえば意図的にGPUを削除した上で実行すると、
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
」
$ 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.
」
$ lxc exec kubeflow -- microk8s kubectl get pod NAME READY STATUS RESTARTS AGE cuda-vector-add 0/1 RunContainerError 2 23s
kubectl describe
を実行すれば、
以上のように正しく設定してあるときちんとGPUがコンテナから見えて、
ここから先はGPUが使えるKubernetes環境なので、