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

第25回LXCの構築・活用 [11] ─lxc-autostartコマンドによるコンテナの自動起動

LXCは、ホストOSの起動・停止時にコンテナを自動的に起動・停止させたり、複数のコンテナをまとめて起動、停止、リブートしたりする際に使える仕組みを持っています。

この仕組みはlxc-autostartコマンドから使います。このコマンドを使って、ホストの起動と同時に起動させたいコンテナがある場合に、起動スクリプト中で使用してコンテナを自動で起動できます。また、管理者が直接実行して複数のコンテナを同時に起動させたい場合にも使えます。

今回の実行例はUbuntu 14.04.2 LTS上のLXC 1.0.7を使って実行しています。

設定

この仕組みはコンテナの設定ファイルで設定して使用します。まずはこの自動起動の仕組みに関係するコンテナの設定項目を紹介しましょう。

表1 lxc-autostartに関係する設定項目
設定項目 設定項目の説明 デフォルト値
lxc.start.auto コンテナlxc-autostartの対象にするかどうかを設定。0(オフ⁠⁠ or 1(オン)のどちらかを設定可能 0
lxc.group コンテナが属するコンテナグループ名
lxc.start.delay コンテナを起動させた後、次のコンテナを起動させるまで待機する時間(秒) 0
lxc.start.order 対象のコンテナが複数ある場合の起動順。整数を指定する

lxc.start.auto

lxc-autostartで処理を行いたいコンテナは、コンテナの設定ファイルでlxc.start.autoを1に設定します。デフォルトではlxc.start.autoは0なのでlxc-autostartの処理対象にはなりません。

lxc.group

lxc.groupを使ってコンテナをグループ分けできます。このグループはlxc-autostartでのみ使われ、対象のコンテナをグループ分けして指定する際に使います。

lxc.groupには複数の値を指定できます。以下の例のようにスペースで区切って複数の値を指定します。また、lxc.groupを複数回指定しても構いません。

# lxc-autostartの対象とする
lxc.start.auto = 1
# コンテナは group01 と group02 に属する
lxc.group = group01 group02
# 更に group03 に属する
lxc.group = group03

以上のように設定したコンテナ"ct01"は"group01"、"group02"、"group03"の3つのグループに属することになります。

$ sudo lxc-ls -f ct01
NAME  STATE    IPV4  IPV6  AUTOSTART                        
----------------------------------------------------------
ct01  STOPPED  -     -     YES (group01, group02, group03)  

lxc.groupを指定していないコンテナは、どのグループにも属しません。このようなグループに属さないコンテナを指定するために、特別に"NULL"グループが定義されています。

lxc.start.delay

lxc-autostartを使って複数のコンテナを起動する際、一気にコンテナが起動しようとするとホストの負荷に影響を与えるような場合や、コンテナの起動に問題がある場合があるでしょう。そういう場合はlxc.start.delayを設定します。lxc.start.delayを設定したコンテナが起動した後、次のコンテナを起動するまで待つ秒数を指定します。

lxc.start.order

lxc.start.orderlxc-autostartで指定したグループに属するコンテナの起動順を指定する必要がある場合に指定します。この順番はあくまで同じグループ内に属するコンテナ間の順序を決めます。別のグループに属するコンテナとの間の起動順は、グループの指定順で順序が決まります。

lxc.start.orderに指定する値は整数で、現時点では指定された数値が大きい方から順に(降順で)起動します。たとえば、同じグループに属するコンテナ"ct01"に"1"を、"ct02"に"2"を、"ct03"に"3"を指定すると、ct03→ct02→ct01の順に起動します。

ただし、この指定は直感的ではなく、ct01→ct02→ct03の順で起動することを期待してしまう人もいるでしょう。実際にmasterブランチには、現在とは逆に数値が小さいほうから順に(昇順で)起動するパッチがマージされました。このパッチがマージされた際に、降順でソートされる動きはバグとされましたので、将来のバージョンでは現在と逆に昇順で動作するようになるかもしれません。ただ、全く逆の動きになってしまうので既に降順でリリースされている1.0、1.1系列でマージされるかどうかはわかりません。

現時点では、起動順序が重要な場合にはこの機能を使わず、グループ分けをしてグループの指定順で起動順を決めるなど、別の工夫をした方が良いかもしれません。

lxc-autostartコマンドの実行

設定について一通り紹介が済んだ所で、lxc-autostartを使ったコンテナの起動を見ていきましょう。

まずはlxc-autostartコマンドのオプションを見ておきましょう。

表2 lxc-autostartコマンドのオプション
オプション オプションの説明
-r,--reboot コンテナのリブート
-s,--shutdown コンテナのシャットダウン
-k,--kill コンテナの強制終了
-t,--timeout コンテナ停止時のタイムアウト時間の指定
-g,--group グループの指定
-L,--list 実際の処理は行わず対象のコンテナのリストを表示する
-a,--all lxc.start.auto=1が設定された全てのコンテナを対象とする

-r-s-k-tという停止に関係するオプションは第8回で説明したlxc-stopマンドのオプションと同じです。

グループを指定したlxc-autostartコマンドの実行

それでは、lxc-autostartコマンドでグループを指定して複数のコンテナを起動してみましょう。

グループの指定ではカンマ区切りで複数のグループを指定できます。また-gオプションを複数回指定できます。複数のグループを指定した場合は、指定したグループの順にそれぞれに属するコンテナが起動します。

たとえば、以下のように3つのコンテナをそれぞれ別のグループに所属するように設定します。

$ sudo lxc-ls -f
NAME  STATE    IPV4  IPV6  AUTOSTART      
----------------------------------------
ct01  STOPPED  -     -     YES (group01)  
ct02  STOPPED  -     -     YES (group02)  
ct03  STOPPED  -     -     YES (group03)

ここで"group01"と"group02"を指定してlxc-autostartコマンドを実行します。

$ sudo lxc-autostart -g group01,group02 (group01,group02に属するコンテナの起動)
$ sudo lxc-ls -f
NAME  STATE    IPV4        IPV6  AUTOSTART      
----------------------------------------------
ct01  RUNNING  10.0.3.87   -     YES (group01)  
ct02  RUNNING  10.0.3.241  -     YES (group02)  
ct03  STOPPED  -           -     YES (group03)
$ sudo lxc-autostart -g group01,group02 -s  (group01,group02に属するコンテナの停止)

指定したグループに属するコンテナのみ起動していますね。以上の例ではカンマ区切りでグループを指定しましたが、以下のように-gを複数回指定することもできます。

$ sudo lxc-autostart -g group01,group02 -g group03
 (group01,group02,group03に属するコンテナの起動)
$ sudo lxc-ls -f
NAME  STATE    IPV4        IPV6  AUTOSTART      
----------------------------------------------
ct01  RUNNING  10.0.3.87   -     YES (group01)  
ct02  RUNNING  10.0.3.241  -     YES (group02)  
ct03  RUNNING  10.0.3.20   -     YES (group03)
$ sudo lxc-autostart -g group01,group02 -g group03 -s
 (group01,group02,group03に属するコンテナの停止)

1つ目の-gで2つグループを指定し、2つ目の-gで1つグループを指定してみましたが、全てのコンテナが起動しています。

全てのコンテナに対するlxc-autostartコマンドの実行

-aオプションを使い、グループ指定を無視してlxc.start.auto = 1が設定されたコンテナ全てを処理対象にできます。

$ sudo lxc-autostart -a  (lxc.start.auto=1が設定された全てのコンテナの起動)
$ sudo lxc-ls -f
NAME  STATE    IPV4        IPV6  AUTOSTART      
----------------------------------------------
ct01  RUNNING  10.0.3.87   -     YES (group01)  
ct02  RUNNING  10.0.3.241  -     YES (group02)  
ct03  RUNNING  10.0.3.20   -     YES (group03)
$ sudo lxc-autostart -a -s  (lxc.start.auto=1が設定された全てのコンテナの停止)

NULLグループの指定

先に説明した"NULL"グループに属するコンテナを-gオプションでどのように指定するのかを紹介しましょう。

$ sudo lxc-ls -f
NAME  STATE    IPV4  IPV6  AUTOSTART      
----------------------------------------
ct01  STOPPED  -     -     YES            
ct02  STOPPED  -     -     YES (group02)  
ct03  STOPPED  -     -     YES (group03)  

以上のようにコンテナ"ct01"のみグループに属していません。ここで"ct01"のみを指定するには以下のように空文字列を指定します。

$ sudo lxc-autostart -g ""  (NULLグループを指定してコンテナを起動)
$ sudo lxc-ls -f
NAME  STATE    IPV4       IPV6  AUTOSTART      
---------------------------------------------
ct01  RUNNING  10.0.3.87  -     YES            
ct02  STOPPED  -          -     YES (group02)  
ct03  STOPPED  -          -     YES (group03)
$ sudo lxc-autostart -g "" -s   (NULLグループを指定してコンテナを停止)

ただし、"NULL"グループのみを指定する場合は、-gオプションを指定せずにlxc-autostartコマンドを実行しても同じです。

$ sudo lxc-autostart  (-gオプションを指定せずに実行)
$ sudo lxc-ls -f
NAME  STATE    IPV4       IPV6  AUTOSTART      
---------------------------------------------
ct01  RUNNING  10.0.3.87  -     YES            
ct02  STOPPED  -          -     YES (group02)  
ct03  STOPPED  -          -     YES (group03)
$ sudo lxc-autostart -s  (-gオプションを指定せずにコンテナを停止)

"NULL"グループを含む複数のグループも指定できます。

$ sudo lxc-autostart -g "" -g group02  (NULLグループとgroup02を指定してコンテナを起動)
$ sudo lxc-ls -f
NAME  STATE    IPV4        IPV6  AUTOSTART      
----------------------------------------------
ct01  RUNNING  10.0.3.87   -     YES            
ct02  RUNNING  10.0.3.241  -     YES (group02)  
ct03  STOPPED  -           -     YES (group03)
$ sudo lxc-autostart -g "" -g group02 -s  (NULLグループとgroup02を指定してコンテナを停止)

"NULL"グループの指定は次のようにも指定できます。

$ sudo lxc-autostart -g ,group02  (グループ指定をカンマから始める)
$ sudo lxc-autostart -g group02,  (グループ指定をカンマで終わる)
$ sudo lxc-autostart -g group02,,group03  (カンマを2つ続ける)

対象コンテナのリスト表示

ここまではlxc-autostartコマンドを使って、実際に対象となるコンテナを起動しました。一方、実際にコンテナは起動せずに、対象となっているコンテナのリストを表示するだけのオプションもあります。

これが-Lオプションです。このオプションを使うと、lxc.start.orderの設定も反映した順でコンテナ名とlxc.start.delayの値がリスト表示されます。

"ct01"、"ct02"、"ct03"の順に起動するように設定し、全てlxc.start.delay = 1と設定した同じグループに属するコンテナに対して-Lオプションを付けると以下のように出力されます(※1)

$ sudo lxc-autostart -L
ct01 1
ct02 1
ct03 1

Ubuntu起動時のlxc-autostartの使用

一通りlxc-autostartコマンドの使い方を見た所で、実際にlxc-autostartコマンドがどのように使われているのかを見てみましょう。

Ubuntuでlxcパッケージをインストールすると、upstart用のジョブ定義ファイルが3つインストールされます。

$ dpkg -L lxc | grep /etc/init/
/etc/init/lxc.conf
/etc/init/lxc-instance.conf
/etc/init/lxc-net.conf

このうち、lxc-net.conf第8回で説明したUbuntuで設定されるLXC用のネットワークを作成するための定義ファイルです。

これ以外の2つのファイル内で、ホストOS起動時にコンテナを自動起動するための処理が記述されています。

コンテナの自動起動と停止は、先に説明したlxc-autostartを直接使ってるのかと思って確認してみましたが、実はそうなってはいません。簡単に見ていきましょう。

まず、ホストOS起動時にコンテナの自動起動を行うかどうかが/etc/default/lxcで定義されています。

$ grep LXC_AUTO /etc/default/lxc
# LXC_AUTO - whether or not to start containers symlinked under
LXC_AUTO="true"

このLXC_AUTOtrueになっているときだけ、コンテナの自動起動が行われます。

続いて/etc/init/lxc.confを見てみましょう。

    :(略)
 4: start on runlevel [2345]
 5: stop on starting rc RUNLEVEL=[016]
 6:
 7: env LXC_AUTO="false"
    :(略)
16: env BOOTGROUPS="onboot,"
    :(略)
33: pre-start script
34:         [ -f /etc/default/lxc ] && . /etc/default/lxc
    :(略)
45:         [ "x$LXC_AUTO" = "xtrue" ] || exit 0
46:
47:         if [ -n "$BOOTGROUPS" ]
48:         then
49:                 BOOTGROUPS="-g $BOOTGROUPS"
50:         fi
51:
52:         # Process the "onboot" group first then the NULL group.
53:         lxc-autostart -L $OPTIONS $BOOTGROUPS | while read line; do
54:                 set -- $line
55:                 (start lxc-instance NAME=$1 && sleep $2) || true
56:         done
57: end script

自動起動に関係する行だけ抜き出しましたので簡単にみていきましょう。

  • 先に紹介したLXC_AUTOtrueの時のみ、自動起動が実行されるようになっています(7,34,45行目)
  • OS起動時に自動起動するコンテナとして"onboot"グループに属するコンテナと"NULL"グループに属するコンテナが指定されています(16, 49行目)
  • "onboot"グループ、"NULL"グループの順で対象コンテナをリストアップして、コンテナ名を1つずつ順に与えながら"lxc-instance"というジョブを開始させ、その後lxc.start.delayで指定した秒数だけsleepしています(53〜56行目)

ジョブ"lxc-instance"は/etc/init/lxc-instance.confで定義されており、以下のようになっています。

    :(略)
 4: stop on stopping lxc
    :(略)
10: kill signal SIGPWR
    :(略)
13: instance $NAME
    :(略)
16: pre-start script
17:         lxc-wait -s RUNNING -n $NAME -t 0 && { stop; exit 0; } || true
18: end script
19:
20: script
21:         exec lxc-start -n $NAME
22: end script

"lxc-instance"ジョブは以下のように動くように定義されています。

  • "lxc"ジョブが停止する時(runlevel 0,1,6に入る時)に停止します(4行目)
  • 停止の際はプロセスにSIGPWRシグナルを送ります。つまりコンテナのinitにSIGPWRを送っていることになります(10行目)
  • 対象のコンテナが既に起動している時はジョブを停止し、ジョブの処理部分は実行しません(16~18行目)
  • 引数NAMEで与えられた値を引数にlxc-start -n $NAMEコマンドを実行します。つまりジョブ"lxc"から与えられたコンテナ名を引数にコンテナを起動しています(20~22行目)

つまりホストOS起動時はlxc-autostart -Lで対象コンテナをリストアップして、ひとつずつlxc-startしているわけですね。停止の時はlxc-autostart -slxc-stopも使わずに直接コンテナのinitプロセスにシャットダウン用のシグナルを送っています。

ここではホストOSがUbuntuで、initとしてupstartが使われている場合の処理を見てみましたが、LXCのソースに同梱されている各種init用のファイルでも、"onboot"グループと"NULL"グループを使ってコンテナの起動を行うようになっています。

LXCに同梱されているスクリプトをベースにしているディストリビューションでは、"onboot"グループを指定するか、グループ指定をしないかのどちらかで、ホストOS起動時に自動起動させることができるでしょう。しかし、ディストリビューション独自の自動起動の仕組みになっている可能性がありますので、もしこの機能を使ってホストOS起動時にコンテナを起動したい場合は確認が必要です。

まとめ

今回は複数のコンテナをまとめて起動できるlxc-autostartコマンドを紹介しました。このコマンドを使ってホストOS起動時に同時にコンテナを起動したり、複数のコンテナをグループ分けして一斉に起動したりできます。

Ubuntuではlxc-autostartを使ってホストOS起動時にコンテナを起動できるようになっています。その仕組みについても簡単に紹介しました。お使いのディストリビューションでも、このコマンドを使ってホストOS起動時にコンテナを起動する仕組みがあるかも知れませんので、必要であれば調べてみてください。

おすすめ記事

記事・ニュース一覧