概要
それなりのスペックを有したXeonでGTX1080 2枚載せなワークステーション(死語)に触れる機会を得たので、良い感じに皆で活用すべくProxmox VEを入れてみた。
その上でUbuntu 16.04なLXC Containerを動作させて、そこでCUDAを動かそうとした。しかしながら思いの外つまずいたのでメモっておく。
前提
Proxmox VE 4.4は予めインストールされていることとする。
なお余談だがFakeRAID(Intel RST)なドライブ上にProxmox VEをインストールしたかったので、Debianを入れてからProxmox VEに仕立て上げた。
Install Proxmox VE on Debian Jessie - Proxmox VE
参考文献
基本的には参考文献をなぞった。
Journey to Deep Learning: Nvidia GPU passthrough to LXC Container
Setting up CUDA in Linux containers - SQream
ホストマシンへのNVIDIAドライバインストール
ドライバのバージョンは 381.22
を入れることにした。
注意点として、ホストマシンに入れたドライバのバージョンとコンテナ上に入れたドライバのバージョンは完全一致 させておく必要がある。
wget http://jp.download.nvidia.com/XFree86/Linux-x86_64/381.22/NVIDIA-Linux-x86_64-381.22.run
sudo chmod a+x NVIDIA-Linux-x86_64-381.22.run
sudo ./NVIDIA-Linux-x86_64-381.22.run
適当にポチポチすればインストールできる。
余談: 最新ドライバのチェック方法
公式サイトを見に行くとちゃんとまとまっている。
NVIDIAドライバダウンロード
余談: アンインストール方法
aptで入れたわけじゃないので sudo apt remove --purge nvidia*
等で削除はできない。以下のようにして削除する。
sudo ./NVIDIA-Linux-x86_64-381.22.run --uninstall
ホストマシンの設定
この状態だとCUDAのドライバがカーネルにロードされないらしい。
なので以下のようにファイルをかきかきしておく。
/etc/modules-load.d/modules.conf
# /etc/modules: kernel modules to load at boot time.
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with “#” are ignored.
nvidia
nvidia_uvm
/etc/udev/rules.d/70-nvidia.rules
# Create /nvidia0, /dev/nvidia1 … and /nvidiactl when nvidia module is loaded
KERNEL=="nvidia", RUN+="/bin/bash -c '/usr/bin/nvidia-smi -L && /bin/chmod 666 /dev/nvidia*'"
# Create the CUDA node when nvidia_uvm CUDA module is loaded
KERNEL=="nvidia_uvm", RUN+="/bin/bash -c '/usr/bin/nvidia-modprobe -c0 -u && /bin/chmod 0666 /dev/nvidia-uvm*'"
設定変更後は以下コマンドを実行
update-initramfs -u
reboot
ドライバ動作チェック
nvidia-smi
デバイスのcgroupをチェック
sudo nvidia-smi -L && /bin/chmod 666 /dev/nvidia*
sudo nvidia-modprobe -c0 -u && /bin/chmod 0666 /dev/nvidia-uvm*
ls /dev/nvidia* -l
`195`と`244`というのをメモっておく。
# コンテナ作成
## Templateのダウンロード
local -> Content -> Templates

ubuntu-16.04-standard

## Create LXC
適当に作成。


## 設定変更
ホストマシンの以下のファイルを次のように編集。
ここで先程メモった`195`と`244`が効いてくる。
` /etc/pve/lxc/104.conf` (104はCT ID)
arch: amd64
cores: 44
hostname: UbuntuLXCforBD
memory: 65536
net0: name=eth0,bridge=vmbr0,gw=192.168.0.1,hwaddr=AE:1D:D8:47:0F:37,ip=192.168.0.6/24,type=veth
ostype: ubuntu
rootfs: local:104/vm-104-disk-1.raw,size=128G
swap: 12288
以下追記分
lxc.cgroup.devices.allow: c 195:* rwm
lxc.cgroup.devices.allow: c 244:* rwm
lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry: /dev/nvidia1 dev/nvidia1 none bind,optional,create=file
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
この設定追記によってコンテナ内から当該デバイスへのアクセスが可能となる。
## 起動
適当に起動。

# コンテナへNVIDIAドライバインストール
コンテナへSSHして以下のように実行。
wget http://jp.download.nvidia.com/XFree86/Linux-x86_64/381.22/NVIDIA-Linux-x86_64-381.22.run
chmod a+x NVIDIA-Linux-x86_64-381.22.run
./NVIDIA-Linux-x86_64-381.22.run --no-kernel-module
# コンテナへCUDA Toolkitをインストール
引き続きコンテナへSSHして実行。
## 必要なライブラリをインストール
apt-get update
apt-get install build-essential perl-modules g++ freeglut3 freeglut3-dev libglu1-mesa libxi-dev libxmu-dev libglu1-mesa-dev
ln -s /usr/lib/x86_64-linux-gnu/libXmu.so /usr/lib/libXmu.so
ln -s /usr/lib/x86_64-linux-gnu/libXi.so /usr/lib/libXi.so
## runfileでインストール
公式サイトからrunfileを拾ってくる
[CUDA Toolkit Download | NVIDIA Developer](https://developer.nvidia.com/cuda-downloads)

wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_375.26_linux-run
chmod a+x cuda_8.0.61_375.26_linux-run
./cuda_8.0.61_375.26_linux-run --silent --toolkit --samples --override
# コンテナ上でのCUDA動作チェック
gcc-4.9じゃないとコンパイルにコケるので…
apt-get install gcc-4.9 g++-4.9
ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gcc
ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++
makeして実行
cd NVIDIA_CUDA-8.0_Samples/
make -j4
./bin/x86_64/linux/release/deviceQuery

# 所感
NVIDIA Dockerの楽さを思い知った今日このごろ…
おしまい。