5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LXC で NVIDIA GPU が使える非特権コンテナを作る

Last updated at Posted at 2020-02-04

異なるバージョンのCUDAを一つの計算機で共存したいときにこうすると便利である。ホスト側のLinuxで nvidia-smi を実行したときと同じようにコンテナ内の nvidia-smi が動作するようにする。LXC でコンテナを作成し実行することはすでに出来ているとする。(非特権コンテナとUbuntu 20.04に合わせて記事を少し更新した)。一般ユーザー(非rootユーザー)でコンテナを作りたい場合 ここ を参照

ホスト側でnvidia-smiを実行すると以下のように見える

# nvidia-smi
Tue Feb  4 10:52:19 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.48.02    Driver Version: 440.48.02    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| 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 RTX 208...  Off  | 00000000:08:00.0 Off |                  N/A |
| 30%   31C    P8    25W / 250W |     18MiB / 11016MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce RTX 208...  Off  | 00000000:09:00.0 Off |                  N/A |
| 29%   32C    P8    20W / 250W |      1MiB / 11019MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1262      G   /usr/lib/xorg/Xorg                            16MiB |
+-----------------------------------------------------------------------------+

ホスト側での作業

まず lxc-create -n コンテナ名 -t download -- -d ubuntu -r focal -a amd64 でUbuntuのコンテナを作る。もし /var/lib/lxc がBTRFSにあるなら -B btrfs を付けておくと後で lxc-copy -n 古いコンテナ -N 新しいコンテナ でコンテナを複製するときに掛かる時間が劇的に短くなる。

次に lxc-execute -n コンテナ名 -- /bin/passwd でrootに適切なパスワードを設定する。

以下の設定を追加する

/var/lib/lxc/コンテナ名/configに追加
lxc.mount.entry = /dev/nvidiactl dev/nvidiactl none bind,rw,create=file 0 0
lxc.mount.entry = /dev/nvidia-modeset dev/nvidia-modeset none bind,rw,create=file,optional 0 0
lxc.mount.entry = /dev/nvidia-uvm dev/nvidia-uvm none bind,rw,create=file 0 0
lxc.mount.entry = /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,rw,create=file 0 0
lxc.mount.entry = /dev/nvidia0 dev/nvidia0 none bind,rw,create=file 0 0
lxc.mount.entry = /dev/nvidia1 dev/nvidia1 none bind,rw,create=file,optional 0 0
# 以下は非特権コンテナなら不要、またホストLinuxがFedora 31などCGroup2を用いるディストロの場合
# cgroupをcgroup2に置き換える
lxc.cgroup.devices.allow = c 195:* rwm
lxc.cgroup.devices.allow = c 235:* rwm

最後に lxc-start -F -n コンテナ名 でコンテナを起動する。ログインプロンプトが表示されたらrootでログインする。非特権コンテナからNVIDIA GPUにアクセスするためには上記の '/dev' 以下のファイルの所有者またはグループをコンテナ内のroot(たいていの場合100000)にchownchgrp で予めホスト側で変更しておく必要がある

コンテナ内での作業

apt-get --no-install-recommends install software-properties-common
add-apt-repository ppa:graphics-drivers/ppa
# 上記2行はUbuntu Focalでは不要
apt-get --no-install-recommends install nvidia-utils-440

最後のnvidia-utils-440 はホスト側LinuxのNVIDIAドライバのバージョンと完全に同一でないとエラーになりnvidia-smiが動作しないので注意。ここまで行いコンテナ内でnvidia-smiを実行すると

# nvidia-smi
Tue Feb  4 02:01:33 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.48.02    Driver Version: 440.48.02    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| 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 RTX 208...  Off  | 00000000:08:00.0 Off |                  N/A |
| 30%   31C    P8    26W / 250W |     18MiB / 11016MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce RTX 208...  Off  | 00000000:09:00.0 Off |                  N/A |
| 29%   32C    P8    20W / 250W |      1MiB / 11019MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

となる。

ホストの/homeをコンテナ内で見えるようにするには

/var/lib/lxc/コンテナ名/configに追加
lxc.mount.entry = /home home none bind,rw 0 0

非特権コンテナの場合上記の方法では /home 以下のすべてのファイルの所有者が nobody になってしまし、まともにアクセスできない。その不都合を解消するためには、読み書きしたいファイルのUIDが1000であるとして、コンテナの設定ファイルの中のUID/GIDの変換方法を指定している lxc.idmap の行を例えば以下のように書き換えるとよい。

$HOME/.local/share/lxc/コンテナ名/configを変更
lxc.idmap = u 0 100000 1000
lxc.idmap = g 0 100000 1000
lxc.idmap = u 1000 1000 1
lxc.idmap = g 1000 1000 1
lxc.idmap = u 1001 101001 64535
lxc.idmap = g 1001 101001 64535

上記のように書き換えるとホスト側ほホームディレクトリのUID 1000, GID 1000 がコンテナ内部でもUID 1000, GID 1000に割り当てられるため、UID 1000のユーザーがそのホームディレクトリにあるファイルを操作できるようになる。

他のホストからネットワーク的に見えるようにするには

設定ファイルに以下の内容を追加する。以下の設定はlxc-startをrootから起動しないとエラーになりできない(コンテナは非特権でも構わない)。

/var/lib/lxc/コンテナ名/configに追加
lxc.net.0.type = macvlan
lxc.net.0.link = enp6s0 # この名前は "ip l" で表示されるEthernetインターフェースの名前
lxc.net.0.flags = up
lxc.net.0.name = eth0
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?