今回は前回紹介できなかったコマンドの紹介を続けます。その後、Ubuntu 14.04 LTSでcgroupを管理するために導入されたcgmanagerについて少し紹介します。
アプリケーションコンテナ
lxc-startを使ったアプリケーションコンテナの起動
第8回でlxc-start
コマンドの使い方を紹介しました。その際に紹介したのはシステムコンテナを起動する方法でした。lxc-start
は特に指定しなければコンテナイメージ内の/sbin/init
を実行します。
ここでコマンドを指定するとlxc-start
はアプリケーションコンテナとして指定したコマンドを実行します。
/bin/bash
を指定すると警告は出るものの、コンテナct01
として/bin/bash
が実行されています。
lxc-start
でアプリケーションコンテナを実行するときには注意が必要です。指定したコマンドがすぐに終了して制御が戻ってきてしまうような場合、lxc-start
はコンテナのinit
に相当するコンテナ内のPIDが1のプロセスがすぐに終了したとみなしてコンテナが起動しません。
以下の例を見てください。これはCentOSコンテナにApacheをインストールして、アプリケーションコンテナとして実行しようとしています。
lxc-start
の実行はエラー出力もなく成功しているようです。しかし、確認してみると停止しています。ログを見てみましょう。
指定した/usr/sbin/httpd
の実行は行われ、PIDが1504として起動していますが、直後にexitしてしまっています。
このような場合は指定したコマンドが終了しなければ良いので、以下のように/sbin/sbin/httpd
をフォアグラウンドで起動すれば良いのです。
このようにきちんと実行されます。
lxc-executeによるアプリケーションコンテナの実行
以上のようにフォアグラウンドで起動させるためにちょっと工夫が必要なコマンドをコンテナとして実行する際に便利な場合があるコマンドがlxc-execute
です。「場合がある」と微妙な表現になっている理由は後で説明します。
lxc-execute
はlxc-start
と同様にコンテナを起動するためのコマンドです。lxc-start
との違いは、lxc-execute
はアプリケーションコンテナを起動させるためのコマンドであるという点です。
lxc-execute
は内部的な処理はlxc-start
と同じです。違いはコンテナのinitとしてLXCが提供する簡易的なinitプログラムであるlxc.init
を起動し、その子プロセスとして指定したコマンドを実行するところです。
これを確認してみましょう。以下ではUbuntuコンテナにApacheをインストールして実行しています。
ご覧のように通常通りApacheの起動を行ってもコンテナが終了することなく起動した状態になっています。
このlxc-execute
コマンドをpstree
コマンドで見てみましょう。
ご覧のようにinit.lxc
というプログラムを挟んでapache2
が実行されています。
このinit.lxc
はlxc-execute
で指定したコマンドの終了を監視し、コマンドが終了すると自身も終了し、コンテナを終了させます。また、lxc-stop
から送られてくるシグナルを子プロセスに送る役割も果たします。
ここまでご覧になると、アプリケーションコンテナを起動するにはlxc-execute
が便利なような気がします。しかし実はそうでもありません。LXC 1.0系列でlxc-execute
を使うには準備が必要です。
前述の例はUbuntu 14.04 LTSのコンテナを使っています。このコンテナに"apache2"パッケージだけでなく、以下のように"lxc"パッケージもインストールしました。これはinit.lxc
をインストールするためです。
コンテナ内で実行するコマンドはコンテナイメージ内に存在する必要があります。lxc-execute
が内部的に実行するinit.lxc
であってもこれは同じです。これを手っ取り早く準備するためにinit.lxc
が含まれる"lxc"パッケージをインストールしたのです。
ホストOSにインストールした"lxc"パッケージにもinit.lxc
コマンドが含まれますので、これをコンテナ内にコピーするかバインドマウントすれば良さそうに思えますが、そう簡単にはいきません。LXC 1.0系列のinit.lxc
はダイナミックリンクされているため、依存するライブラリを全て調べてコンテナ内に準備する必要があります。
そこで"lxc"パッケージをインストールしたわけです。コンテナ内で"lxc"パッケージをインストールすれば依存関係で必要なパッケージがインストールされるので楽です。
しかし、この方法が使えたのは、ここで使った例ではコンテナの環境がUbuntu14.04 LTSだったからです。これが別のディストリビューションだとそもそもLXCのパッケージがすぐに利用可能かどうかわかりません。
環境が準備されてしまえばlxc-execute
を使うのは簡単ですが、それまでの手間を考えると少し微妙な気がしますね。ここで紹介した例のように、init.lxc
を使うためだけに、使わない"lxc"パッケージの他のコマンドや依存ライブラリを大量にインストールするのは無駄です。
なお、LXC 1.1からは、lxc-execute
が使うinit.lxc
はスタティックリンクされ、lxc-execute
を実行した時点でホストOSのinit.lxc
がコンテナ内に自動でバインドマウントされるようになる予定ですので、簡単に使えるようになりそうです。
LXCのシステム設定 ~ lxc-config
lxc-config
はLXCのシステム設定を確認するためのコマンドです。「システム設定」とは第8回で紹介した「システム設定ファイル」で設定する項目です。コンテナのデフォルト設定ファイルのパスやコンテナの保存場所のパスなどの設定でしたね。
まずはlxc-config
で確認できる値の一覧を表示してみましょう。
コンテナのデフォルト設定ファイルとコンテナの保存場所を表示させてみましょう。一覧で出てきた設定を指定するだけです。
コンテナの一時停止、再開 ~ lxc-freeze,lxc-unfreeze
起動中のコンテナを一時停止させる場合はlxc-freeze
を使います。
一時停止中のコンテナを再開させる場合はlxc-unfreeze
を使います。
コンテナの状態のモニタリング ~ lxc-monitor
lxc-monitor
はコンテナの状態をモニタリングします。実行すると、コンテナの状態が変わるたびに状態の表示が行います。
コンテナの状態はこれまでもlxc-ls
とlxc-info
の出力として紹介しました。しかし、これまでどのような状態があるのかは説明していませんでしたので、ここで紹介しておきましょう。
表1 コンテナの状態一覧
状態 | 説明 |
STOPPED |
停止 |
STARTING |
起動途中 |
RUNNING |
実行中 |
STOPPING |
停止途中 |
ABORTING |
コンテナの初期化に失敗 |
FREEZING |
一時停止途中 |
FROZEN |
一時停止 |
THAWED |
再開 |
コンテナct01
の状態をモニタリングしてみましょう。
これはlxc-monitor
を実行した後、別の端末で以下のようなコマンドを順に実行した時の出力です。
コンテナ名を指定しないで実行すると、コンテナの保存場所に存在する全てのコンテナをモニタリングします。
指定したコンテナの状態への待機 ~ lxc-wait
lxc-wait
はコンテナが指定した状態になるのを待って終了します。コンテナの状態に応じて何かを行うようなスクリプト中で使えそうですね。
と実行しておいて、別の端末で
とコンテナを停止させるとlxc-wait
の実行は終了します。
Ubuntu 14.04 LTSのcgroup管理
一通りコンテナの管理に必要なコマンドの紹介が済んだ所で、lxc-cgroupのところで触れたUbuntu 14.04 LTSでのcgroupの管理について簡単に紹介しておきます。
Ubuntu 12.04 LTSでは、"lxc"パッケージをインストールすると、依存関係で"cgroup-lite"というパッケージが同時にインストールされ、ホストOSの起動時にサブシステムごとのディレクトリを作成してマウントするシェルスクリプトが実行され、cgroupfsがマウントされていました。
起動後、cgroupfsがマウントされている様子は以上のようになっていました。
ところがUbuntu 14.04 LTSでは"cgroup-lite"パッケージはインストールされません。
最近の議論では、cgroupは将来的にはcgroupfsを直接触って管理はせず、cgroupを管理するエージェントを介して管理するという流れになっています。このことは第5回の「cgroupの今後」で少し紹介しました。
この流れに従い、Ubuntuでもcgmanagerというソフトウェアが開発されました。Ubuntu 14.04 LTSでは、cgroup-liteの代わりにこのcgmanagerがLXCと同時にインストールされます。
このためUbuntu 14.04 LTS環境では/sys/fs/cgroup
ディレクトリは以下のようにすっきりしています。
cgmanager
というディレクトリが存在し、その下にはソケットが存在するだけです。
この状態でもLXCを使ってコンテナは起動し、cgroupを使ったリソースが制限できます。cgroupはcgroupfsをマウントしなければ利用できません。どこで管理されているのでしょう?
実はcgmanagerは起動時に新たなマウント名前空間を作成し、その名前空間内でcgroupfsをマウントします。このため、ホストOSが属する名前空間からはcgmanagerがマウントしたcgroupfsが見えないのです。
util-linux 2.23以降に含まれるnsenter
というコマンドを使って確認してみましょう。nsenter
は任意の名前空間上でコマンドが実行できるコマンドです。実行中のcgmanager
デーモンが属するマウント名前空間を指定してコマンドを実行してみます[1]。
ご覧のように実行中のcgmanager
が属するマウント名前空間では/run/cgmanager/fs
以下にcgroupfsがマウントされているのがわかります。
cgmanagerはホストOSの属する名前空間にあった/sys/fs/cgroup/cgmanager/sock
経由でDBusのメッセージを受け付けて別の名前空間でマウントされたcgroupfsの操作を行います。
なお、LXC自体はcgmanager経由でも、従来通りのcgroupfsがホストOSの名前空間でマウントされていて直接cgroupfsを触る環境でもcgroupの管理が可能なように作られています。
まとめ
今回はLXCに付属するコマンドのうち、これまで紹介していなかったものを紹介し、その後でUbuntu 14.04 LTSでLXCを使う際にcgroupを管理する役割を果たすcgmanagerを紹介しました。
次回からはLXCの設定について解説していく予定です。
第4回 コンテナ型仮想化の情報交換会@東京
筆者が主催している「コンテナ型仮想化の情報交換会」の第4回目を、9月6日(土)にニフティ株式会社に会場をお借りして開催してきました。
この勉強会の資料や動画を以下にまとめました。LinuxやLXCに限らないいろいろなコンテナ関連の技術のお話や活用事例のお話が聞けて非常に勉強になりました。興味のある方はぜひご覧ください。
- 第4回 コンテナ型仮想化の情報交換会@東京