Ubuntu Weekly Recipe

第532回 LXDのコンテナからGPUを利用する

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

第521回ではUbuntu 18.04 LTSに最初からインストールされているコンテナ管理システムLXDについて紹介しました。今回はコンテナの中からホスト上のGPUデバイスを利用する方法を紹介しましょう。

コンテナから見えるデバイス

LXDで作成したコンテナからアクセスできるデバイスは,システムが起動するために必要なものだけに制限されています。

container$ ls /dev/
console  full     log     net   pts     stderr  tty
core     fuse     lxd     null  random  stdin   urandom
fd       initctl  mqueue  ptmx  shm     stdout  zero

しかしながらコンテナの中からもホスト上に見えているデバイスにアクセスできると嬉しい場合は多々あります。LXD 2.0以前でこれを行おうとするといろいろと細かい設定が必要でした。ところが,LXD 2.xの開発中にインターフェースが大きく改善され,Ubuntu 18.04 LTSに最初からインストールされているLXD 3.0においては,ほぼコマンド一発でホストの大抵のデバイスファイルを参照できるようになったのです。

設定が簡単になったデバイスの中で特に便利なのが,GPU,USB,NICでしょう。今回はこれらのデバイスのうちGPUの使い方について紹介します。なお,LXDの基本的な使い方と初期設定については第521回を参照してください。

GPUをコンテナの中からアクセスできるようにする

LinuxにおいてユーザーランドからGPUにアクセスする際は,主に/dev/dri以下のファイルを経由します。よってこのデバイスファイルへコンテナからアクセスできれば,GPUを使うツールをコンテナの中で動かせることになります。

LXDコンテナにホストのGPUデバイスを見せるには,次のコマンドを実行します。

$ lxc config device add container mygpu gpu
デバイス mygpu が container に追加されました

containerは任意のコンテナ名であり,mygpuは追加するデバイスに対するラベルです。

デバイスは実行中のコンテナの中でもすぐに見えるようになります。

$ lxc exec container -- ls -l /dev/dri
total 0
crw-rw---- 1 root root 226,   0 Aug 11 07:33 card0
crw-rw---- 1 root root 226, 128 Aug 11 07:33 renderD128

GPUデバイスの権限を変更する

デバイス追加時は,パーミッションに注意が必要です。一般的なビデオデバイスは,次のようにグループが「video」になるようudevが設定しています。

$ ls -l /dev/dri/
total 0
drwxr-xr-x 2 root root       120 Aug 11 06:17 by-path
crw-rw---- 1 root video 226,   0 Aug 11 06:17 card0
crw-rw---- 1 root video 226, 128 Aug 11 06:17 renderD128

一般的なユーザーはvideoグループに所属しているため※1)⁠特に設定することなくGPUにアクセスできます。ところがLXDコンテナの内部ではグループもrootになっているため,このままでは管理者権限でしかアクセスできないことになります。

※1
Ubuntu Serverの場合は,sudo usermod -aG video ユーザー名などで明示的にvideoグループに所属させる必要があります。

これを回避する方法はいくつかありますが,デバイス追加時にグループIDを指定するのが一番わかりやすいでしょう。

一旦デバイスを削除する
$ lxc config device remove container mygpu
デバイス mygpu が container から削除されました

グループIDを指定して追加する
$ lxc config device add cuda mygpu gpu \
  gid=`getent group video | cut -d: -f3`
デバイス mygpu が container に追加されました

$ lxc exec cuda -- ls -l /dev/dri
total 0
crw-rw---- 1 root video 226,   0 Aug 11 06:18 card0
crw-rw---- 1 root video 226, 128 Aug 11 06:18 renderD128

無事にvideoグループに所属するようになりました。

デバイス追加時はgid=グループIDでデバイスファイルのグループIDを変更できます。今回はvideoグループに所属させたかったのでgetentコマンドでvideoグループのIDを抽出し,それを指定しています。なおuid=を指定することで,ユーザーIDも変更できます。

追加するGPUデバイスを指定する

複数のグラフィックカードを繋いでいたり,内蔵GPUと外付けGPUの両方が存在する場合,/dev/dri以下には複数のGPUデバイスファイルが作成されます。このうち一部のGPUのみをLXDコンテナに展開したい場合は,idオプションを指定します。

たとえばこのマシンは2つのGPUが認識されています。

$ ls -l /dev/dri/
total 0
drwxr-xr-x 2 root root       120 Aug 11 06:17 by-path
crw-rw---- 1 root video 226,   0 Aug 11 06:17 card0
crw-rw---- 1 root video 226,   1 Aug 11 06:17 card1
crw-rw---- 1 root video 226, 128 Aug 11 06:17 renderD128
crw-rw---- 1 root video 226, 129 Aug 11 06:17 renderD129

by-pathのほうを見ると,それぞれのGPUがどのようにPCIバスにぶら下がっているかがわかります。

$ ls -l /dev/dri/by-path/
total 0
lrwxrwxrwx 1 root root  8 Aug 11 06:17 pci-0000:00:02.0-card -> ../card1
lrwxrwxrwx 1 root root 13 Aug 11 06:17 pci-0000:00:02.0-render -> ../renderD129
lrwxrwxrwx 1 root root  8 Aug 11 06:17 pci-0000:01:00.0-card -> ../card0
lrwxrwxrwx 1 root root 13 Aug 11 06:17 pci-0000:01:00.0-render -> ../renderD128

lspciコマンドで個々のアドレスのデバイスを見てみましょう。

$ lspci -s 0000:00:02.0
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 530 (rev 06)
$ lspci -s 0000:01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] (rev a1)

このことから,card0(0000:01:00.0)が外付けGPUであるGeForce GTX 1050 Tiであり,card1(0000:00:02.0)が内蔵GPUである Intel HD Graphics 530であることがわかります。

NVIDIAのGPU(card0)のみLXDコンテナの中から使いたいのであれば,次のように追加してください。

$ lxc config device add cuda mygpu gpu id=0

ちなみにCUDAなどの利用を目的とする場合,NVIDIAのドライバーが作成するデバイスファイルを読み書きすることになるので,/dev/dri以下のグループIDの変更は不要です。

著者プロフィール

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

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

コメント

コメントの記入