LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術

第18回 Linuxカーネルのコンテナ機能 [7] ─ overlayfs

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

3.18カーネルのoverlayfs

さて,Ubuntu 14.04 LTSを使ってoverlayfsの動きを見てみました。Ubuntu14.04 LTSを使った理由は,現時点でoverlayfsを試す環境として一番お手軽ではないかと考えたからです。

しかし,実はUbuntu 14.04 LTSで使えるoverlayfsと,3.18カーネルで導入されたoverlayfsでは仕様が異なるため,3.18 カーネルで前述の例を実行してもエラーになります。また,下層側に存在するファイルやディレクトリを変更した際の動きも変更されています。

使い方として現れる変更点は以下です。

ファイルシステムのタイプ名が変更された理由はコミットログに書かれています。UbuntuやSUSEでは3.18より前のカーネルでパッチを適用してoverlayfsをサポートしてきました。

タイプ名を変更することにより,互換性のためにこの古い仕様のoverlayfsを維持する一方で,新しい仕様のoverlayfsも使えるようにできます。

また,このように複数の仕様のoverlayfsが存在する場合,プログラムでどちらのバージョンのoverlayfsが実行されているかを判定する必要もでてきます。

タイプ名を変更しておくと,/proc/filesystems内で"overlay"という行が存在するか,"overlayfs"という行が存在するかで判定できるようになります。LXCでも今後この方法でマウントの際のオプションを判定する変更がなされる予定です。

それではUbuntu 14.04 LTSで試したのと同様の操作を3.18カーネルで行って変化を見てみましょう。

ここではPlamo Linux 5.3に3.18.3カーネルをインストールした環境で試しています。

# mkdir lower upper overlay work (workdir用にworkという名前でディレクトリを作成)
# touch lower/testfile_lower upper/testfile_upper (テスト用ファイルの作成)
# mkdir lower/testdir_lower upper/testdir_upper   (テスト用ディレクトリの作成)
# mount -t overlayfs -o lowerdir=lower,upperdir=upper,workdir=work overlay overlay
("overlayfs"というタイプ名でマウント)
mount: unknown filesystem type 'overlayfs' ("overlayfs"というタイプ名だとエラー)
# mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work overlay overlay
("overlay"というタイプ名でマウント)
# mount -l | grep overlay (マウントの確認)
/root/overlay_test/overlay on /root/overlay_test/overlay type overlay (rw,lowerdir=lower,upperdir=upper,workdir=work)
# ls -F overlay/  (マウントしたディレクトリの確認)
testdir_lower/  testdir_upper/  testfile_lower  testfile_upper

テスト用にファイルやディレクトリを作成したあと,Ubuntu 14.04 LTSと同様に"overlayfs"という名前でマウントしようとすると"unknown filesystemtype"でエラーになりました。タイプ名を"overlay"にすると無事マウントできていますね。

マウントしたディレクトリ内で下層側と上層側それぞれに存在するファイル,ディレクトリがきちんと見えているのがわかります。

それではマウントした状態で,下層側に存在するファイルに変更を加えてみましょう。

# echo "test" > overlay/testfile_lower(下層側ファイルを変更)
# touch overlay/testdir_lower/testfile(下層側ディレクトリにファイルを作成)
# cat lower/testfile_lower(下層側ファイルの確認)
# cat upper/testfile_lower(上層側にできたファイルの確認)
test
# ls lower/testdir_lower/(下層側ディレクトリの確認)
# ls upper/testdir_lower/(上層側にできたディレクトリの確認)
testfile

以上のようにUbuntu 14.04 LTSで実行したときと特に動きに変化はありませんね。

それではいよいよ,マウントした状態で下層側に存在するファイル,ディレクトリを削除してみましょう。

# rm overlay/testfile_lower (下層側ファイルの削除)
# rm -rf overlay/testdir_lower/ (下層側ディレクトリの削除)
# ls -F overlay/
testdir_upper/  testfile_upper (消去された)
# ls -lF upper/*_lower (上層側ディレクトリの確認)
c--------- 1 root root 0, 0  1月 20日  19:26 upper/testdir_lower
c--------- 1 root root 0, 0  1月 20日  19:26 upper/testfile_lower

Ubuntu 14.04 LTSで実行したときは特別なシンボリックリンクだったのが,以上のようにノード番号0,0であるデバイスファイルになっているのがわかります。

拡張ファイル属性も見ておきましょう。

# getfattr -n trusted.overlay.whiteout upper/testdir_lower 
upper/testdir_lower: trusted.overlay.whiteout: No such attribute
# getfattr -n trusted.overlay.whiteout upper/testdir_lower 
upper/testdir_lower: trusted.overlay.whiteout: No such attribute

拡張属性はついていません。

opaque(不透明)ディレクトリ

overlayfsにはopaqueディレクトリという機能があります。これはどのバージョンのoverlayfsでも使えるはずです。

通常のoverlayfsでは上層側と下層側が透過的に重ねあわせられますが,上層側で「不透明」の指定がなされているディレクトリの内部では,上層側に存在するオブジェクトだけが見えて,下層側に存在するオブジェクトは見えません。

簡単に見てみましょう。ここでは3.18.3カーネルを入れたPlamo 5.3上で試しています。

# mkdir lower upper overlay work
# mkdir lower/opaquetest upper/opaquetest  (上層,下層側ディレクトリにディレクトリを作成)
# touch lower/opaquetest/testfile_lower upper/opaquetest/testfile_upper
(作成したディレクトリにファイルを作成)

以上のようにopaquetestというディレクトリを上層側と下層側のディレクトリに作成します。その中にそれぞれファイルを作成します。

このままovarlayディレクトリにマウントすると,overlay/opaquetestの下には2つのファイルが見えるはずです。

# mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work overlay overlay
# ls overlay/opaquetest/  (マウントしたディレクトリの確認)
testfile_lower  testfile_upper
# umount overlay

期待通り2つファイルが存在しますね。確認したら一度アンマウントします。

そして,上層側のディレクトリに拡張ファイル属性"trusted.overlay.opaque"として"y"を設定します。

# setfattr -n "trusted.overlay.opaque" -v "y" upper/opaquetest/
# getfattr -n "trusted.overlay.opaque"  upper/opaquetest/
# file: upper/opaquetest/
trusted.overlay.opaque="y"

#

拡張ファイル属性が設定されているのを確認してマウントします。

# mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work overlay overlay
# ls overlay/opaquetest/
testfile_upper (上層側に存在するファイルしか見えない)

先ほどと違って,上層側であるディレクトリに存在するファイルしか見えなくなっていますね。このように下層側に存在する同名のディレクトリを無視する機能がこの「opaqueディレクトリ」機能です。

overlayfsを使う上での注意

現時点でoverlayfsを使う場合には注意すべき点があります。

3.18カーネルの時点では,overlayfsを使う場合のベースとなるファイルシステムはext4しか使えません。これは先に紹介した"whiteout"機能※1がext4にしか実装されていないためです。

※1)
"whiteout"機能が必要なのはupperdirで,workdirはupperdirと同じファイルシステムに存在する必要がありますので,厳密にいうとupperdirとworkdirがext4上にある必要があることになります。また,4.1カーネルでXFSにも"whiteout"機能が実装されています。

以下はほとんど当てはまる人はいないと思いますが,3.14~3.17のカーネルでoverlayfsのリポジトリから取得したソースを使って独自にoverlayfsを使えるカーネルを構築して使ってる場合は,先に紹介した/proc/filesystemsを使ったoverlayfsの仕様の判定ができませんので注意してください。この間のoverlayfsはタイプ名が"overlayfs"である一方,仕様は新しいためです。Plamo 5.3の現時点のカーネルは3.17.6でoverlayfsを使えるようにしているのでこれに当てはまります。

overlayfsの将来

overlayfsは今後も仕様が変わっていくようです。

overlayfsのリポジトリにある"overlayfs-next"というブランチを見ていると,下層側のディレクトリを複数重ねあわせる変更が行われています。

筆者の手元で3.18.3カーネルにこのoverlayfs-nextブランチのパッチを適用して簡単に試してみました。

下層用にディレクトリを3つ作成し,上層用とwork用にディレクトリを1つずつ作成しました。lower1~3のディレクトリにはそれぞれファイルを1つ置いています。

# ls -F
lower1/  lower2/  lower3/  overlay/  upper/  work/
# ls -F lower?/*
lower1/testfile_lower1  lower2/testfile_lower2  lower3/testfile_lower3

ここでlowerdirオプションで3つのディレクトリを":"で連結してマウントしてみると,以下のようにoverlayディレクトリ以下にはtestfile_lower1testfile_lower2testfile_lower3という3つのファイルが存在するように見えます。

# mount -t overlay -o lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work overlay overlay
# mount -l | grep overlay (マウントの確認)
/root/overlay/overlay on /root/overlay/overlay type overlay (rw,lowerdir=lower1:lower2:lower3,upperdir=upper,workdir=work)
# ls -F overlay (マウントしたディレクトリの確認)
testfile_lower1  testfile_lower2  testfile_lower3

lowerdirのみを指定してupperdirを指定しないでマウントできるようにもなるようで,この場合は読み込み専用でマウントされます。

この変更がいつの時点でカーネルにマージされるのかはわかりません。将来マージされて複数の下層ディレクトリが使えるようになるとコンテナの差分管理がさらに便利になりそうですね※2⁠。

※2)
複数のlowerdirはカーネル4.0でサポートされるようになりました。

まとめ

今回は,3.18カーネルで新たに追加され,今後コンテナでの利用が広がりそうなoverlayfsについて紹介しました。

コンテナ以外でも面白い使い方ができそうなファイルシステムです。皆さんも面白い使い方を考えてみてはいかがでしょうか?

次回以降はoverlayfsを含め,さまざまなストレージバックエンドを使ったLXCの便利な使い方について説明していきます。

著者プロフィール

加藤泰文(かとうやすふみ)

2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。

Plamo Linuxメンテナ

Twitter:@ten_forward
技術系のブログ:http://tenforward.hatenablog.com/