FreeBSD - The Power To Serve

CentOS in a FreeBSD jail howtoにて興味深いテクニックが発表された。FreeBSD Jailの中身をCentOS 5.5にすることで、FreeBSDホストサーバの中にいくつものCentOS 5.5を稼働させるというもの。設定方法はRunning CentOS 5.5 in a Jailにまとまっている。

JailでCentOS 5.5を動作させようとした動機は、より軽量で柔軟、スケーラビリティの高い仮想化機能が必要だったためだと説明がある。VMwareやXenでの仮想化や、VirtualBoxによる仮想化は機能はするものの消費するリソースが多すぎ、さらにスケールが小さいという。理想的にはJailによる仮想化とZFSによる柔軟なボリューム管理とファイルシステム管理、またはZFSを活用したスナップショットやバックアップ、ロールバックなどを実施したいという寸法だ。

FreeBSDのLinuxバイナリ互換機能はLinuxバイナリをほとんどネイティブに実行する。FreeBSDバイナリを実行する場合と性能上の違いがあまりない。原則的にはJailの内部に必要なLinuxディストリビューションを用意すれば、FreeBSDカーネルを使ったLinuxディストリビューションが動作する。Running CentOS 5.5 in a Jailはこれを実際にやってみたという内容になっている。実用利用を目指して作業しているところが興味を引く。

ここで構築手順を簡単に紹介する。事前条件は次のとおり。

  • FreeBSD 9-CURRENT、またはlinprocfs向けのパッチがあたった8系を使っていること(ここでは9-CURRENTを使ってテストを実施)
  • Linuxバイナリ互換機能が有効になっている、およびemulators/linux_base-f10をインストール
  • archivers/rpmではなくarchivers/rpm4をインストール (pkg_delete rpm-3.0.6_15 ; cd /usr/ports/archivers/rpm4/; make install clean)

説明の便宜上、利用するパスを次のように定める。

  • /home/jails/ - Jailを配置するディレクトリ
  • /home/jails/centos/ - CentOSディストリビューションをインストールするJailディレクトリ
  • /home/jails/distfiles/ - 必要になるファイルをあらかじめ保存しておくディレクトリ

ZFSでの用意手順は例えば次のとおり。

zfs create tank/jails
zfs create tank/jails/centos
zfs create tank/jails/distfiles
mkdir /home/jails
mkdir /home/jails/centos
mkdir /home/jails/distfiles
zfs set mountpoint=/home/jails tank/jails
zfs set mountpoint=/home/jails/centos tank/jails/centos
zfs set mountpoint=/home/jails/distfiles tank/jails/distfiles

作業に必要になるファイルはRunning CentOS 5.5 in a Jailからダウンロードして/home/jails/distfiles/にコピーしておく。

# ls /home/jails/distfiles/
CentOS-5.5-i386-bin-DVD.iso         initd_syslog.patch
centos5.5_bootstrap_rpm_list.txt    squashfs-tools-3.4-1.i386.rpm
initd_halt.patch

次のように作業して、必要になるCentOS 5.5の内容物を/home/jails/centos/以下にインストール。

cd /compat/linux
rpm2cpio - < /home/jails/distfiles/squashfs-tools-3.4-1.i386.rpm | cpio -id
mdconfig -a -t vnode -f /home/jails/distfiles/CentOS-5.5-i386-bin-DVD.iso
mkdir /media/centos
mount -t cd9660 /dev/md0 /media/centos
cd /home/jails
/compat/linux/usr/sbin/unsquashfs -dest centos-stage2 /media/centos/images/stage2.img
cd centos-stage2
mkdir dist
umount /dev/md0
mount -t cd9660 /dev/md0 /home/jails/centos-stage2/dist
mkdir stage
zfs set mountpoint=/home/jails/centos-stage2/stage tank/jails/centos
cp /home/jails/distfiles/centos5.5_bootstrap_rpm_list.txt /home/jails/centos-stage2/
chroot /home/jails/centos-stage2 /usr/bin/bash
  mkdir -p /stage/var/lib/rpm
  rpm --root /stage --initdb
  mkdir bootstrap
  for rpm in `cat /centos5.5_bootstrap_rpm_list.txt`; do
    cp /dist/CentOS/${rpm} bootstrap
  done
  cd bootstrap
  rpm --root /stage -Uvh *.rpm
  exit
umount /dev/md0
mdconfig -d -u 0

インストールが完了したので、最初に用意したパスへマウントし直し。

zfs set mountpoint=/home/jails/centos tank/jails/cents

CentOSのディレクトリをJailで使用するために/etc/rc.confに次の設定を追加。NIC名、IPアドレス、ホスト名は適宜書き換える必要あり。

jail_enable="YES"
jail_list="centos"
jail_sysvipc_allow="YES"
jail_interface="re0"
jail_devfs_enable="YES"
jail_exec_start="/bin/sh /etc/rc.d/rc 3"
jail_exec_stop="/bin/sh /etc/rc.d/rc 0"
jail_centos_rootdir="/home/jails/centos"
jail_centos_hostname="centos.localhost"
jail_centos_ip="192.168.1.30"

ContOSの領域にプロセスファイルシステムがマウントされるように/etc/fstabに次の設定を追加。

linprocfs       /home/jails/centos/proc linprocfs       rw,late 0       0

CentOSのsyslogを次のように編集。

--- /home/jails/centos/etc/sysconfig/syslog.org 2010-10-26 17:54:46.555861780 +0900
+++ /home/jails/centos/etc/sysconfig/syslog     2010-10-26 18:00:28.248865500 +0900
@@ -3,7 +3,7 @@
 # -r enables logging from remote machines
 # -x disables DNS lookups on messages recieved with -r
 # See syslogd(8) for more details
-SYSLOGD_OPTIONS="-m 0"
+SYSLOGD_OPTIONS="-m 0 -p /var/run/log"
 # Options to klogd
 # -2 prints all kernel oops messages twice; once for klogd to decode, and
 #    once for processing with 'ksymoops'

ユーザやサービスなどCentOS内のもろもろの設定を変更。

echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > /home/jails/centos/etc/master.passwd
pwd_mkdb -d /home/jails/centos/tmp -p /home/jails/centos/etc/master.passwd 
cd /home/jails/centos/tmp/
mv master.passwd pwd.db spwd.db ../etc
cp /etc/resolv.conf /home/jails/centos/etc
echo "NETWORKING=yes" >> /home/jails/centos/etc/sysconfig/network
echo "HOSTNAME=centos.localhost" >> /home/jails/centos/etc/sysconfig/network
echo "192.168.1.30 localhost centos centos.localhost" >> /home/jails/centos/etc/hosts
chroot /home/jails/centos /bin/bash
  cd /etc
  pwconv
  grpconv
  passwd root
  touch /etc/fstab
  touch /etc/mtab
  cd /sbin
  mv consoletype consoletype.orig
  ln -s /bin/true consoletype
  cd /bin
  mv umount umount.prev
  ln -s /bin/true umount
  chkconfig --list
  chkconfig gpm off
  chkconfig lvm2-monitor off
  chkconfig mcstrans off
  chkconfig netfs off
  chkconfig network off
  chkconfig rawdevices off
exit
cd /home/jails/centos
patch < /home/jails/distfiles/initd_syslog.patch
patch < /home/jails/distfiles/initd_halt.patch

CentOS in Jailを起動。

/etc/rc.d/jail start centos

jlsでJailが動作しているかどうか確認し、jexecでJail内に入って操作を実施してみる。

% uname
FreeBSD
% uname -a
FreeBSD parancell.ongs.co.jp 9.0-CURRENT FreeBSD 9.0-CURRENT #6 r213257: Thu Sep 30 10:30:06 JST 2010     root@parancell.ongs.co.jp:/usr/obj/usr/src/sys/PARANCELL  amd64
% jls
   JID  IP Address      Hostname                      Path
     1  192.168.1.30    centos.localhost              /home/jails/centos
% jexec 1 bash
# uname
Linux
# uname -a
Linux centos.localhost 2.6.16 FreeBSD 9.0-CURRENT #6 r213257: Thu Sep 30 10:30:06 JST 2010 i686 i686 i386 GNU/Linux
# ps auxww
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     76715  0.0  0.0   2172   904 ?        R+   06:45   0:00 ps auxww
root     71863  0.0  0.0   2496  1532 ?        S+   06:33   0:00 bash
root      1759  0.0  0.0   3356  1356 ?        Ss   06:07   0:00 crond
smmsp     1750  0.0  0.0   8324  3372 ?        Ss   06:07   0:00 /usr/sbin/sendmail -L sm-msp-queue -Ac -q1h
root      1743  0.0  0.0   9340  3576 ?        Ss   06:07   0:00 /usr/sbin/sendmail -bd -q1h
root      1713  0.0  0.0   1892   732 ?        Ss   06:07   0:00 syslogd -m 0 -p /var/run/log
#

それぞれの作業の意味や、設定している内容、なぜその設定が必要なのかはRunning CentOS 5.5 in a Jailに詳しくまとまっている。追作業をする場合にはもとのドキュメントを参考に作業を実施した方がいい。

FreeBSDバイナリ互換機能はLinuxカーネル2.6.16相当の機能を提供している。ただし、システムコールが大幅に異なるものと、機能的にFreeBSDカーネルが提供していないものはまだ実装されていない。このためすべてのアプリケーションがそのままCentOS in Jailで利用できるわけではない。

しかし、FreeBSDをベースのコンテナとして採用し、そこでCentOSを複数インスタンスとして可動させるというのは興味深い取り組みといえる。1台のサーバでいくつものCentOSをホスティングして提供でき、バックエンドとなるストレージにZFSがそのまま活用できるという便利さがある。