lxc(7) Linux コンテナ

クイックスタート

急いでいて、この man ページすら読みたくないという場合は、いいでしょう、 保証はないですが、あらかじめ準備されている設定テンプレートを使ったコンテナ内でシェルを動かすためのコマンドを紹介しましょう。 /usr/bin/lxc-execute -n foo -f /usr/share/doc/lxc/examples/lxc-macvlan.conf /bin/bash

概要

コンテナ技術は、メインストリームの linux kernel で活発に開発が進んでいる技術です。 コンテナ技術は、process container という名前でも知られる control groups の機能を使って、リソース管理を提供し、名前空間を使って、リソースの隔離を提供します。

linux コンテナ (lxc) は、ユーザースペースのコンテナオブジェクトを提供するための新しい機能を使う事を目指しています。 この新しい機能とは、アプリケーションやシステムでの利用を目的とした、完全なリソースの隔離やリソースコントロールを提供する機能です。

このプロジェクトの第一の目的は、コンテナプロジェクトに参加するカーネル開発者の作業を快適にすることと、特に新機能である Checkpoint/Restart 機能への取り組みを続ける事です。 lxc コマンドは、シンプルなコマンドでコンテナの管理を簡単に行えるように小さく、他の目的のために使うのに充分な機能を持っています。

必要条件

lxc は、カーネルが提供するいくつかの機能に依存しており、その機能がアクティブになっている必要があります。 機能が足りない場合は、lxc は、いくつかの機能が制限されるか、単純に動作が失敗します。

以下のリストは、コンテナの全機能を有効にするために、カーネルで有効にする必要のある機能の一覧です。

            * General setup
              * Control Group support
                -> Namespace cgroup subsystem
                -> Freezer cgroup subsystem
                -> Cpuset support
                -> Simple CPU accounting cgroup subsystem
                -> Resource counters
                  -> Memory resource controllers for Control Groups
              * Group CPU scheduler
                -> Basis for grouping tasks (Control Groups)
              * Namespaces support
                -> UTS namespace
                -> IPC namespace
                -> User namespace
                -> Pid namespace
                -> Network namespace
            * Device Drivers
              * Character devices
                -> Support multiple instances of devpts
              * Network device support
                -> MAC-VLAN support
                -> Virtual ethernet pair device
            * Networking
              * Networking options
                -> 802.1d Ethernet Bridging
            * Security options
              -> File POSIX Capabilities
      

2.6.32 以上のバージョンが採用されているディストリビューションならば、lxc は動作するでしょう。 機能的には若干少ない形ですが、充分に楽しめるはずです。 ヘルパースクリプトの lxc-checkconfig を使って、あなたのカーネルの設定に関する情報を取得できるでしょう。

control group は、どこにでもマウント可能です。 例えば、mount -t cgroup cgroup /cgroup のようにです。 しかし、cgroup の階層構造を /sys/fs/cgroup 以下にマウントするために cgmanager や cgroup-lite や systemd の使用が推奨されています。

機能仕様

コンテナは、コンテナ内で実行されているシステムやアプリケーションに対するホストのリソースのいくつかが、隔離されているオブジェクトです。

アプリケーション/システムは、あらかじめ作成された設定もしくは開始コマンドのパラメータで指定された設定で、コンテナ内で実行されます。

どうやってコンテナ内でアプリケーションを実行するのでしょう?

アプリケーションを実行する前に、隔離したいリソースについて知っておくべきです。 デフォルトの設定では、pid、sysv ipc、マウントポイントが隔離されます。 コンテナ内でシンプルなシェルを実行したい場合で、特に rootfs を共有したい場合、基本的な設定が必要です。 もし、sshd のようなアプリケーションを実行したい場合、新しいネットワークスタックと、新しいホスト名を準備しなくてはなりません。 もし、同じファイル (/var/run/httpd.pid 等) の衝突を避けたい場合、空の /var/run/ を再度マウントしなければなりません。 どんな場合でも、衝突を避けたい場合、コンテナ専用の rootfs を指定することができます。 rootfs はディレクトリツリーとなる事も可能で、前もって元の rootfs を bind マウントし、しかし、自身の /etc/homeを使って。自身のディストリビューションを使うことが可能です。

ここで、sshd のためのディレクトリツリーのサンプルを示しましょう。

        
[[email protected] sshd]$ tree -d rootfs
        
rootfs  
|-- bin 
|-- dev 
|   |-- pts
|   `-- shm
|       `-- network
|-- etc 
|   `-- ssh
|-- lib 
|-- proc
|-- root
|-- sbin
|-- sys 
|-- usr 
`-- var 
    |-- empty
    |   `-- sshd
    |-- lib
    |   `-- empty
    |       `-- sshd
    `-- run
        `-- sshd
      

そして、それに対応するマウントポイントのファイルは以下のようになります。

        [[email protected] sshd]$ cat fstab
        /lib /home/root/sshd/rootfs/lib none ro,bind 0 0
        /bin /home/root/sshd/rootfs/bin none ro,bind 0 0
        /usr /home/root/sshd/rootfs/usr none ro,bind 0 0
        /sbin /home/root/sshd/rootfs/sbin none ro,bind 0 0
      

コンテナ内でシステムを実行する方法は?

コンテナ内でシステムを実行するのは、逆説的ではありますが、アプリケーションを実行するよりも簡単です。 それは、隔離するリソースについて考える必要がないからで、全てを隔離する必要があるからです。 他のリソースは、コンテナが設定を行うので、設定なしで隔離されるように指定されます。 例えば、IPv4 アドレスはコンテナの init スクリプトでシステムによってセットアップされるでしょう。 以下に、(システムを実行するときの) マウントポイントファイルを示します。

        [[email protected] debian]$ cat fstab
        /dev    /home/root/debian/rootfs/dev none bind 0 0
        /dev/pts /home/root/debian/rootfs/dev/pts  none bind 0 0
      

設定を手助けするために、コンテナに更なる情報を追加することも可能です。 例えば、ホスト上に存在する resolv.conf ファイルをコンテナからアクセス可能にするには、以下のようにします。

        /etc/resolv.conf /home/root/debian/rootfs/etc/resolv.conf none bind 0 0
      

コンテナのライフサイクル

コンテナが作成されるとき、コンテナは設定情報を含みます。 プロセスが生成されるとき、コンテナは開始し、実行されるでしょう。 コンテナ内で実行されている最後のプロセスが終了したとき、コンテナは停止します。

コンテナの初期化時の失敗の場合は、(以下の図の) 中断の状態を通ります。

   ---------
  | STOPPED |<---------------
   ---------                 |
       |                     |
     start                   |
       |                     |
       V                     |
   ----------                |
  | STARTING |--error-       |
   ----------         |      |
       |              |      |
       V              V      |
   ---------    ----------   |
  | RUNNING |  | ABORTING |  |
   ---------    ----------   |
       |              |      |
  no process          |      |
       |              |      |
       V              |      |
   ----------         |      |
  | STOPPING |<-------       |
   ----------                |
       |                     |
        ---------------------
      

設定

コンテナは設定ファイル経由で設定します。設定の書式は以下で説明しています。 lxc.conf(5)

コンテナの生成と終了 (持続性のコンテナ)

持続性のコンテナオブジェクトは lxc-create コマンドで作成することができます。 コマンドにはコンテナ名をパラメータとして、オプションで設定ファイルとテンプレートを指定します。 ここで指定する名前は、他のコマンドからこのコンテナを参照する際に使います。 lxc-destroy コマンドはコンテナオブジェクトを破壊します。

          lxc-create -n foo
          lxc-destroy -n foo
        

揮発性のコンテナ

コンテナを開始する前にコンテナオブジェクトを作成する必要はありません。 コンテナを設定ファイルのパラメータで指定して直接開始することができます。

コンテナの開始と終了

コンテナが作成されると、アプリケーションもしくはシステムとして実行することができます。 このために使用するのが lxc-executelxc-start コマンドです。 アプリケーションが開始する前にコンテナが作成されなかった場合、コンテナはコマンドへ与えるパラメータを取得するのに設定ファイルを使うでしょう。 もし、このようなパラメータもない場合は、デフォルトで指定されている通りに隔離されます。 アプリケーションが終了した場合、コンテナも停止しますが、実行中のアプリケーションを停止するには lxc-stop を使用する必要があります。

コンテナ内のアプリケーションの実行は、正確にはシステムとして実行するのとは異なります。 そのような理由で、コンテナ内でアプリケーションを実行するためのコマンドには、2 種類の違ったものがあります。

          lxc-execute -n foo [-f config] /bin/bash
          lxc-start -n foo [-f config] [/bin/bash]
        

lxc-execute コマンドは、lxc-init プロセス経由で、コンテナ内で特定のコマンドを実行します。 lxc-init はコマンドを実行した後、(コンテナ内でのデーモンの実行をサポートするために) 実行したコマンドと生成された全てのプロセスが終了するのを待ちます。 言いかえると、コンテナ内では lxc-init は pid 1 を持ち、アプリケーションの最初のプロセスは pid 2 をもちます。

lxc-start コマンドは、コンテナ内の特定のコマンドを直接実行します。 最初のプロセスの pid が 1 となります。 もし、実行するコマンドが指定されない場合は、lxc-start は lxc.init_cmd で設定されたコマンドを実行します。もし lxc.init_cmd が設定されていない場合は /sbin/init を実行します。

まとめると、lxc-execute はアプリケーションを実行するためのコマンドであり、lxc-start はシステムを実行するのにより適したコマンドです。

もしアプリケーションの反応がなくなった場合や、アクセスできなくなった場合、自分で終了することができない場合は、荒っぽいですが、lxc-stop コマンドがコンテナ内の全てのプロセスを容赦なく停止させてくれるでしょう。

利用可能な TTY への接続

コンテナが tty を持つように設定されているならば、tty を通してコンテナにアクセスすることができます。 それは以下のコマンドが使う tty がコンテナで利用可能に設定されているか次第です。 tty が失われたとき、再度のログインなしでその tty に再接続することが可能です。

          lxc-console -n foo -t 3
        

コンテナの凍結と解凍

ジョブスケジューリングなどで、コンテナに属する全てのプロセスを停止する事が役に立つときがあります。 コマンド

          lxc-freeze -n foo
        

は、全てのプロセスを中断不可能な状態に置きます。そして、

          lxc-unfreeze -n foo
        

その全てのプロセスを再開します。

この機能は、カーネルで cgroup freezer 機能が有効になっている場合に使用可能です。

コンテナに関する情報の取得

多数のコンテナが存在する場合、それらが実行されたり破壊されたりすること、何が実行されていて、特定のコンテナ内で実行されている pid が何であるかをフォローするのは大変です。 このような時には、以下のようなコマンドが役に立つかもしれません。

          lxc-ls
          lxc-info -n foo
        

lxc-ls は、システムのコンテナを一覧します。

lxc-info は、指定したコンテナに関する情報を取得します。

ここで、以上のコマンドを組み合わせて、どのようにしたら全てのコンテナのリストと、それぞれの状態が得られるかの例を示します。

          for i in $(lxc-ls -1); do
            lxc-info -n $i
          done
        

コンテナのモニタリング

時々、コンテナの状態を追跡することが出来ると便利な事があります。 例えば、状態をモニタリングしたり、スクリプト内で特定の状態を待ったりするような場合です。

lxc-monitor コマンドは、一つもしくはいくつかのコンテナをモニタリングします。 このコマンドのパラメータは、正規表現を受け付けます。例えば

          lxc-monitor -n "foo|bar"
        

は 'foo' と 'bar' という名前のコンテナの状態をモニタリングします。そして、

          lxc-monitor -n ".*"
        

は全てのコンテナの状態をモニタリングします。

コンテナ 'foo' が開始され、いくつか処理を行い、終了した場合、出力は以下のようになります。

          'foo' changed state to [STARTING]
          'foo' changed state to [RUNNING]
          'foo' changed state to [STOPPING]
          'foo' changed state to [STOPPED]
        

lxc-wait コマンドは指定した状態を待って、終了します。 これは、コンテナの開始や終了に同期したいスクリプトで役に立ちます。 パラメータは、異なった状態の論理和 (OR) を指定します。 以下の例は、バックグラウンドで実行されたコンテナをどのようにして待つかを示します。

          # launch lxc-wait in background
          lxc-wait -n foo -s STOPPED &
          LXC_WAIT_PID=$!
          # this command goes in background
          lxc-execute -n foo mydaemon &
          # block until the lxc-wait exits
          # and lxc-wait exits when the container
          # is STOPPED
          wait $LXC_WAIT_PID
          echo "'foo' is finished"
        

コンテナの CONTROL GROUP の設定

コンテナは control group と結合しています。 コンテナが開始すると control group が生成され、それと結びつけられます。 control group のプロパティは、lxc-cgroup コマンドを使って、コンテナが実行中に読み取ったり、変更したりすることができます。

lxc-cgroup コマンドは、コンテナと結びつけられている control group サブシステムを設定したり、取得したりするのに使います。 サブシステム名の指定はユーザが行ない、このコマンドはサブシステム名の文法チェックは一切行ないません。 もし、指定したサブシステム名が存在しない場合は、コマンドの実行は失敗します。

          lxc-cgroup -n foo cpuset.cpus
        

は、このサブシステムの内容を表示します。

          lxc-cgroup -n foo cpu.shares 512
        

は、このサブシステムに指定した値を設定します。

バグ

lxc はまだ開発中です。 従って、コマンドの文法や API は変更される可能性があります。 バージョン 1.0.0 がそれらを凍結するバージョンとなるでしょう。

作者

Daniel Lezcano <[email protected]>