LXC 1.1をのんびり紹介しているうちに、Ubuntu 16.04 LTSに向けて、次のバージョンのリリースが間近になってしまいました。うかうかしているとLXC 1.1の紹介が終わらないうちに、LXC 1.1がEOLになってしまいそうなので、慌てて今回の記事を書きました。
LXC 1.1の次は1.2かと思っていたら、linuxcontainers.org関連のプロダクトであるLXC、LXD、LXCFSすべてをバージョン2.0で揃えてリリースするようです。もうひとつ、cgmanagerというプロダクトがありましたが、こちらはLXCFSの進化に伴い不要となりましたので、今後は開発が終息していくようです。
1.1から2.0はそれほど大きな変更はなく、ライブラリについてもABIレベルでの互換性が維持されるようです。もちろん第29回と今回、LXC 1.1の新機能として紹介した機能はそのまま2.0でも使えるはずです。
今回はLXC 1.1の新機能や変更点のうち、設定ファイルに関係する部分を紹介します。
ディレクトリのinclude
LXCの設定ファイルでは、第11回で紹介したように、lxc.include
を用いて、他の設定ファイルをincludeできました。
LXC 1.1では、ファイルに加えて、lxc.include
にディレクトリを指定できるようになりました。
たとえば、LXCがインストールするcommon.conf
では、デフォルトで以下のような設定が書かれています。
ここに設定したい内容を書いたファイルを置けば、デフォルトの設定ファイルを変更せずに全コンテナで有効にしたい設定ができます。
UbuntuにLXC 1.1をインストールすると、依存関係でLXCFSがインストールされます。その際、LXCコンテナがLXCFSを使うよう、フックを設定するためにファイルが置かれます。
コンテナがinitとして実行するプログラム
コンテナを起動する際に使うlxc-start
コマンドで、コンテナ名だけを指定してコンテナを起動すると、システムコンテナが起動しました。これはlxc-start
は、デフォルトでコンテナ内の/sbin/init
をコマンドとして実行するためでした。
一方lxc-start
コマンドを実行する際に、コマンドを指定してアプリケーションコンテナを起動できました。
LXC 1.1からは、lxc-start
が実行するコマンドが設定で指定できるようになりました。上記の例と同じ指定を設定ファイルで行う場合は、コンテナの設定ファイルで以下のように設定します。
lxc-start
を実行すると、以下のように指定通りにbashが実行できていますね。
柔軟なlxc.cap.keepの設定
第12回で紹介したlxc.cap.keep
は、コンテナで保持したいケーパビリティを指定するための設定項目でした。ここで指定したケーパビリティ以外はすべて削除されます。
この設定にnone
というキーワードを指定できるようになりました。
LXCは設定ファイルを順に読んでいきますので、lxc.cap.keep
にnone
を設定すると、それまでに許可されているケーパビリティを一旦すべて削除できます。その後に許可したいケーパビリティをlxc.cap.keep
に指定すれば、コンテナに許可されているケーパビリティを一旦すべて削除したあとで、許可したいケーパビリティを設定できます。
lxc.include
などを使って、全コンテナで共通の設定がなされている場合に、特定のコンテナだけではケーパビリティの設定を変えたい場合に便利ですね。
以上の設定でCAP_NET_ADMIN
のみが許可されたコンテナになります。lxc.cap.keep
の最後にnone
が設定されると、すべてのケーパビリティが削除された状態になります。
これまでは紹介していませんでしたが、LXCではケーパビリティ、cgroup、マウント、UID/GIDのマッピングといった複数の値を設定できる項目で空の値を設定すると、その時点でなされている設定値をクリアできます。
ケーパビリティを削除する場合のlxc.cap.drop
では、以上のように設定すると、1行目で設定されている削除したい4つのケーパビリティが、2行目ですべてクリアされます。lxc.cap.drop
では、この空の値を設定する方法ですべてのケーパビリティを許可できました。
この設定をクリアする方法はlxc.cap.keep
でも使えます。しかし、lxc.cap.keep
の設定をクリアすると、すべてのケーパビリティが許可されてしまいます。つまり、LXC 1.0では、すべてのケーパビリティを削除するという設定を書くのは大変でした。
lxc.cap.keep
にnone
が指定できるようになり、一旦すべてのケーパビリティを削除してから、許可したいケーパビリティを簡単に設定できるようになりました。
コンテナのinitへ渡す環境変数
LXC 1.1では、lxc.environment
という設定が追加され、コンテナのinitに任意の環境変数を渡せるようになりました。
たとえば、以上のようにAPP_ENV
という環境変数にproduction
という値を設定するように指示してみましょう。そして、コンテナを起動後にinitに設定されている環境変数を表示させてみます。
以上のように、lxc.environment
で設定したAPP_ENV=production
という環境変数が設定されています。
このlxc.environment
を使うと、コンテナの起動時に環境変数を参照して何らかの処理を行えます。
ちなみに、上記の例のcontainer
とcontainer_ttys
はLXCが内部的に設定している環境変数です。
LXC 1.0では、内部的には環境変数container
にlxc
という値が設定されているだけでした。Ubuntuの起動スクリプトでは、この環境変数を参照して、コンテナ内で実行されているかどうかを判定している部分があります。
container_ttys
という環境変数はLXC 1.1になってから設定されるようになった変数で、systemdが要求するようです。この環境変数については、systemdのContainer Interfaceという文書に記載があります。
lxc.pivotdirの無効化
LXC 1.0では、pivot_rootシステムコールを使ってコンテナのルートファイルシステムを設定する際、lxc.pivotdir
という設定の値を使用していました。
LXC 1.1では、pivot_rootを行う部分のコードがシンプルに書き換えられました。その際にlxc.pivotdir
の値は使われなくなりました。
lxc.pivotdir
を設定してもエラーにはなりませんが、設定は無視され、警告が出ます。
lxc.autodev処理の変更
lxc.autodev
は、コンテナの起動時に、/dev
以下に最小限必要なデバイスファイルを作成するための設定です。
LXC 1.0では、lxc.autodev
はデフォルトで0(無効)になっていました。LXC 1.0で、この機能がどのような処理を行っていたのか、筆者はよくわかっていませんが、ホストの/dev/.lxc
以下にコンテナ用のディレクトリを作成し、コンテナの/dev
にバインドマウントするというような処理を行っていました。
LXC 1.1では、このlxc.autodev
の処理が書き直され、コンテナの/dev
はtmpfsでマウントされ、LXCが最小限のデバイスを作成しています。コードも非常にシンプルでわかりやすくなりました。
LXC 1.0では、非特権コンテナでlxc.autodev
を使用すると問題が起こっていたようですが、これがLXC 1.1の実装で解消されたため、lxc.autodev
はデフォルトでは1(有効)になりました。
これに伴い、いくつかのテンプレートファイルで、lxc.autodev
が1で動作するように修正が行われています。
lxc.kmsgのデフォルト値の変更
lxc.kmsg
は、コンテナの/dev/kmsg
を/dev/console
へのシンボリックリンクとするための設定です。
1.0では、lxc.kmsg
のデフォルト値は1(有効)でしたが、1.1で0(無効)がデフォルトになりました。コンテナのinitがUpstartの場合に、boot時のメッセージを見るために、この値を1にしていたようです。
このようなリンクは有害であると指摘されていたようですし、Ubuntuでinitがsystemdへ移行するのに伴い、デフォルト値が変更されました。
lxc.mount.auto の sys の変更
lxc.mount.auto
は第11回で説明した通り、コンテナ内で、proc、sysfs、cgroupの各ファイルシステムを自動的にマウントするための設定でした。
それぞれのファイルシステムをマウントする際のオプションが指定でき、より安全にコンテナ内でこれらのファイルシステムを利用できるようにマウントできました。
オプションは読み込み専用のro
、読み書き可能のrw
、書き込みさせたくないファイルは読み込み専用で、それ以外は書き込みできる形でマウントするmixed
の中から選択できました。
たとえばlxc.mount.auto = proc:mixed
という指定は、procファイルシステムを読み書き可能でマウントしますが、/proc/sys
や/proc/sysrq-trigger
は読み込み専用でマウントしました。
1.0ではこの3つのファイルシステムのうち、sysfsをマウントする指定であるsys
のみ、mixed
オプションは指定できませんでした。
1.1で、sys
にmixed
というオプションが新設されました。mixed
を指定すると、sysfsを/sys
以下に読み込み専用でマウントする一方で、/sys/devices/virtual/net/
以下は書き込み可能でマウントします。これによりネットワークインターフェースの設定を変更できます。
sys
でオプションを指定しない場合のデフォルト値は、1.0ではro
でしたが、1.1ではmixed
となります。
sys:mixed
またはsys
sys
を読み込み専用でマウントします。ただし、/sys/devices/virtual/net/
は読み書き可能でマウントします。
sys:ro
/sys
を読み込み専用でマウントします。
sys:rw
/sys
を読み書き可能でマウントします。
1.0では、いくつかのディストリビューション用のデフォルトの設定ファイルでlxc.mount.auto
が、それぞれのディストリビューションに適した値で指定されていました。1.1では、全ディストリビューション共通の設定ファイル内で、lxc.mount.auto
の値がcgroup:mixed proc:mixed sys:mixed
と指定されるようになりました。
まとめ
今回はLXC 1.1の新機能や変更点のうち、設定ファイルに関係する部分を紹介しました。
第29回と今回紹介した機能は、どちらかというと細かい改良ばかりです。
これらの細かい改良の中には、コンテナでのsystemdのサポートを考慮してなされた変更があります。その積み重ねで、LXC 1.1ではコンテナのinitとしてsystemdがサポートされるようになりました。
LXC 1.1はこのような細かい改良ばかりでなく、まだ紹介していないCRIUを使ったチェックポイント・リストアの機能が追加されています。この機能はLXC 1.1の新機能として紹介するつもりでしたが、間に合いませんでしたので、今後LXC 2.0と一緒に紹介していくつもりです。