kernel に入るぞ、と言われつつ入ってない overlayfs。いつですかね?
なかなか凝ったことを試す時間が取れない今日このごろ、非常に薄い内容のエントリです。
(2014-05-15 追記) LXC では、ファイルシステムの機能を利用した snapshot による clone をサポートしています。しかし、非特権コンテナで clone を作成する場合、どうしても通常の rsync による clone になってしまいます。しかし、Ubuntu のカーネルだと overlayfs が利用可能で、非特権コンテナの場合でも使用可能です。一般ユーザが overlayfs の操作が可能ということでなく、User Namespace 内の root の権限で overlayfs のマウントが可能になっているためです。(追記終わり)
(2014-10-08 追記)
今はオプションで "workdir" を指定する必要があるようです (いつから?)。以下は 3.17 (+patch) で確認。→ overlayfs.v22 (= 3.15) 以降のようですね。つまり現在の lxc-clone は 3.14kernel+v21 パッチまでの上でしか動きません。
# mkdir 1 2 3 4 # touch 1/lower # touch 2/upper # mount -t overlayfs -o lowerdir=1,upperdir=2,workdir=3 overlayfs 4 # touch 3/overlay # umount 4 # find . . ./1 ./1/lower ./2 ./2/upper ./2/overlay ./3 ./3/work ./4
overlayfs
overlayfs を使ってみました。ドキュメント全く読んでないので (ヲイ) わかりませんが、カーネルが対応すれば特に何もすることはなさそうです。以下で試しました。
パッチはこの辺りをご参照。
- GitHub - adilinden/overlayfs-patches: Created patches from the overlayfs git repo at http://git.kernel.org/cgit/linux/kernel/git/mszeredi/vfs.git/
- http://adis.ca/post/overlayfs-patch/
早速試してみます。
- 重ねあわせをするディレクトリを作り、確認用にファイルを作っておきます。
# mkdir 1 2 3
# touch 1/LOW
# touch 2/HIGH - マウントします。マウントされています。
# mount -t overlayfs -o lowerdir=1,upperdir=2 overlayfs 3
# mount -l | grep overlayfs
overlayfs on /root/3 type overlayfs (rw,lowerdir=1,upperdir=2) - ファイルを作ってみます。元々あったファイルに加えて、新しく作ったファイルも見えます。
# cd 3
touch OVERLAY
# ls
HIGH LOW OVERLAY - umount します。
# umount 3
- 各ディレクトリを確認してみます。
# ls 1
LOW
# ls 2
HIGH OVERLAY
# ls 3
upperdir で指定したディレクトリが更新されていくわけですね。lowerdir で指定したディレクトリが更新されると、マウントされた overlayfs のディレクトリも更新されたようにみえます。
# cd 3 # ls HIGH LOW OVERLAY # cd ../1 # ls LOW # touch LOW2 # ls LOW LOW2 # cd ../3 # ls HIGH LOW LOW2 OVERLAY
これだけ。
Ubuntu 14.04 の非特権コンテナの overlayfs による clone
以下は一般ユーザで実行しています。非特権コンテナの作り方は Ubuntu 14.04 LTS での非特権コンテナ - TenForwardの日記 辺りをどうぞ。
"ct01" というコンテナを "ct02" という名前のコンテナに overlayfs を使って snapshot clone してみましょう。ちなみに aufs だとこんな風に怒られます。
$ lxc-clone -o ct01 -n ct02 -s -B aufs lxc_container: Unsupported snapshot type for unprivileged users lxc_container: Error copying storage clone failed
overlayfs だとこんな風にあっさり成功。
$ lxc-ls ct01 $ lxc-clone -o ct01 -n ct02 -s -B overlayfs Created container ct02 as snapshot of ct01 $ lxc-ls ct01 ct02
ct02 のディレクトリを覗いてみると
$ cd .local/share/lxc/ct02 $ ls -F config delta0/ lxc_rdepends rootfs/ $ grep lxc.rootfs config lxc.rootfs = overlayfs:/home/karma/.local/share/lxc/ct01/rootfs:/home/karma/.local/share/lxc/ct02/delta0
つまり
- ct01 の rootfs を lowerdir に
- ct02 の delta0 ディレクトリを upperdir に
して、ct02 の rootfs ディレクトリに overlayfs でマウントするというわけですね。
$ lxc-start -n ct02 -d $ lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ------------------------------------------ ct01 STOPPED - - NO ct02 RUNNING 10.0.3.178 - NO
ct02 に ubuntu ユーザでログインして $HOME/TEST ファイルを作ると、
$ cd ~/.local/share/lxc/ct02/delta0/home/ubuntu $ ls TEST
と delta0 ディレクトリにファイルが作られていきます。
一つ注意が必要なのは ct01 のファイルが更新されると ct02 のファイルも更新されてしまうので、なんか良くわからない状態になってしまいがちですね。普通に filesystem レベルでサポートされている snapshot を使った clone とはちょっと違うので、使い方も変えていく必要はあります。そういう場合は 1.0 ではサポートされない気がしますが、btrfs を使えばいけるようになりそうです→btrfs: support unprivileged create and clone · lxc/lxc@2659c7c · GitHub
Plamo 5.2 の非特権コンテナの clone
私にとってはここからが本題。
同じように Plamo でも出来るはず、ってことで試してみましたが...
$ lxc-clone -o ct01 -n ct02 -s -B overlayfs lxc_container: Operation not permitted - overlayfs: error mounting /home/karma/.local/share/lxc/ct01/rootfs onto /usr/lib64/lxc options upperdir=/home/karma/.local/share/lxc/ct02/delta0,lowerdir=/home/karma/.local/share/lxc/ct01/rootfs clone failed
(;_;) Why?? 偉い人教えて。(続く)
(2014-05-15 追記)
わかりました。overlayfs のパッチで User Namespace 内の root が overlayfs をマウント出来るようなフラグを与えました(Ubuntu のカーネルはこれが当たってるはず)。具体的には fs/overlayfs/super.c 内の ovl_fs_type に FS_USERNS_MOUNT ってのをフラグで追加しました。
static struct file_system_type ovl_fs_type = { .owner = THIS_MODULE, .name = "overlayfs", .mount = ovl_mount, .kill_sb = kill_anon_super, .fs_flags = FS_USERNS_MOUNT, };
FS_USERNS_MOUNT は include/linux/fs.h に定義されています。
$ grep FS_USERNS_MOUNT include/linux/fs.h #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
これで Plamo でも
$ lxc-clone -o ct01 -n ct02 -s -B overlayfs
Created container ct02 as snapshot of ct01
$ for c in /sys/fs/cgroup/*; do echo $$ > $c/karma/tasks; done
$ lxc-start -n ct02 -d$ lxc-ls --fancy
NAME STATE IPV4 IPV6 AUTOSTART
--------------------------------------------
ct01 STOPPED - - NO
ct02 RUNNING 10.0.100.253 - NO