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

第10回 LXCの基本操作 [3]

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

コンテナの状態のモニタリング ~ lxc-monitor

lxc-monitorはコンテナの状態をモニタリングします。実行すると,コンテナの状態が変わるたびに状態の表示が行います。

コンテナの状態はこれまでもlxc-lslxc-infoの出力として紹介しました。しかし,これまでどのような状態があるのかは説明していませんでしたので,ここで紹介しておきましょう。

表1 コンテナの状態一覧

状態説明
STOPPED 停止
STARTING 起動途中
RUNNING 実行中
STOPPING 停止途中
ABORTING コンテナの初期化に失敗
FREEZING 一時停止途中
FROZEN 一時停止
THAWED 再開

図1 状態遷移図

図1 状態遷移図

コンテナct01の状態をモニタリングしてみましょう。

$ sudo lxc-monitor -n ct01
'ct01' changed state to [STARTING]
'ct01' changed state to [RUNNING]
'ct01' changed state to [FREEZING]
'ct01' changed state to [FROZEN]
'ct01' changed state to [THAWED]
'ct01' changed state to [STOPPING]
'ct01' changed state to [STOPPED]

これはlxc-monitorを実行した後,別の端末で以下のようなコマンドを順に実行した時の出力です。

$ sudo lxc-start -n ct01 -d
$ sudo lxc-freeze -n ct01
$ sudo lxc-unfreeze -n ct01
$ sudo lxc-stop -n ct01

コンテナ名を指定しないで実行すると,コンテナの保存場所に存在する全てのコンテナをモニタリングします。

$ sudo lxc-monitor 
'ct01' changed state to [STARTING]
'ct01' changed state to [RUNNING]
'ct02' changed state to [STARTING]
'ct02' changed state to [RUNNING]
'ct02' changed state to [STOPPING]
'ct02' changed state to [STOPPED]
'ct01' changed state to [STOPPING]
'ct01' changed state to [STOPPED]

指定したコンテナの状態への待機 ~ lxc-wait

lxc-waitはコンテナが指定した状態になるのを待って終了します。コンテナの状態に応じて何かを行うようなスクリプト中で使えそうですね。

$ sudo lxc-wait -n ct01 -s STOPPED

と実行しておいて,別の端末で

$ sudo lxc-stop -n ct01

とコンテナを停止させるとlxc-waitの実行は終了します。

Ubuntu 14.04 LTSのcgroup管理

一通りコンテナの管理に必要なコマンドの紹介が済んだ所で,lxc-cgroupのところで触れたUbuntu 14.04 LTSでのcgroupの管理について簡単に紹介しておきます。

Ubuntu 12.04 LTSでは,"lxc"パッケージをインストールすると,依存関係で"cgroup-lite"というパッケージが同時にインストールされ,ホストOSの起動時にサブシステムごとのディレクトリを作成してマウントするシェルスクリプトが実行され,cgroupfsがマウントされていました。

$ grep cgroup /proc/mounts
cgroup /sys/fs/cgroup tmpfs rw,relatime,mode=755 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/cpu cgroup rw,relatime,cpu 0 0
cgroup /sys/fs/cgroup/cpuacct cgroup rw,relatime,cpuacct 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,relatime,blkio 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,relatime,hugetlb 0 0
$ ls /sys/fs/cgroup/
blkio  cpu  cpuacct  cpuset  devices  freezer  hugetlb  memory  perf_event

起動後,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ディレクトリは以下のようにすっきりしています。

$ grep cgroup /proc/mounts 
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
systemd /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/run/cgmanager/agents/cgm-release-agent.systemd,name=systemd 0 0
$ ls /sys/fs/cgroup
cgmanager  systemd
$ ls -l /sys/fs/cgroup/cgmanager/
total 0
srwxrwxrwx 1 root root 0 Aug 12 18:40 sock

cgmanagerというディレクトリが存在し,その下にはソケットが存在するだけです。

この状態でもLXCを使ってコンテナは起動し,cgroupを使ったリソースが制限できます。cgroupはcgroupfsをマウントしなければ利用できません。どこで管理されているのでしょう?

実はcgmanagerは起動時に新たなマウント名前空間を作成し,その名前空間内でcgroupfsをマウントします。このため,ホストOSが属する名前空間からはcgmanagerがマウントしたcgroupfsが見えないのです。

util-linux 2.23以降に含まれるnsenterというコマンドを使って確認してみましょう。nsenterは任意の名前空間上でコマンドが実行できるコマンドです。実行中のcgmanagerデーモンが属するマウント名前空間を指定してコマンドを実行してみます※1)⁠

※1)
Ubuntu 14.04 LTSのutil-linuxは2.20.1でnsenterは含まれませんので別途ソースからコンパイルして準備しています。
$ sudo ./nsenter --target `pgrep cgmanager` --mount -- grep cgroup /proc/mounts 
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
none,name=systemd /run/cgmanager/fs/none,name=systemd cgroup rw,relatime,release_agent=/run/cgmanager/agents/cgm-release-agent.systemd,name=systemd 0 0
cpuset /run/cgmanager/fs/cpuset cgroup rw,relatime,cpuset,release_agent=/run/cgmanager/agents/cgm-release-agent.cpuset,clone_children 0 0
cpu /run/cgmanager/fs/cpu cgroup rw,relatime,cpu,release_agent=/run/cgmanager/agents/cgm-release-agent.cpu 0 0
cpuacct /run/cgmanager/fs/cpuacct cgroup rw,relatime,cpuacct,release_agent=/run/cgmanager/agents/cgm-release-agent.cpuacct 0 0
memory /run/cgmanager/fs/memory cgroup rw,relatime,memory,release_agent=/run/cgmanager/agents/cgm-release-agent.memory 0 0
devices /run/cgmanager/fs/devices cgroup rw,relatime,devices,release_agent=/run/cgmanager/agents/cgm-release-agent.devices 0 0
freezer /run/cgmanager/fs/freezer cgroup rw,relatime,freezer,release_agent=/run/cgmanager/agents/cgm-release-agent.freezer 0 0
blkio /run/cgmanager/fs/blkio cgroup rw,relatime,blkio,release_agent=/run/cgmanager/agents/cgm-release-agent.blkio 0 0
perf_event /run/cgmanager/fs/perf_event cgroup rw,relatime,perf_event,release_agent=/run/cgmanager/agents/cgm-release-agent.perf_event 0 0
hugetlb /run/cgmanager/fs/hugetlb cgroup rw,relatime,hugetlb,release_agent=/run/cgmanager/agents/cgm-release-agent.hugetlb 0 0
$ sudo ./nsenter --target `pgrep cgmanager` --mount -- ls /run/cgmanager/fs
blkio  cpu  cpuacct  cpuset  devices  freezer  hugetlb  memory  none,name=systemd  perf_event

ご覧のように実行中の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回 コンテナ型仮想化の情報交換会@東京

著者プロフィール

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

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

Plamo Linuxメンテナ

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