下記の記事で Docker というものを知って少し気になったのですが、Docker を試してみる前に LXC がどんなものなのか試してみたほうがいいかなーと思ったので、手元の CentOS6 で使ってみました。
他のブログやWikiから切り貼りしただけですが、自分で見返したときに意味がわかるようにそれなりに説明も書きました。
参考にしたサイト
- http://tenforward.github.io/lxc-doc-ja/lxc.conf.html
- http://wiki.1tux.org/wiki/Centos6/Installation/Minimal_installation_using_yum
- http://nullpopopo.blogcube.info/2013/06/lxc_on_sakuravps.html
- http://d.hatena.ne.jp/enakai00/20110529/1306658627
前提
LXC のインストールとホストの設定
epel と rpmforge を追加
rpmforge に lxc の rpm があるようなので rpmforge を追加します。
$ yum localinstall -y http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
また、lxc-templates が依存している debootstrap が epel にあるので、これも追加します。
$ yum localinstall -y http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
どちらもデフォルトで無効にしておきます。
$ sed -i.bak '/^enabled/c enabled=0' /etc/yum.repos.d/epel.repo $ sed -i.bak '/^enabled/c enabled=0' /etc/yum.repos.d/rpmforge.repo
LXC をインストール
yum で LXC をインストールします。
$ yum --enablerepo=epel,rpmforge -y install lxc lxc-templates lxc-doc lxc-libs
ブリッジ作成
ホスト~ゲスト間のためのブリッジを作成します。NAT を使うようにするので実 I/F には繋ぎません。
$ cat > /etc/sysconfig/network-scripts/ifcfg-lxcbr0 <<EOS DEVICE=lxcbr0 ONBOOT=yes TYPE=Bridge BOOTPROTO=none IPADDR=10.12.128.1 PREFIX=24 DEFROUTE=no EOS $ ifup lxcbr0
cgroup をマウントします。
$ cat >> /etc/fstab <<EOS cgroup /cgroup cgroup defaults 0 0 EOS $ mkdir -p /cgroup $ mount -a
dnsmasq インストール
ゲストの IP を DHCP で割り当てるために dnsmasq をインストールします。固定で割り当てるなら必要ありません。
$ yum install -y dnsmasq $ mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig $ cat > /etc/dnsmasq.conf <<EOS domain-needed bogus-priv interface=lxcbr0 listen-address=127.0.0.1 listen-address=10.12.128.1 expand-hosts domain=lxc dhcp-range=10.12.128.100,10.12.128.200,1h EOS $ service dnsmasq start $ chkconfig dnsmasq on
IP Forwarding と NAT
ゲスト→ホスト で NAT するために IP Forwarding を有効にして iptables で NAT を設定します。 ホストの実 I/F が DHCP だったので MASQUERADE です。
$ sed -i.bak '/^net\.ipv4\.ip_forward/c net.ipv4.ip_forward = 1' /etc/sysctl.conf $ sysctl -p $ service iptables start $ chkconfig iptables on $ iptables -t nat -A POSTROUTING -s 10.12.128.0/24 -o eth0 -j MASQUERADE $ service iptables save
ゲストの rootfs 作成
ゲストの rootfs を作成します。
作業用のディレクトリとして /t を使います。
$ mkdir /t $ cd /t
chroot で yum を動かすために必要な最小限のパッケージをインストールします。
--installroot=/t
で /t をルートとしてインストールします--releasever=6
がないと $releasever が未定義 とか言われてエラーになります
$ yum --installroot=/t --releasever=6 -y install centos-release rootfiles yum
resolv.conf をコピーします。
$ cp /etc/resolv.conf /t/etc/
chroot します。
$ chroot /t
デバイスファイルを作成します。
$ rm -f /dev/null $ mknod -m 666 /dev/null c 1 3 $ mknod -m 666 /dev/zero c 1 5 $ mknod -m 666 /dev/urandom c 1 9 $ ln -s /dev/urandom /dev/random $ mknod -m 600 /dev/console c 5 1 $ mknod -m 660 /dev/tty1 c 4 1 $ chown root:tty /dev/tty1 $ mkdir -p /dev/shm $ chmod 1777 /dev/shm $ mkdir -p /dev/pts $ chmod 755 /dev/pts
その他に必要そうなパッケージをインストールします。
$ yum -y install dhclient passwd openssh-server
/etc/sysconfig/network を作ります。
$ cat > /etc/sysconfig/network <<EOS NETWORKING=yes HOSTNAME=localhost EOS
I/F 設定を作ります。
$ cat > /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOS DEVICE=eth0 ONBOOT=yes TYPE=Ethernet BOOTPROTO=dhcp DEFROUTE=yes PEERDNS=yes PEERNTP=no EOS
/etc/fstab を作ります。これはコンテナの起動時にマウントされます。
$ cat > /etc/fstab <<EOS /dev/root / rootfs defaults 0 0 tmpfs /dev/shm tmpfs nosuid,nodev 0 0 EOS
lxc-sysinit.conf を作ります。コンテナの起動時に init から upstart で実行されます。
$ cat > /etc/init/lxc-sysinit.conf <<EOS start on startup env container pre-start script if [ "x$container" != "xlxc" -a "x$container" != "xlibvirt" ]; then stop; fi telinit 3 initctl start tty TTY=console exit 0; end script EOS
root のパスワードを設定します。
$ passwd
udev-post はたぶん不要なので off にします。
$ chkconfig udev-post off
chroot を抜けます。
$ exit
作成した rootfs をゲストの作成時に使いまわすために tar で固めます。
$ cd /t
$ tar cvzf /centos6-lxc-root.tgz .
ゲストの作成
ゲストのディレクトリを作成します。この位置に作成すれば lxc-create しなくても認識されます。
$ mkdir -p /var/lib/lxc/vm01/rootfs
rootfs のアーカイブを展開します。
$ cd /var/lib/lxc/vm01/rootfs $ tar xvzf /centos6-lxc-root.tgz --numeric-owner
lxc の config を作成します。cgroup でリソース制限ができるようですがとりあえず必要最小限にします。
$ cat > /var/lib/lxc/vm01/config <<EOS lxc.utsname = vm01 lxc.network.type = veth lxc.network.flags = up lxc.network.link = lxcbr0 lxc.network.name = eth0 lxc.network.veth.pair = veth-vm01 lxc.tty = 6 lxc.pts = 1024 lxc.rootfs = /var/lib/lxc/vm01/rootfs lxc.mount = /var/lib/lxc/vm01/fstab lxc.cap.drop = sys_module mac_admin EOS
fstab を作成します。これはたぶんゲストの init の前の chroot の前にマウントされます。
$ cat > /var/lib/lxc/vm01/fstab <<EOS proc /var/lib/lxc/vm01/rootfs/proc proc nodev,noexec,nosuid 0 0 sysfs /var/lib/lxc/vm01/rootfs/sys sysfs defaults 0 0 EOS
ゲストの起動
ゲストの準備はできたので起動してみます。-d
はデーモンとして起動するオプションです。
-o
でログの出力先の指定、-l
でログレベルの指定もできます。
$ lxc-start -n vm01 -d
ゲストのコンソールに接続します。
$ lxc-console -n vm01
ログインのプロンプトが表示されるので、↑の方で設定した root のパスワードでログインします。
コンソールからの切断は Ctrl+a → q です。
SSH で接続する
ホストの dnsmasq が DHCP でゲストに割り当てた IP アドレスを確認します。
$ cat /var/lib/dnsmasq/dnsmasq.leases
あるいは messages から探します。
$ grep dnsmasq-dhcp /var/log/messages
SSH でゲストにログインします。
$ ssh root@10.12.128.197
ゲストの停止
$ lxc-stop -n vm01
疑問点
- lxc の config の lxc.mount がなくでも動作したけど必要?
- proc や sysfs はなくてもマウントされている
- rootfs 以外のホストのディレクトリをゲストに見せたいときに使うのでは?
- ゲストの中の fstab がなくても動作したけど必要?
- rootfs はなくてもマウントされている
- tmpfs もなくてもマウントされている
- しかもゲストの中の fstab に書いていると2重にマウントされているように見える
lxc-start -n vm01
としてもブートのメッセージが見えない- lxc-sysinit.conf を弄ると表示されるようになった
- が、コンソールにログインプロンプトが表示されなくなった
lxc-stop -n vm01
で止めると次回起動時にネットワークとかが自動で始動しない?- /var/lock/subsys/ にいろいろ残るため?
- lxc-sysinit.conf で消し去る?