まえだこうへ
い
![]() |
Debian 勉強会に参加されている面々は、 そろそろ Xen や KVM 以外に何かないのか、 新たなネタを求めている向きが多い かと思います。 そこで、 最近、 Linux Kernel に新たにマージされた機能を使って実現している、 lxc という仮想化技術につい て紹介します。
lxc*5 は、 正式名称を Linux Containers と言い、 コンテナ自体が稼働するためのカーネルの機能と、 コンテナを管理するためのとユー ザツールから構成されます。 lxc で使用している Kernel の機能 (Control Group, 以下 Cgroup と省略) は、 kernel 2.6.29 で完全にマージされ、 カーネルにパッチを当ててビルドする必要がなくなってなってい ます。 kernel 2.6.29 より前のカーネルでは、 kernel 2.6.27 以降であればパッチを当てれば使うことができ ます。
lxc は GPL2 ライセンスで公開されていて、 開発およびメンテナンスは、 Daniel Lezcano 氏が実質一人で行ってい ます。
Debian では、 Squeeze/Sid からパッケージ化されており、 一つ前の最新 版*6 が パ ッケ ー ジ と な って い ま す 。
コンテナ型の仮想化技術というと有名なのは、 Solaris Containers や FreeBSD jail がありますが、 Linux では Linux-VServer, OpenVZ*7 な どがあります。 いずれも既に使ったことがある方が多いのではないのでしょうか。
lxc で提供されるサービスは、 大きく分類してシステムコンテナと、 アプリケーションコンテナの 2 つがあります。 前者は、 いわゆる OS まるごとの仮想化です。 init から起動して、 仮想 OS の空間を提供します。 後者は、 chroot によるアプリ ケーションの分離に近いです。 単一アプリケーションを分離するだけなので、 とても軽くシンプルなのが特徴 です。
lxc は現状、 一人で開発・メンテナンスされており、 今後プロジェクトがどうなるのか先行き見えないところではあります。 現在、 メーリングリストを見ている限りでは開発は続いているようです。
ユーザスペースのツールのソースコードは、 SourceForge にあります。 ソースコードは git で管理されており、 最新版は git リ ポジトリから取得できます。
$ git clone git://lxc.git.sourceforge.net/gitroot/lxc/lxc
|
Debian では前述のとおり、 Squeeze/Sid でパッケージになってい る*8 た め、 最新版である必要がなければ、 ソースコードは特に必要ありません。
lxc の機能をフルに活用するには以下のカーネルオプションが有効になっている必要があります。
* General
* Control Group support -> namespace cgroup subsystem -> cpuset support -> Group CPU scheduler -> control group freeze subsystem -> Basis for grouping tasks (Control Groups) -> Simple CPU accounting -> Resource counters -> Memory resource controllers for Control Groups -> Namespace support -> UTS namespace -> IPC namespace -> User namespace -> Pid namespace * Network support -> Networking options -> Network namespace support |
これらが有効になっているかを確認するには、 lxc のソースツリーに含まれている、 src/lxc/lxc-checkconfig.in というシェル スクリプトを実行すれば、 現在起動中のカーネルでどのカーネルオプションが無効になっているかをチェックでき ます。
また、 Debian パッケージでは、 /usr/bin/lxc-checkconfig としてインストールされています。 Squeeze/Sid で Debian のカーネル パッケージ*9 を 使っている環境で確認すると以下の結果になります。 Cgroup memory controller のみが無効になっているよう です。
$ lxc-checkconfig
Kernel config /proc/config.gz not found, looking in other places... Found kernel config file /boot/config-2.6.30-2-amd64 --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup namespace: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: disabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled File capabilities: enabled |
ここから先は、 Squeeze/Sid でパッケージを使うことを前提として話を進めますが、 このままでは、 cgroup でのメモリ管理 は無効になっていますので、 カーネルオプションCONFIG_CGROUP_MEM_RES_CTLRを有効にしてリビルド してください。 それ以外で実際に Debian で lxc を使うために必要なパッケージは何かというと lxc だけ です。
$ sudo apt-get install lxc
|
これでアプリケーションコンテナを試すことはできます。 README にも載っている手順ですが、 次のコマンドを実行する と、 即席のコンテナを起動できます。
$ uname -a
Linux silicon 2.6.32 #1 SMP Sun Dec 6 02:30:30 JST 2009 x86_64 GNU/Linu $ sudo lxc-execute -n hoge -f ./lxc-macvlan.conf /bin/bash # uname -a Linux alpha 2.6.32 #1 SMP Sun Dec 6 02:30:30 JST 2009 x86_64 GNU/Linux |
他のコンソールからコンテナが起動しているか確認してみます。
$ sudo lxc-info -n hoge
’hoge’ is RUNNING $ lxc-ps -n hoge CONTAINER PID TTY TIME CMD 4747 pts/3 00:00:00 bash 5692 pts/3 00:00:00 lxc-ps 5693 pts/3 00:00:00 ps |
ちゃんと確認できましたね。 今回は、 これで以上です、 と言いたいところですが、 この環境はコンテナを起動させただけでし かなく、 はっきり言って役に立ちません。 bash を sudo で起動しているだけで、 ホスト OS のファイルシステムにもアクセス できてしまいます。
コンテナだけを起動させて満足、 はい、 終了とするのであれば良いかもしれませんが、 実際に lxc を活用しようと考えて いるなら次に挙げる他のパッケージをインストールし、 さらにコンテナ用のクローズ環境を作る必要があり ます。
今回は、 クローズな Debian 環境を簡単に作るための方法を紹介します。 *10
ブリッジの設定
必要なパッケージをインストールしたら、 まずはブリッジの設定を行う必要があります。 /etc/network/interfaces で直接ブ リッジの設定をすれば良いと思いますが。 シェルスクリプトを用意して、 それを post-up で実行させれば良いで しょう。
#!/bin/sh
brctl addbr br0 <- ブリッジデバイスの追加 brctl setfd br0 0 <- ブリッジデバイス br0 の設定 ifconfig br0 192.168.0.1 promisc up brctl addif br0 eth0 ifconfig eth0 0.0.0.0 up route add -net default gw 192.168.0.254 br0 <- ホスト OS のゲートウェイ |
interfaces は以下のように設定します。
$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 allow-hotplug eth0 iface eth0 inet static address 192.168.0.101 netmask 255.255.255.0 broadcast 192.168.0.255 pre-up /etc/init.d/iptables start post-up /etc/network/if-up.d/brctl.sh |
以上のあと、 ブリッジの設定がきちんとされているか確認してみると、 以下のようになります。
$ /usr/sbin/brctl show
bridge name bridge id STP enabled interfaces br0 8000.00wwwwyyyyxxno eth0 veth0_14820 veth0_15932 veth0_17164 |
ちなみに “veth0_” の後ろの数字は、 コンテナで起動した init プロセスのプロセス ID です。
IP フォワードと NAT の設定
ホスト OS とコンテナ、 コンテナとホスト OS の外部のネットワーク、 コンテナ間での通信は、 上記の設定だけでなく、 IP フォワードや NAT の設定をする必要があります。 例えば、 コンテナ起動後、 ホスト OS から ssh でログインするのにも、 IP フォワードが必要となります。
$ sudo bash -c ‘‘echo 1 > /proc/sys/net/ipv4/ip_forward’’
|
IP フォワードを設定するととで、 ホスト OS の外部のネットワークへの通信や、 コンテナ同士の通信も行えるようにはなり
ます。 一方、 ホスト OS の外部ネットワークからはこのままではアクセスできません。 アクセスを許可するには、 ホスト OS で
ポートフォワーディングや、 宛先 NAT などを行う必要があります。 ポートフォワーディングを行うのであれば、 以下のような
ルールを設定します。
ここでの設定は、 デフォルトポリシーが全て ACCEPT であることを前提にしていますが、 実際には当然 DROP に
すると思いますので、 FORWARD のルールなども定義する必要があります。 Netfilter のルールと IP フォ
ワーディングの許可はスクリプトにして、 /etc/network/interface で pre-up として設定しておくと良いで
しょう。
なお、 FORWARD チェインのデフォルトポリシーが ACCEPT である場合は問題ありませんが、 DROP や REJECT に設
定してある場合は、 コンテナ同士での通信はできません。 FORWARD チェインでの ACCEPT ルールが必要になり
ます。
では、 システムコンテナのイメージを作成してみます。 lxc のパッケージに含まれる、 /usr/share/doc/lxc/examples/lxc-debian.gz
を使って、 Debian のシステムコンテナを作成します。
まず、 このファイルをホームディレクトリなどで伸張します。
次に、 cgroup ファイルシステムをマウントします。 /etc/fstab に下記一行を追記します。 マウントポイントは任意の場所で
構いません。
追記したら、 マウントポイントのディレクトリを作成し、 マウントします。
それでは、 先ほどの lxc-debian スクリプトを使ってコンテナイメージを作成します。 このスクリプトでは debootstrap を
使ってイメージが作成されますが、 ディストリビューションは lenny になっています。 前述した通り本環境は
Squeeze/Sid ですので、 コンテナも Squeeze/Sid の方が良ければ、 コンテナイメージを作成する前に予めスクリプト
を 書 き 換 え て お く 必 要 が あ り ま す 。 ま た 、 パ ッケ ー ジ も 、 デ フ ォル ト で
apache2 がインストールされたり、
一方、 sudo や vi, dig コマンドが無かったりするので、 そのままインストールすると不便であったりする
ので、 予めインストールするパッケージの指定を変更しておく必要があります。 lxc-debian スクリプト内の
debootstrap コマンドの--includeオプションでパッケージの指定は変更できます。 また、 sshd の設定や、 ネッ
トワークの設定も予め設定しておくと便利です。 以下、 変更済みファイルとの diff の結果を掲載しておき
ます。
それでは、 コンテナを作成します。 コンテナを作成する場所は任意の場所にできます。 通常、 lxc-debian スクリプトを実行
を実行したディレクトリの下に debian ディレクトリを自動的に作成し、 その下にコンテナイメージである rootfs が作成されま
す。 配置したいディレクトリが無ければ作成し、 そのディレクトリへ移動し、 sudo lxc-debian createを実行し
ます。
これで、 /var/cache/lxc/debian/rootfs.hoge という名前でコンテナイメージのディレクトリが作成され、 ここに、
debootstrap による Debian イメージのコピーが作成されます。 初めて lxc-debian create を実行すると、 debootstrap で
ダウンロードされるキャッシュイメージが、 /var/cache/lxc/debian/rootfs-architecture として作成されます。
*12
コンテナ自体のメタ情報は、 /var/lib/lxc ディレクトリのコンテナ名のディレクトリ以下にあります。 ツリー表示すると以下
のようになっています。
システムコンテナの起動の前に、 やることがあります。 コンテナイメージに、 ログイン可能なユーザアカウ
ントを作成することと、 /etc/hosts を書き換えることです。 前者は、 コンテナ作成後にそのまま起動
させたのでは、 ログインすることができません。 ホスト OS 側と同じユーザアカウントで問題なけれ
ば、 /var/cache/lxc/debian/rootfs.hoge/etc/ディレクトリの下の、 passwd, shadow, group をホストのそれで上書きしておくと良い
でしょう*13 。
後者はコンテナ自身の名前解決の設定が目的です。 現状では、 コンテナの/etc/hosts は、 一律、
となっており、 上記の 2 行目が、 /etc/hostname と異なるため、 ユーザアカウントを作っても、 ログイン時に名前解決で時間が
掛かってしまいます。 ですので、 予め、 ホスト OS のホスト名になっている部分をコンテナのホスト名に書き換えておく必要がある
わけです。 上記の設定を終えたら、 システムコンテナを起動します。 システムコンテナの起動は、 lxc-start コマンドを使います。 一
つの環境で複数のコンテナを起動できるので、 コンテナ名の指定が必ず必要です。 コンテナ名の指定には、 オプション-n を使
います。
このまま起動させると、 現在のシェルでそのままコンテナのコンソールが表示されます。 ログインするにはその
ままコンソールログインすれば良いでしょう。 バックグラウンドで起動させるには、 -d オプションをつけ
ます。
KVM や Xen などのようにカーネルから起動させる訳ではなく、 init プロセスから起動させるので、 起動完了までに要する
時間はわずかです。
Linux コンテナのライフサイクルは他の仮想化技術と大きく異なるところはなく、 次の図の様になります。
この図での状態を遷移させるためのコマンド、 つまりコンテナを管理するためのコマンドは以下の通りです。
status コマンド 実行後の状態 備考 コンテナの起動 lxc-start STARTING, RUNNING システムコンテナ lxc-execute アプリケーションコンテナ コンテナの一時停止 lxc-freeze FROZEN コンテナの再開 lxc-unfreeze RUNNING コンテナの停止 lxc-stop STOPPING, STOPPED コンテナの再起動 lxc-restart STOPPING, STOPPED STARTING, RUNNING コンテナの作成 lxc-create STOPPED lxc-debian は内部で lxc-create を実行。 lxc-fedora, lxc-sshd なども同様。 コンテナの破棄 lxc-destroy lxc では、 コンテナのリソースを制御するために、 cgroup というカーネルの機能を使っています。 cgroup とは、 Control
group の略です。 Linux Kernel は通常プロセス単位でのリソース制御を行っていました。 cgroup を使うと、 同じ cgroup に所
属しているプロセス間でのリソースの共有ができます。 lxc では、 lxc-cgroup コマンドを用い、 コンテナのリソースの設定を
表示したり、 値をセットすることができます。
設定を変更する。 例えば、 CPU リソースの割り当てには、 cpu.shares というパラメータを用いますが、 あるコンテナに割り当てられている比
率を算出するには、 任意のコンテナの cpu.shares / 各コンテナの cpu.share の総和を計算する必要があります。 具体的
には、 現在の各コンテナの cpu リソースの割り当て設定を確認すると、
総和は 7168 で、 各コンテナは、 couchdb は約 28.6%、 他のコンテナは約 14.3% ごとの比率で CPU リソースをシェアする
ということ分かります。
コンテナ全体のリソースは? /var/local/cgroup ディレクトリ以下にある、 “xxx.yyyy” の形式をとっているのが、 cgroup で管理するリソース項目で、 こ
のディレクトリ直下はシステム全体のリソースです。 一方、 hoge/などのディレクトリがありますが、 これは各コンテナに割り
当てられているリソース項目です。 ですので、 このディレクトリを使って、 lxc 全体と各コンテナのリソースの管理を行うこと
ができます。
Linux Kernel の標準機能だけを使ったコンテナである、 Linux Containers について説明しました。 まだまだ機能的には不十
分なところもあり、 開発体制も不安なところはありますが、 特別なカーネルパッチを適用せずに試せる点では非常に気軽に使え
るのではないかと思います。
また、 lxc は libvirt のサポート対象にもなっています。 本資料を作成前に libvirt で扱えるか検証してみたと
ころ、 定義ファイルを作るところまではできたものの、 virsh でコネクトするとうまくリソースにアクセス
できないといった問題もありますが、 やることが多いのでハックするには良いネタになるのではないでしょ
うか。
iptables -t nat -A PREROUTING -d 192.168.0.1 -p tcp --dport 5984 -i br0 -j DNAT --to 192.168.0.102
8.2.5 システムコンテナの作成
$ sudo mount cgroup
--- a/lxc-debian 2009-11-30 21:22:59.000000000 +0900
+++ b/lxc-debian 2009-10-30 17:58:20.000000000 +0900
@@ -8,8 +8,8 @@
MNTFILE=
TMPMNTFILE=
UTSNAME=
-IPV4="172.20.0.21"
-GATEWAY="172.20.0.1"
+IPV4="192.168.0.101"
+GATEWAY="192.168.0.1"
MTU="1500"
# These paths are within the container so do not need to obey configure prefixes
@@ -99,14 +99,14 @@
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
-PermitRootLogin yes
+PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
-PermitEmptyPasswords yes
+PermitEmptyPasswords no
ChallengeResponseAuthentication no
EOF
}
@@ -259,8 +259,8 @@
# download a mini debian into a cache
echo "Downloading debian minimal ..."
debootstrap --verbose --variant=minbase --arch=$ARCH \
- --include ifupdown,locales,libui-dialog-perl,dialog,apache2,netbase,net-tools,iproute,openssh-server \
- lenny $CACHE/partial-$ARCH http://ftp.debian.org/debian
+ --include ifupdown,locales,libui-dialog-perl,dialog,sudo,vim-tiny,dnsutils,netbase,net-tools,iproute,openssh-server \
+ sid $CACHE/partial-$ARCH http://cdn.debian.or.jp/debian
RESULT=$?
if [ "$RESULT" != "0" ]; then
$ cd /var/cache/lxc
$ sudo bash /home/kohei/lxc-debian create
What is the name for the container ? [debian] hoge <- コンテナの名前
What hostname do you wish for this container ? [hoge] <- コンテナのホスト名
What IP address do you wish for this container ? [192.168.0.101] <- コンテナの IP アドレス
What is the gateway IP address ? [192.168.0.1] <- コンテナから見たデフォルトゲートウェイのアドレス
What is the MTU size ? [1500]
Specify the location of the rootfs [./rootfs.hoge]
Specify the location for an extra fstab file [(none)]
(snip)
Choose your architecture
1) amd64
2) i386
#? 1 <- Core 2 Duo のマシンなのでアーキテクチャは amd64 を選択。
Architecture amd64 selected
Checking cache download ...Found.
Copying rootfs ...Done.
(snip)
update-rc.d: using dependency based boot sequencing
Done.
You can run your container with the ’lxc-start -n hoge’
couchdb/
|-- cgroup
|-- config
|-- fstab
|-- init
|-- network
| ‘-- veth0
| |-- ifindex
| |-- link
| |-- mtu
| |-- name
| ‘-- up
|-- nsgroup -> /var/local/cgroup/hoge
|-- pts
|-- rootfs
| ‘-- rootfs -> /var/cache/lxc/debian/rootfs.hoge
|-- state
|-- tty
‘-- utsname
5 directories, 13 files
8.2.6 システムコンテナの起動
127.0.1.1 ホスト OS のホスト名8.3 lxc の仕組みを見てみる
8.3.1 コンテナのライフサイクル
8.3.2 リソースを制御する
cgroup の変数を表示する場合は、 “lxc-cgroup -n コンテナ名 変数名” で、 変数の値を変更するには、 “sudo lxc-cgroup
-n コンテナ名変数名 設定する値” とします。
couchdb git hoge octave w3m web
$ for i in ‘lxc-ls‘; do echo -ne $i"\t"; lxc-cgroup -n $i cpu.shares; done
couchdb 2048
git 1024
hoge 1024
octave 1024
w3m 1024
web 1024
上記の通り、 lxc-cgroup コマンドは、 コンテナを明示的に指定する必要があるので、 cgroup 管理下全体での使用率などを把握す
るには不便です。 cgroup で制御されるリソースは 8.2.5節でマウントした、 cgroup ファイルシステムからアクセスすることもでき
ます。 今回はマウントポイントを/var/local/cgroup にしているのでこのディレクトリの下を見てみると以下の様になっていま
す。
$ ls -F
couchdb/ cpuset.memory_pressure git/
cpu.shares cpuset.memory_pressure_enabled hoge/
cpuacct.stat cpuset.memory_spread_page net_cls.classid
cpuacct.usage cpuset.memory_spread_slab notify_on_release
cpuacct.usage_percpu cpuset.mems octave/
cpuset.cpu_exclusive cpuset.sched_load_balance release_agent
cpuset.cpus cpuset.sched_relax_domain_level tasks
cpuset.mem_exclusive devices.allow w3m/
cpuset.mem_hardwall devices.deny web/
cpuset.memory_migrate devices.list
8.4 まとめ
8.5 参考文献
____________________________________________________________________________________________
http://lxc.sourceforge.net/lxc.html
http://www.ibm.com/developerworks/jp/linux/library/l-lxc-containers/*16
http://www.linux-foundation.jp/uploads/seminar20081119/CgroupMemcgMaster.pdf Debian 勉強会資料
2009 年12 月12 日 初版第1 刷発行
東 京 エ リ ア
Debian 勉強会 (編集・印刷・発行)
__________________________