LXC ではコンテナのクローンを行う際に色々なストレージバックエンドの特徴を生かしたスナップショットクローンを行えます。この辺りは 連載の第 19 回〜 22 回 辺りで詳しく解説しています。
今まで、非特権LXCコンテナでストレージバックエンドの特徴を生かしたスナップショットクローンは、btrfs か overlayfs でしか行えませんでした。
先日、私の送ったパッチで aufs を使ったスナップショットクローンが一般ユーザ権限でもできるようになりました。
- aufs: Support unprivileged clone, mount · lxc/lxc@31a882e · GitHub
- Support unprivileged ephemeral container using aufs · lxc/lxc@dc80aa9 · GitHub
前者は liblxc 側の変更で lxc-clone や lxc-start 側で関係するパッチ、後者は lxc-start-ephemeral コマンドに関係するパッチです。
これで一般ユーザでも aufs を使った非特権クローンとコンテナが起動できるようなりました。簡単に紹介しておきます。
Plamo 5.3.1 に aufs パッチを当てた 4.1.1 カーネルを使っています。
$ lsb_release -d Description: Plamo Linux release 5.3.1 $ uname -r 4.1.1-plamo64-aufs
最近の aufs では allow_userns というモジュールオプションを Y にすると User Namespace 内の特権ユーザが aufs をマウントできるようになります。マニュアルにも記載があります。
私も手元では以下のように設定しています。
$ cat /etc/modprobe.d/aufs.conf options aufs allow_userns=1
こんな一般ユーザで操作しています。
$ id uid=1000(karma) gid=100(users) groups=100(users),26(audio),28(dialout),29(video),32(cdrom),36(kvm),38(pulse),39(pulse-access),44(mlocate),47(libvirt),60(docker),1000(sudo)
まず、普通に dir バックエンドを使ったコンテナを作成します。以下がその config の rootfs の設定。
$ grep lxc.rootfs ~/.local/share/lxc/ct01/config lxc.rootfs = /home/karma/.local/share/lxc/ct01/rootfs
このコンテナのクローンを作成します。
$ lxc-clone -o ct01 -n aufs01 -s -B aufs Created container aufs01 as snapshot of ct01 $ lxc-ls -f NAME STATE IPV4 IPV6 GROUPS AUTOSTART ---------------------------------------------- aufs01 STOPPED - - - NO ct01 STOPPED - - - NO
クローンは成功しています。
$ grep lxc.rootfs ~/.local/share/lxc/aufs01/config lxc.rootfs = aufs:/home/karma/.local/share/lxc/ct01/rootfs:/home/karma/.local/share/lxc/aufs01/delta0
こんな感じに aufs を使うコンテナのルートファイルシステムの定義がされています。
起動してみます。Plamo では cgmanager とか systemd-logind とかないので、起動前には自分で一般ユーザ権限の cgroup を作成して、現在のシェルの PID を登録してから起動しています。
$ lxc-start -n aufs01 -d $ lxc-ls -f NAME STATE IPV4 IPV6 GROUPS AUTOSTART ------------------------------------------------------ aufs01 RUNNING 10.0.100.179 - - NO ct01 STOPPED - - - NO
無事起動しましたね。
なぜ今 aufs ?
以上が動きと機能の紹介でした。でも、overlayfs がカーネルにマージされた今、なぜ aufs なのか? ってところですが...
色々なファイルシステムを扱う場合は特権が必要となります。例え User Namespace を使った Namespace 内の特権であっても、ファイルシステムをマウントできなかったりします。
User Namespace 内の特権ユーザがファイルシステムをマウントするには、カーネル内でファイルシステムのフラグに "FS_USERNS_MOUNT" というフラグが指定されている必要があります。(参考: overlayfs と LXC 非特権コンテナの snapshot によるクローン - TenForwardの日記)
このフラグ、4.1.1 カーネルで指定されているファイルシステムを調べてみると
$ find fs/ -type f | xargs grep FS_USERNS_MOUNT fs/devpts/inode.c: .fs_flags = FS_USERNS_MOUNT | FS_USERNS_DEV_MOUNT, fs/proc/root.c: .fs_flags = FS_USERNS_MOUNT, fs/ramfs/inode.c: .fs_flags = FS_USERNS_MOUNT, fs/sysfs/mount.c: .fs_flags = FS_USERNS_MOUNT, fs/namespace.c: if (!(type->fs_flags & FS_USERNS_MOUNT)) {
最後の (fs/namespace.c) は関係ないので devpts, proc, ramfs, sysfs だけです。この辺りはマウントできないとそもそも非特権のシステムコンテナが起動できなかったりするので指定されていて当然という気がしますね。つまり普通のファイルシステムはこれがそもそも指定されていないわけです。
overlayfs もこのフラグは指定されていません。なのに LXC で非特権 overlayfs がサポートされているのはなぜか? という話ですが、これは Ubuntu のカーネルにパッチが当たっているからです。パッチがあたっていないバニラカーネルだと当然これは失敗します。
$ lxc-clone -o ct01 -n overlay01 -s -B overlayfs clone failed
私の使っている 4.1.1 の overlayfs には特に何の変更も加えていないので、このように失敗します。
一方、aufs はカーネルにはマージされていないものの、最新の aufs が使える環境では素の aufs で User Namespace 内の特権ユーザが aufs をマウントできるわけです。この辺りからでしょうか。
まあ、パッチの量の大小の差はあるにせよ、overlayfs も aufs もバニラカーネルにパッチを当てないと非特権コンテナでは使えないわけで、なら aufs の非特権コンテナサポートを追加することで少しでも非特権コンテナのサポートする範囲が広がれば良いかなと思ってパッチを作りました。
あ、ちなみに Ubuntu のカーネルに当たっている aufs は古いバージョンなので、allow_userns は使えない模様です。Ubuntu は aufs 止めちゃうみたいですものね。
ま、LXC の overlayfs 周りとかは以前もパッチ送ったことがあってコードをよく知ってたので、非特権 aufs 対応はさほど難しくないって分かってたから作ったんですけどね。(^_^;)