lxc (Linux Container) を試す2

LXC: Linux コンテナー・ツールに書いてあることを試してみます。

準備

以下のパッケージをインストールしておきます。

  • iproute
  • bridge-utils

cgroup のマウント

カーネルオプションで指定した control group というのが必要そうなので mount します。

$ sudo mkdir -p /cgroup
$ sudo mount -t cgroup cgroup /cgroup

ネットワークブリッジの作成

本体側のネットワークインターフェースと、コンテナのネットワークインターフェースで構成するようです。
ここでは eth1 をコンテナとブリッジします。

$ /sbin/ifconfig
eth0      Link encap:イーサネット  ハードウェアアドレス 08:00:27:d8:cd:de 
          inetアドレス:10.0.1.151 ブロードキャスト:10.0.1.255  マスク:255.255.255.0
          inet6アドレス: fe80::a00:27ff:fed8:cdde/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:18762 エラー:3 損失:0 オーバラン:0 フレーム:0
          TXパケット:12117 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:13773838 (13.1 MiB)  TXバイト:1243038 (1.1 MiB)
          割り込み:19 ベースアドレス:0xd020 

eth1      Link encap:イーサネット  ハードウェアアドレス 08:00:27:b6:b1:5a 
          inetアドレス:10.0.2.15 ブロードキャスト:10.0.2.255  マスク:255.255.255.0
          inet6アドレス: fe80::a00:27ff:feb6:b15a/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:9 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:33 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:2660 (2.5 KiB)  TXバイト:3646 (3.5 KiB)
          割り込み:16 ベースアドレス:0xd240 

lo        Link encap:ローカルループバック  
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          inet6アドレス: ::1/128 範囲:ホスト
          UP LOOPBACK RUNNING  MTU:16436  メトリック:1
          RXパケット:13 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:13 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:0 
          RXバイト:1120 (1.0 KiB)  TXバイト:1120 (1.0 KiB)
$ sudo /usr/sbin/brctl addbr br0
$ sudo /usr/sbin/brctl setfd br0 0
$ sudo /sbin/ifconfig br0 10.0.2.15 promisc up
$ sudo /usr/sbin/brctl addif br0 eth1
$ sudo /sbin/ifconfig eth1 0.0.0.0 up
$ sudo /sbin/route add -net default gw 10.0.2.2 br0
$ /sbin/ifconfig
br0       Link encap:イーサネット  ハードウェアアドレス 08:00:27:b6:b1:5a 
          inetアドレス:10.0.2.15 ブロードキャスト:10.255.255.255  マスク:255.0.0.0
          inet6アドレス: fe80::5c3c:71ff:fe72:8667/64 範囲:リンク
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  メトリック:1
          RXパケット:0 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:6 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:0 
          RXバイト:0 (0.0 B)  TXバイト:468 (468.0 B)

eth0      Link encap:イーサネット  ハードウェアアドレス 08:00:27:d8:cd:de 
          inetアドレス:10.0.1.151 ブロードキャスト:10.0.1.255  マスク:255.255.255.0
          inet6アドレス: fe80::a00:27ff:fed8:cdde/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:18951 エラー:3 損失:0 オーバラン:0 フレーム:0
          TXパケット:12216 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:13789192 (13.1 MiB)  TXバイト:1253476 (1.1 MiB)
          割り込み:19 ベースアドレス:0xd020 

eth1      Link encap:イーサネット  ハードウェアアドレス 08:00:27:b6:b1:5a 
          inet6アドレス: fe80::a00:27ff:feb6:b15a/64 範囲:リンク
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:9 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:37 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:2660 (2.5 KiB)  TXバイト:3946 (3.8 KiB)
          割り込み:16 ベースアドレス:0xd240 

lo        Link encap:ローカルループバック  
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          inet6アドレス: ::1/128 範囲:ホスト
          UP LOOPBACK RUNNING  MTU:16436  メトリック:1
          RXパケット:13 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:13 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:0 
          RXバイト:1120 (1.0 KiB)  TXバイト:1120 (1.0 KiB)

$ netstat -rn
カーネルIP経路テーブル
受信先サイト    ゲートウェイ    ネットマスク   フラグ   MSS Window  irtt インタフェース
10.0.1.0        0.0.0.0         255.255.255.0   U         0 0          0 eth0
10.0.0.0        0.0.0.0         255.0.0.0       U         0 0          0 br0
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 br0
0.0.0.0         10.0.1.1        0.0.0.0         UG        0 0          0 eth0

コンテナの環境を準備する(手動)

コンテナが使うための環境(ファイルシステム)を準備します。
sshd を独立して動かすために、ファイルツリーを作ります。
また、bin とかは readonly で本体側のディレクトリをマウントします。
http://lxc.sourceforge.net/lxc.html

$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/dev/{pts,shm/network}
$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/etc/ssh
$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/{bin,lib,proc,root,sbin,sys,usr}
$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/var/empty/sshd
$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/lib/empty/sshd
$ mkdir -p /usr/local/var/lib/lxc/sshd/rootfs/run/sshd
$ tree -d /usr/local/var/lib/lxc/sshd
/usr/local/var/lib/lxc/sshd
`-- rootfs
    |-- bin
    |-- dev
    |   |-- pts
    |   `-- shm
    |       `-- network
    |-- etc
    |   `-- ssh
    |-- lib
    |   `-- empty
    |       `-- sshd
    |-- proc
    |-- root
    |-- run
    |   `-- sshd
    |-- sbin
    |-- sys
    |-- usr
    `-- var
        `-- empty
            `-- sshd

21 directories

fstab はこんなかんじで。

$ cat /usr/local/var/lib/lxc/sshd/fstab
/lib /usr/local/var/lib/lxc/sshd/rootfs/lib none ro,bind 0 0
/bin /usr/local/var/lib/lxc/sshd/rootfs/bin none ro,bind 0 0
/usr /usr/local/var/lib/lxc/sshd/rootfs/usr none ro,bind 0 0
/sbin /usr/local/var/lib/lxc/sshd/rootfs/sbin none ro,bind 0 0

lxc 用の config を作成します。

$ cat /usr/local/var/lib/lxc/sshd/config
lxc.utsname = sshd
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.0.101/24
lxc.network.name = eth0
lxc.rootfs = /usr/local/var/lib/lxc/sshd/rootfs
lxc.mount - /usr/local/var/lib/lxc/sshd/fstab

コンテナの環境を準備する(半自動)

実は lxc のユーティリティで同じようなことができるのでした…

$ sudo lxc-sshd create
What is the container name ? [sshd] sshd-tmpl
What hostname do you wish for this container ? [sshd-tmpl] 
What IP address do you wish for this container ? [172.20.0.20/24] 
Done.

You can run your container with: 
        'lxc-execute -n sshd-tmpl /usr/sbin/sshd &'

コンテナの起動

init からコンテナを起動してみます。

$ sudo lxc-start -n sshd
lxc-start: failed to clone(0x6c020000): Invalid argument
lxc-start: Invalid argument - failed to fork into a new namespace
lxc-start: failed to spawn '/sbin/init'
lxc-start: No such file or directory - failed to remove cgroup '/cgroup/sshd'

そういえば cgroup 以下はこんなふうになってます。

$ ls -l /cgroup/
合計 0
-rw-r--r-- 1 root root 0 2009-11-29 17:25 cpu.shares
-rw-r--r-- 1 root root 0 2009-11-29 17:25 cpuacct.usage
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.cgroup_refcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.current_css_set
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.current_css_set_refcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.releasable
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.taskcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.allow
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.deny
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.list
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.failcnt
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.force_empty
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.stat
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 notify_on_release
-rw-r--r-- 1 root root 0 2009-11-29 17:25 release_agent
-rw-r--r-- 1 root root 0 2009-11-29 17:25 tasks

lxc-start が失敗するとこうなる。

$ sudo lxc-start -n sshd
lxc-start: No such file or directory - failed to rename cgroup /cgroup/2351->/cgroup/sshd
lxc-start: failed to spawn '/sbin/init'
lxc-start: No such file or directory - failed to remove cgroup '/cgroup/sshd'
$ ls -l /cgroup
合計 0
drwxr-xr-x 2 root root 0 2009-11-29 17:27 2350
-rw-r--r-- 1 root root 0 2009-11-29 17:25 cpu.shares
-rw-r--r-- 1 root root 0 2009-11-29 17:25 cpuacct.usage
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.cgroup_refcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.current_css_set
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.current_css_set_refcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.releasable
-rw-r--r-- 1 root root 0 2009-11-29 17:25 debug.taskcount
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.allow
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.deny
-rw-r--r-- 1 root root 0 2009-11-29 17:25 devices.list
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.failcnt
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.force_empty
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.stat
-rw-r--r-- 1 root root 0 2009-11-29 17:25 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 2009-11-29 17:25 notify_on_release
-rw-r--r-- 1 root root 0 2009-11-29 17:25 release_agent
-rw-r--r-- 1 root root 0 2009-11-29 17:25 tasks

2350 は PID ぽいし、エラーメッセージを見ると名前が違ってるみたいです。

最初に起動したときの failed to clone あたりで、何かおかしくなっちゃってるのかな…