今回からはLXCがコンテナイメージを置く領域に使えるいろいろなストレージバックエンドを利用し、LXCを便利に使う方法を紹介していきます。
LXCでいろいろなストレージバックエンドを利用する方法を紹介する前に、今後コンテナでの利用が増えそうな、3.18カーネルで新たに追加されたoverlayfsについて紹介しておきましょう。
タイトルは「Linuxカーネルのコンテナ機能」としていますが、これまでの機能と同様にoverlayfsもコンテナ専用として使う機能ではありません。名前空間やCgroup以上にコンテナ以外でさまざまなシーンで使えそうですね。
overlayfsとは
overlayfsはunion filesystemの実装の1つで、ディレクトリを重ね合わせて1つのディレクトリツリーが構成できます。
話題のDockerが持つ特長として、よくコンテナイメージの差分管理ができることが挙げられます。この差分管理を行うための手段のひとつとしてunion filesystemの実装であるaufsが用いられており、Dockerが急激に話題になり始めたころはaufsが良く紹介されていました。
Ubuntuなどの一部のディストリビューションではaufsが使えますが、aufsはカーネルソースに対するパッチという形で提供されているため一部のディストリビューションでしか使えません。一方、overlayfsは3.18カーネルでマージされましたので、今後はどのディストリビューションでも使えるようになっていき、それに伴いコンテナでの利用が増えていくでしょう。
Ubuntuでは3.18でカーネルにマージされる前の12.04 LTSや14.04 LTSの時点でパッチを適用してoverlayfsが使えるようになっていました。他にSUSEやopenSUSEでも以前からoverlayfsが利用できていたようです。
Ubuntuで対応していたためか、LXCでもかなり前からaufsだけでなくoverlayfsにも対応していました。
3.18カーネルでマージされたことを受けて、overlayfsが使える環境が増えてきました。
Dockerでは1.4.0でoverlayfsに対応しました。
さらに、Docker関連で良く話題になるCoreOSも最近ファイルシステムとしてbtrfsの代わりにoverlayfsを使用するという提案が行われ、執筆時点でのAlphaリリースである561.0.0でファイルシステムがext4+overlayfsへ変更されているようです。
overlayfsを使ってみる
union filesystemとか「重ね合わせ」と言われてもピンと来ない方もいらっしゃるでしょうから、ここで簡単にoverlayfsの動きを見ておきましょう。
まずはUbuntu 14.04 LTSでの使い方や動きを紹介して、overlayfsがどのようなファイルシステムであるかを理解してみましょう。Ubuntu 14.10でも同様の動きになるはずです。
overlayfsのマウント
まずは必要なディレクトリを作成します。重ねあわせの下層にするディレクトリ、上層にするディレクトリ、重ねあわせてマウントするためのディレクトリを作成します。
以上のように普通にディレクトリを作成しました。では早速マウントしてみましょう。
overlayfsのマウントにはオプションが必要です。
- lowerdir
- 重ねあわせの下層側のディレクトリ
- upperdir
- 重ねあわせの上層側のディレクトリ
何事もなくmount
コマンドが終了しました。成功したようですね。一応、マウントされているか確認してみましょう。
確かにマウントされています。では、このマウントしたディレクトリにファイルとディレクトリを作成してみましょう。
当たり前ですが普通にディレクトリとファイルができましたね。では、この時のlower
とupper
はどうなっているか確認してみましょう。
以上のようにlower
には何もありませんが、upper
には先ほど作成したファイルとディレクトリがあります。このように重ねあわせた上層であるディレクトリに変更が加えられていきます。
ここでさらにいろいろ試すために、一旦アンマウントします。
元から上層と下層にファイルが存在する状態でマウント
それではマウントされていない状態で下層であるlower
と上層であるupper
にファイルとディレクトリを置いてみましょう。
lower
にはファイルとディレクトリがひとつずつ、upper
には先ほどoverlayfsをマウントした状態で作ったファイルとディレクトリに加えて、今作ったファイルとディレクトリが存在する状態です。
それでは再度マウントしてみましょう。
先ほどマウントした状態で作ったファイル、ディレクトリと、マウントしない状態で作ったファイル、ディレクトリが全て見えますね。つまり下層と上層それぞれのディレクトリの内容が重ねあわせて見えるようになるわけです。これがunion filesystemです。
上層側への変更
それでは存在するファイルに変更を加えてみましょう。先ほどマウントした状態では上層にファイルができましたし、上層に存在するファイルに変更を加えた時の動きは容易に想像がつくのではないでしょうか。
上層にあるファイルに変更を加えると、そのまま上層にあるファイルが変更されています。上層にあるディレクトリに変更を加えても同様にそのまま上層が変更されます。
上層に存在するディレクトリ内にファイルを作ると、そのまま上層であるディレクトリupper/testdir_upper
以下にファイルが作成されました。
下層側への変更
それでは下層側に存在するファイルやディレクトリに変更を加えるとどうなるのでしょうか? 早速変更して下層側を確認してみましょう。
下層側に存在するファイルは元通りで変更は加えられていませんし、ディレクトリにファイルは存在しません。上層側を確認してみましょう。
先ほどまでは上層には存在しなかったtestdir_lower
とtestfile_lower
が存在していますね。ファイルの中身は先ほど書き込んだ中身になっていますし、出現したディレクトリ内には先ほど作成したファイルが存在します。
このことから、変更は常にupperdir
オプションで指定した上層側ディレクトリ以下になされることがわかります。ディレクトリやファイルが下層にも上層にも存在する場合は上層側のものが見えます。
ファイルやディレクトリの消去
ここまではファイルの作成や変更を見てきました。それではファイルやディレクトリを削除した場合はどうなるでしょう?
上層側に存在するファイルやディレクトリの場合はわかりやすいと思います。上層側に存在するファイルが消去されます。
先ほどまで上層側に存在していたtestdir_overlay
とtestfile_overlay
がマウントされたディレクトリでも上層側のディレクトリでも消去されていますね。
では、下層側のファイルやディレクトリを消去した場合はどうなるでしょう?
下層にも上層にも存在していたtestfile_lower
ファイルを消してみました。すると、下層側にはそのままの状態でファイルが残っているようですが、上層側では先ほどまでファイルとして存在していたtestfile_lower
がシンボリックリンクになっています。もう少し詳しく見てみると、
ご覧にように上層側ディレクトリ以下に存在したtestfile_lower
は"(overlay-whiteout)"へのシンボリックリンクになっています。つまり消去をした場合は上層側に変更が加えられ、「削除した」という印のために"(overlay-whiteout)"へのシンボリックリンクになります。下層に存在するファイルを上層で修正するために"whiteout(白の修正液)"というわけです。
ディレクトリも消去してみましょう。
ディレクトリでも同様になりましたね。
ところで、上記の例では表面的には見えていませんが、"(overlay-whiteout)"へのシンボリックリンクが張られた際、同時に拡張ファイル属性"trusted.overlay.whiteout"に"y"がセットされるようです。これも確認しておきましょう。
まとめると、
- 変更は常に
upperdir
オプションで指定した上層側ディレクトリ以下になされる
lowerdir
オプションで指定した下層側に存在するファイルに加えられた変更は上層側になされる。変更対象であるファイルやディレクトリが上層側にない場合は作成される
- 下層側に存在するファイルやディレクトリを削除すると"(overlay-whiteout)"へのシンボリックリンクが作成され、拡張ファイル属性"trusted.overlay.whiteout"が"y"に設定される
となります。
非常にシンプルでわかりやすい動きですね。
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カーネルをインストールした環境で試しています。
テスト用にファイルやディレクトリを作成したあと、Ubuntu 14.04 LTSと同様に"overlayfs"という名前でマウントしようとすると"unknown filesystemtype"でエラーになりました。タイプ名を"overlay"にすると無事マウントできていますね。
マウントしたディレクトリ内で下層側と上層側それぞれに存在するファイル、ディレクトリがきちんと見えているのがわかります。
それではマウントした状態で、下層側に存在するファイルに変更を加えてみましょう。
以上のようにUbuntu 14.04 LTSで実行したときと特に動きに変化はありませんね。
それではいよいよ、マウントした状態で下層側に存在するファイル、ディレクトリを削除してみましょう。
Ubuntu 14.04 LTSで実行したときは特別なシンボリックリンクだったのが、以上のようにノード番号0,0であるデバイスファイルになっているのがわかります。
拡張ファイル属性も見ておきましょう。
拡張属性はついていません。
opaque(不透明)ディレクトリ
overlayfsにはopaqueディレクトリという機能があります。これはどのバージョンのoverlayfsでも使えるはずです。
通常のoverlayfsでは上層側と下層側が透過的に重ねあわせられますが、上層側で「不透明」の指定がなされているディレクトリの内部では、上層側に存在するオブジェクトだけが見えて、下層側に存在するオブジェクトは見えません。
簡単に見てみましょう。ここでは3.18.3カーネルを入れたPlamo 5.3上で試しています。
以上のようにopaquetest
というディレクトリを上層側と下層側のディレクトリに作成します。その中にそれぞれファイルを作成します。
このままovarlay
ディレクトリにマウントすると、overlay/opaquetest
の下には2つのファイルが見えるはずです。
期待通り2つファイルが存在しますね。確認したら一度アンマウントします。
そして、上層側のディレクトリに拡張ファイル属性"trusted.overlay.opaque"として"y"を設定します。
拡張ファイル属性が設定されているのを確認してマウントします。
先ほどと違って、上層側であるディレクトリに存在するファイルしか見えなくなっていますね。このように下層側に存在する同名のディレクトリを無視する機能がこの「opaqueディレクトリ」機能です。
overlayfsを使う上での注意
現時点でoverlayfsを使う場合には注意すべき点があります。
3.18カーネルの時点では、overlayfsを使う場合のベースとなるファイルシステムはext4しか使えません。これは先に紹介した"whiteout"機能[1]がext4にしか実装されていないためです。
以下はほとんど当てはまる人はいないと思いますが、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つ置いています。
ここでlowerdir
オプションで3つのディレクトリを":"で連結してマウントしてみると、以下のようにoverlay
ディレクトリ以下にはtestfile_lower1
、testfile_lower2
、testfile_lower3
という3つのファイルが存在するように見えます。
lowerdir
のみを指定してupperdir
を指定しないでマウントできるようにもなるようで、この場合は読み込み専用でマウントされます。
この変更がいつの時点でカーネルにマージされるのかはわかりません。将来マージされて複数の下層ディレクトリが使えるようになるとコンテナの差分管理がさらに便利になりそうですね[2]。
まとめ
今回は、3.18カーネルで新たに追加され、今後コンテナでの利用が広がりそうなoverlayfsについて紹介しました。
コンテナ以外でも面白い使い方ができそうなファイルシステムです。皆さんも面白い使い方を考えてみてはいかがでしょうか?
次回以降はoverlayfsを含め、さまざまなストレージバックエンドを使ったLXCの便利な使い方について説明していきます。