LXD 2.0.8/2.6から、LXDコンテナとホストのUID/GIDを設定コマンドからremapできるようになりました。これにより「コンテナの中からホストのホームディレクトリを読み書きする」ための手順が非常に簡単になります。
詳しいことは以下の記事を参照してください。
必要なパッケージのインストール
最新のLXDをインストールしてください。Ubuntu 16.04 LTSであれば、パッケージを更新すればLXD 2.0.8になるはずです。
$ sudo apt update
$ sudo apt install lxd
lxd
グループに所属するために、一度ログインしなおしてください。
LXDを使いはじめる前にLXDの初期設定を行います。基本的に次のコマンドを実行して、提案される設定をそのまま適用していくだけです。
$ sudo lxd init
LXDの使い方についてはLXDの公式サイトのヘルプやLXD Blog post seriesを参考にすると良いでしょう。LXDの試用ページにあるチュートリアルも参考になります。
subuid
とsubguid
の変更
ここからが今回の機能に関する説明です。
まずコンテナ起動時に実行されるnewuidmap/newgidmap
において、ホストのUID/GIDをマッピングできるようにsubuid/subgid
ファイルを編集します。
Ubuntuの標準の設定だと、インストール時に作ったユーザーのUIDとGIDはどちらも1000になりますので、次のコマンドで設定できます。
$ echo "root:1000:1" | sudo tee -a /etc/subuid /etc/subgid
これはrootがnewuidmap/newgidmap
を使って、ホスト上のUID/GIDをユーザー名前空間のマッピングに使えるすることを意味しています。各フィールドの意味は「USER NAME:START ID:NUM
」です。
もし異なるUIDやGIDを許可したい場合は、次のように個別に設定しましょう。
$ echo "root:$(id -u):1" | sudo tee -a /etc/subuid
$ echo "root:$(id -g):1" | sudo tee -a /etc/subgid
ここまでは一度設定するだけです。
コンテナの作成とUID/GIDのマッピング
次にコンテナを作成します。Ubuntu 16.04 LTSのコンテナを「xenial
」という名前で作成しています。
$ lxc init ubuntu:16.04 xenial
xenial
コンテナに対してUID/GIDのマッピングを設定します。これはraw.idmap
設定を変更するだけです。
$ lxc config set xenial raw.idmap 'both 1000 1000'
「both
」はUID/GID両方に同じ値を設定するパラメーターです。書式は「both HOST_ID CONTAINER_ID
」となります。HOST_ID
にはホスト上のUID/GIDを、`CONTAINER_IDにはHOST_IDをコンテナの中にマップした時のIDを記述します。言い換えると「ホスト上のUID/GID 1000をコンテナ上のUID/GID 1000として扱う」ということです。これでコンテナからホストのUID/GID 1000のファイルを扱えることになります。
もしUID/GIDを異なる値にしたい場合はboth
のかわりにuid
やgid
を使います。raw.idmap
に複数の値を設定する場合は、改行を入れます。しかしながらlxc config
コマンドは直接改行を扱えません。そこで設定内容を標準入力から受け付けるようにして、そこにパイプで設定内容を流し込みます。たとえばホスト上のUIDが1010、GIDが1011のIDをコンテナ上のUID/GIDともに1000にマッピングしたい場合は、次のようにコマンドを実行します。
$ echo -e "uid 1010 1000\ngid 1011 1000" | lxc config set xenial raw.idmap -
ハイフンをつないで範囲を指定することも可能です。この場合、マッピング元とマッピング先の個数が同じになるようにしてください。
lxc config show xenial
と実行すると、設定結果が表示されるはずです。
ちなみにlxc config
ではなくlxc profile
を使えば、この設定を複数のコンテナで共用できます。プロファイルに関する詳細はこちらを参照してください。
おそらく起動中の既存のコンテナにも上記設定は可能です。ただし設定が反映されるためには、一度コンテナの再起動が必要です。
ホームディレクトリのマウント
最後にホストのホームディレクトリをコンテナの中にbind mountしてみましょう。
$ lxc config device add xenail homedir disk source=/home/shibata/ path=/home/ubuntu/
この状態でコンテナを起動すると、コンテナの中でホストのホームディレクトリの読み書きが可能になっているはずです。また、コンテナで書き込んだファイルのオーナーIDは、ホストから見るとホストのユーザーのオーナーIDになっているはずです。
$ lxc start xenial
$ lxc file push ~/.ssh/id_rsa.pub xenial/home/ubuntu/.ssh/authorized_keys
$ lxc list
(コンテナの情報表示)
$ ssh ubuntu@コンテナのアドレス
xenial$ ls ~/
(ホストのホームディレクトリと同じ結果になる)
xenial$ echo "test" > abc.txt
(書き込める)
xenial$ exit
$ cat abc.txt
test
$ ls -l abc.txt
(オーナーがホストのUID/GIDに一致している)