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

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

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

今回は前回紹介できなかったコマンドの紹介を続けます。その後,Ubuntu 14.04 LTSでcgroupを管理するために導入されたcgmanagerについて少し紹介します。

アプリケーションコンテナ

lxc-startを使ったアプリケーションコンテナの起動

第8回lxc-startコマンドの使い方を紹介しました。その際に紹介したのはシステムコンテナを起動する方法でした。lxc-startは特に指定しなければコンテナイメージ内の/sbin/initを実行します。

ここでコマンドを指定するとlxc-startはアプリケーションコンテナとして指定したコマンドを実行します

$ sudo lxc-start -n ct01 -- /bin/bash
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
root@ct01:/# hostname 
ct01

/bin/bashを指定すると警告は出るものの,コンテナct01として/bin/bashが実行されています。

lxc-startでアプリケーションコンテナを実行するときには注意が必要です。指定したコマンドがすぐに終了して制御が戻ってきてしまうような場合,lxc-startはコンテナのinitに相当するコンテナ内のPIDが1のプロセスがすぐに終了したとみなしてコンテナが起動しません。

以下の例を見てください。これはCentOSコンテナにApacheをインストールして,アプリケーションコンテナとして実行しようとしています。

# lxc-start -n apache01 -o log -l DEBUG -- /usr/sbin/httpd
# lxc-ls --fancy
NAME      STATE    IPV4  IPV6  AUTOSTART  
----------------------------------------
apache01  STOPPED  -     -     NO         

lxc-startの実行はエラー出力もなく成功しているようです。しかし,確認してみると停止しています。ログを見てみましょう。

# cat log
  : (略)
      lxc-start 1409655419.090 NOTICE   lxc_start - exec'ing '/usr/sbin/httpd'
      lxc-start 1409655419.091 NOTICE   lxc_start - '/usr/sbin/httpd' started with pid '1504'
      lxc-start 1409655419.157 DEBUG    lxc_start - container init process exited

指定した/usr/sbin/httpdの実行は行われ,PIDが1504として起動していますが,直後にexitしてしまっています。

このような場合は指定したコマンドが終了しなければ良いので,以下のように/sbin/sbin/httpdをフォアグラウンドで起動すれば良いのです。

# lxc-start -d -n apache01 -o log -l INFO -- /usr/sbin/httpd -D FOREGROUND
# lxc-ls --fancy
NAME      STATE    IPV4        IPV6  AUTOSTART  
----------------------------------------------
apache01  RUNNING  10.0.3.200  -     NO         

このようにきちんと実行されます。

lxc-executeによるアプリケーションコンテナの実行

以上のようにフォアグラウンドで起動させるためにちょっと工夫が必要なコマンドをコンテナとして実行する際に便利な場合があるコマンドがlxc-executeです。⁠場合がある」と微妙な表現になっている理由は後で説明します。

lxc-executelxc-startと同様にコンテナを起動するためのコマンドです。lxc-startとの違いは,lxc-executeはアプリケーションコンテナを起動させるためのコマンドであるという点です。

lxc-executeは内部的な処理はlxc-startと同じです。違いはコンテナのinitとしてLXCが提供する簡易的なinitプログラムであるlxc.initを起動し,その子プロセスとして指定したコマンドを実行するところです。

これを確認してみましょう。以下ではUbuntuコンテナにApacheをインストールして実行しています。

# lxc-execute -n apache01 -o log -l INFO -- /usr/sbin/apache2ctl start &
[1] 7612
# lxc-ls --fancy
NAME      STATE    IPV4        IPV6  AUTOSTART  
----------------------------------------------
apache01  RUNNING  10.0.3.200  -     NO       

ご覧のように通常通りApacheの起動を行ってもコンテナが終了することなく起動した状態になっています。

このlxc-executeコマンドをpstreeコマンドで見てみましょう。

# pstree -A  7612
lxc-execute---init.lxc---apache2---2*[apache2---26*[{apache2}]]

ご覧のようにinit.lxcというプログラムを挟んでapache2が実行されています。

このinit.lxclxc-executeで指定したコマンドの終了を監視し,コマンドが終了すると自身も終了し,コンテナを終了させます。また,lxc-stopから送られてくるシグナルを子プロセスに送る役割も果たします。

ここまでご覧になると,アプリケーションコンテナを起動するにはlxc-executeが便利なような気がします。しかし実はそうでもありません。LXC 1.0系列でlxc-executeを使うには準備が必要です。

前述の例はUbuntu 14.04 LTSのコンテナを使っています。このコンテナに"apache2"パッケージだけでなく,以下のように"lxc"パッケージもインストールしました。これはinit.lxcをインストールするためです。

$ sudo lxc-attach -n ct01 -- apt-get install lxc
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  apparmor bridge-utils busybox-static ca-certificates cgmanager
  cloud-image-utils debootstrap distro-info distro-info-data dnsmasq-base
  euca2ools genisoimage iptables libaio1 libapparmor-perl libapparmor1
    : (略)

コンテナ内で実行するコマンドはコンテナイメージ内に存在する必要があります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-config -l
lxc.default_config
lxc.lxcpath
lxc.bdev.lvm.vg
lxc.bdev.lvm.thin_pool
lxc.bdev.zfs.root

コンテナのデフォルト設定ファイルとコンテナの保存場所を表示させてみましょう。一覧で出てきた設定を指定するだけです。

$ sudo lxc-config lxc.default_config
/etc/lxc/default.conf
$ sudo lxc-config lxc.lxcpath
/var/lib/lxc

コンテナの一時停止,再開 ~ lxc-freeze,lxc-unfreeze

起動中のコンテナを一時停止させる場合はlxc-freezeを使います。

$ sudo lxc-start -n ct01 -d
$ sudo lxc-freeze -n ct01
$ sudo lxc-ls --fancy ct01                      
NAME      STATE    IPV4        IPV6  AUTOSTART  
----------------------------------------------
ct01      FROZEN   10.0.3.156  -     NO         

一時停止中のコンテナを再開させる場合はlxc-unfreezeを使います。

$ sudo lxc-ls --fancy ct01
NAME  STATE   IPV4        IPV6  AUTOSTART  
-----------------------------------------
ct01  FROZEN  10.0.3.156  -     NO         
$ sudo lxc-unfreeze -n ct01
$ sudo lxc-ls --fancy ct01
NAME  STATE    IPV4        IPV6  AUTOSTART  
------------------------------------------
ct01  RUNNING  10.0.3.156  -     NO         

著者プロフィール

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

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

Plamo Linuxメンテナ。ファーストサーバ株式会社所属。

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

コメント

コメントの記入