あけましておめでとうございます.@r_takaishiです.今年も餡餅雑煮を食べました.一年元気に過ごしていきたいですね.さて,2012年一発目の記事は和訳記事です.本記事はVirtualization in the EC2 cloud using LXCの和訳です.StackatoとLXCによるクラウドにおけるセキュリティ(和訳) で参照されている記事で,後日和訳を公開すると書いていたのですが遅くなってしまいました.CloudFoundryで使われているLXCの使い方に関する内容で,これを読めばLXCでどのような事ができるのかは大体分かるのではないかと思います.
それでは以下和訳です.
–
EC2は既に(準)仮想化環境であり, それはあなたの仮想環境(KVM/VirtualBox/qemu)を動かす事がほぼ不可能ということです.しかしながら,Linuxは最近になってカーネルに新しい機能を導入しました.それはcgroupと呼ばれ,カーネル内のプロセスを互いに隔離する方法を提供します.プロジェクトはこの新しい技術を中心に構成され,それは非常に薄く,速く,セキュアな疑似仮想化です.それはLinuX Containersを省略してLXCと呼ばれています.そして,これはEC2で完璧に動作します.
方法は以下の通り.
あなたは最新のLinux AMI(できればカーネル2.6.35かそれ以上)が欲しいとします.私はUbuntuServer11.04を使っていて,以下の説明はこれに準拠したものです.他のディストリビューションでは保証できません,しかし,他のディストリビューション用に簡単に移植できるでしょう.Ubuntuは,良い既製のAMIイメージがあり,カーネルが最初からLXCに対応していて,EC2でホストされたソフトウェアリポジトリを持っている(システムの更新を非常に高速に行えますね)ためEC2とLXCとの相性が良いです.また,動かすインスタンスのタイプはt1.micro(microインスタンス)で十分です(テストの際に選択する私の武器です).
EC2サーバにSSHでログインします.あなたは以下の全ての手順をrootで行う必要があるので,rootになるため次のコマンドを実行しましょう.
sudo -i
そうでなければ,あなたは全てのコマンドの先頭に’sudo’をつけなくてはいけません.
さて,ここでいくつかのパッケージをインストールすつ必要があります:
apt-get update && apt-get install lxc debootstrap bridge-utils dnsmasq
あなたがインストールするパッケージですが,lxcは,まぁlxcです.debootstrapはディレクトリ内に最小のUbuntuインストールを作成する(すぐに行います)ためのユーティリティです.bridge-utilsはLinux上で我々がコンテナにアクセスするネットワークを提供するネットワークブリッジを作成するための一連のユーティリティです.dnsmasqはコンテナにロー
カルネットワーク内で自身を認識させるためのDNS/DHCPサーバです.
さて,lxc-configを実行して全てのテストをパスすることを確認します(あなたがUbuntu Server 11.04を使っているなら全てパスするはずです).
ノート:これは重要です!EBSを使ったインスタンスでも,外部からのコマンドのほとんどは再起動しても永続化されていないことに注意してください.これらはインメモリな変更のため,マシンをシャットダウンすると消えてしまいます.インスタンスのバックアップをもってくるなら,もう一度実行する必要があり,そうでなければうまくいかないでしょう.回避する方法はいくつかあります:iptablesのルールと/etc/resolve.confはinitスクリプトから設定でき,sysctrlはsysctrl.confで設定でき,マウントは/etc/fstabで指定,brctlは/etc/network/interfacesで設定できます;しかし,このガイドの目的のため(私は個人的にはEBSによるインスタンスを使いません),我々はインスタンスストレージ(設定は再起動で失われます)を使うと仮定します.
cgroupの情報を扱う場所をシステム上に作成する必要があります(LXCが動く必要があります).私は単純に/cgroupを使います.さぁ,cgroup環境をマウントしましょう.
mkdir /cgroup mount -t cgroup none /cgroup
(もし再起動した後もcgroupをマウントしたままにしておきたいのなら,「echo “none /cgroup cgroup defaults 0 0″ >> /etc/fstab」を実行します.)
コンテナがネットワーク/インターネットに接続するためのネットワークブリッジを作成しましょう.以下を実行します.
brctl addbr br0 brctl setfd br0 0 ifconfig br0 192.168.3.1 up
2番目のコマンドですが,このチュートリアルではコンテナのネットワークに192.163.3.*を使っています.もしあなたが別のサブネット(192.168.x.*)を使いたいのなら,自由に変更して構いませんが,この記事中では同様の変更を大量にする箇所があるため,3.*のまま進めることを推奨します.
コンテナがインターネットに届くように,いくつかのシステムルールを設定する必要があります:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sysctl -w net.ipv4.ip_forward=1
新しく作成したブリッジにDHCP/DNSを設定します./etc/dnsmasq.confを開き,編集します.設定ファイルが以下のようになるよう,必要な行のコメントを外します:
domain-needed
bogus-priv
interface = br0
listen-address = 127.0.0.1
listen-address = 192.168.3.1
expand-hosts
domain = containers
dhcp-range = 192.168.3.50,192.168.3.200,1h
DNSがローカルで適切に解決すようにするため,/etc/dhcp3/dhclient.confを編集する必要があります.ファイル先頭に以下を追加します:
prepend domain-name-servers 127.0.0.1;
prepend domain-search “containers.”;
(“containers”の後に”.”を書くのを忘れないように.これはtypoではありません!)
dhclientが/etc/resolv.confを再生成できるようにDHCPリースを更新する必要があります.
dhclient3 -e IF_METRIC=100 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp3/dhclient.eth0.leases eth0
dnsmasqを再起動し,新しい設定を読み込ませましょう.
service dnsmasq restart
次に,コンテナの中身となる環境を作成する必要があります.lxc-ubuntuという,lxcと一緒に使うスクリプトが付属しています.しかし,環境を動かすために若干の微調整が必要です.私は調整済みのスクリプトを公開しているので,これを使います.以下を実行します:
wget -O lxc-ubuntu http://bit.ly/ec2ubuntulxc chmod +x lxc-ubuntu
(もし,自分で調整したいのなら,/usr/lib/lxc/templates/lxc-ubuntuをコピーしてきて,ホストネーム,EC2のUbuntuミラーを変更し,sshdのランレベルを修正,そしてLXCのネットワーク設定をDHCP vethにします(設定の参考に私のスクリプトを見てください).)
新規コンテナを作成しましょう.
./lxc-ubuntu -p /mnt/vm0 -n vm0
スクリプトが終了するまで待つと,/mnt/vm0にコンテナがセットアップされます.試してみましょう!
lxc-start -n vm0
ユーザ名とパスワードにrootを入力してログインします.Googleにピンを打ってみましょう:
ping www.google.com
動いたなら,インターネットの設定はできています!別の事を試してみましょう(ホストではなく,VMの中で実行してください!)
poweroff (Vmをシャットダウンし,ホストに戻ります) lxc-start -n vm0 -d (VMをデーモンモードで実行します)
VMが動いているか確認するには次のようにします:
lxc-info -n vm0
(RUNNNINGと表示されるはずです).ネットワークを試すなら,VMへピンを打ってみましょう(すぐには動かない可能性があります.その場合,少し待つ必要があるかもしれません):
ping vm0 ssh root@vm0
これら2つが動いたら,VMはDNSで解決され,ホストネームでアクセスすることができます.
新しくVMを作成する
別のVMを作成するには,単純にこうします:
./lxc-ubuntu -n vm1 -p /mnt/vm1
パッケージは再ダウンロードされず,コマンドはすぐに終了します.
既存のVMを終了する
VMのを終了したい場合,あなたはまず次のコマンドを実行する必要があります.
cp -r /mnt/vm0 /mnt/vm1
そして,/mnt/vm1/configを編集し,vm0と書かれた箇所を全てvm1に変更します.次に/mnt/vm1/fstabと同じ事をします.そして,/mnt/vm1/rootfs/etc/hostnameを編集し,hostnameをvm1にします.最後に次のコマンドを実行します:
lxc-create -n vm1 -f /mnt/vm1/config
VMが起動したら,pingを打ったりsshでアクセスすることができます:
ping vm1 ssh root@vm1
できないなら,lxc-consoleでVMにログインし,接続を確認してください.全てのインスタンスはbr0だけしか必要としませんが,必要に応じて複数作成することも可能であることを覚えておいてください.
コンテナの内部でサービスを実行する
VMの外(他のEC2やEC2の外)からアクセス可能なウェブサーバが欲しいと思います.VMへポートフォワードするために次のコマンドを実行する必要があります:
iptables -t nat -A PREROUTING -p tcp --dport <port on host> -j DNAT --to-destination <hostname of VM>:<port on VM>
コンテナのハイバネート
コンテナを”ハイバネート”する(後で瞬間的に復元するために現在の状態(動いているプロセス)を保存します)にはこうします:
lxc-freeze -n vm0
そして,
lxc-unfreeze -n vm0
こうすることで復元できます.
コンテナへ追加パッケージをインストールする
コンテナは,もう一つのUbuntuシステムのようなものです.そのため,
apt-get update apt-get install <whatever>
問題なく動きます.
リソース制限の設定
LXCの利点の一つがコンテナ毎に使用できるリソース量を設定できることです.設定可能なリソースについて調べてみましょう:
CPU
LXCでのCPUリソースの制限を行う方法には2種類あります.マルチコアシステムでは,コンテナ毎に異なるコアを割り当てることができます(次のテキストをコンテナの設定ファイルに追加します.設定ファイルは/mnt/vm0/configかそれと同じような名前です.):
lxc.cgroup.cpuset.cpus = 0 (コンテナに最初のCPUを割り当てる)
or
lxc.cgroup.cpuset.cpus = 0,2,3 (コンテナに1番目,3番目,4番目のCPUを割り当てる)
別の方法(これは私にとってより意味があります)はスケジューラを使うことです.’このコンテナはこのコンテナの3倍のCPUを割り当てたい’という値を使うことができます.例えば,次のようにします:
lxc.cgroup.cpu.shares = 2048
コンテナに与えられるデフォルトの設定は2倍(1024)です.
RAM
メモリを制限するには,次のように設定します:
lxc.cgroup.memory.limit_in_bytes = 256M
(あなたが欲しいメモリ量に256Mを書き換えてください).
スワップの値も設定できます:
lxc.cgroup.memory.memsw.limit_in_bytes = 1G
ハードディスク
これには正式な手段がありません,あなた次第です.あなたはLVMを使うことができ(EC2で?),またファイル上にファイルシステムを作成することができ,(“if=/dev/zero of=somefile.img bs=4GB count=1 &&mkfs.ext3 somefile.img && mount -o loop somefile.img/mnt/vm0/rootfs”とします)そしてそれをrootfsとしてマウントすることでスペースを制限できます.
ネットワーク帯域
コンテナ毎にネットワーク帯域を制限するには,tcユーティリティを使います.この方法を使う場合,コンテナ毎にブリッジを分ける(br0,br1)必要があることを覚えておいてください.その場合,VMの設定のブリッジを修正することも忘れないようにしてください.
最後に
EC2環境でLXCを使う方法について基本的な部分をカバーできたと思います.LXCは素晴しい技術で,できることは無限大に広がります.
さらに読む:主なLXCのウェブサイトとして,LXC HOWTOやIBMのチュートリアルがあります.
ノート:不注意にネットワークの再構成を行うと接続が切れる可能性があるため,他のLXCのガイドに従う時に,EC2でのネットワークの設定(ネットワークの再起動や/etc/network/interfacesの変更)は慎重に行ってください.あなたとインスタンス間の接続が切断される(SSH接続が切れます)と,あなたはインスタンスを失うことになります.この解説では私はテストされたものを提供していて,これはEC2との接続を切断しません.