Arch Linux上のLXCにArch Linuxを入れ、systemdとsshが正しく動作するか試し
てみる。
大まかな流れは、
完成時のネットワーク構成は、以下の図のようになる。
- ネットワーク設定
- ブリッジインターフェースの作成
- IP Masqueradeの設定
- コンテナの作成
- コンテナ内システムのbootstrap
- コンテナ内の設定
- コンテナ設定ファイルの作成
- コンテナの起動と終了
完成時のネットワーク構成は、以下の図のようになる。
ホスト側ブリッジインターフェースの設定
LXCのvethネットワークを束ねるブリッジインターフェース(br0)を作成する。
ブリッジインターフェースの作成とアドレスの割当にはipコマンドを用いる。
miku@host% sudo ip link add br0 type bridge miku@host% sudo ip link set br0 up miku@host% sudo ip address add 10.3.93.1/24 dev br0毎度手動でインターフェース設定を行うのは面倒なので、netcfgの設定を行っ ておく。まずは、/etc/network.d/examples/bridgeを参考に /etc/network.d/bridge0を記述する。
INTERFACE="br0" CONNECTION="bridge" DESCRIPTION="Hatsune Bridge connection" BRIDGE_INTERFACES="" IP="static" ADDR="10.3.93.1" NETMASK="24"最後に、systemctlでnetcfg@bridge0がシステム起動時に実行されるよう設定 する。
miku@host% sudo systemctl enable netcfg@bridge0.service一時的に手動でnetcfgを起動することもできる。
miku@host% sudo systemctl start netcfg@bridge0.service
IP Masqueradeの設定
LXCコンテナ側から外部ネットワークにアクセスできるよう、IP Masqueradeを
設定する。まず、IP Forwardingを有効である必要があるため、
/etc/sysctl.confのnet.ipv4.ip_forwardを1に設定する。
次に、iptablesにて10.3.93.0/24から外部ネットワークに接続されたネットワー クインターフェース(enp2s0)へのIP Masqueradeを設定する。
net.ipv4.ip_forward = 1手動で一時的に有効にするには、"sudo sysctl net.ipv4.ip_forward=1"でよ い。
次に、iptablesにて10.3.93.0/24から外部ネットワークに接続されたネットワー クインターフェース(enp2s0)へのIP Masqueradeを設定する。
miku@host% sudo iptables -t nat -A POSTROUTING \ > -s 10.3.93.0/24 -o enp2s0 -j MASQUERADEこの時点のiptablesの状態をiptables-saveコマンドでdumpし、それをそのま まiptablesの恒久的なルールとして利用する。 このルールファイルを置くべきパスは、/etc/conf.d/iptablesに "IPTABLES_CONF=/etc/iptables/iptables.rules"として定義されている。
miku@host% sudo sh -c 'iptables-save > /etc/iptables/iptables.rules'最後に、システム起動時にこのルールが適用されるようにsystemdを設定する。
miku@host% sudo systemctl enable iptables.service
bootstrap
Arch Linuxのrootfsの構築は、Arch LinuxのLiveCDからインストールする際と
同様にarch-install-scriptsのpacstrapコマンドを用いる。合わせて、lxcパッ
ケージとiproute2パッケージを導入しておく。
miku@host% sudo pacman -S lxc arch-install-scripts iproute2/lxc/arch/rootfs以下に環境を作成する場合の操作は以下のようになる。 Arch LinuxのLXCテンプレートも存在するのだが、Arch Linux側の仕様がよく 変わり使い物にならない(すぐ使い物にならなくなる)ため、pacstrapを直接利 用する。
miku@host% sudo mkdir -m 0755 /var/lib/lxc/arch/rootfs miku@host% sudo pacstrap -i -d /var/lib/lxc/arch/rootfs base opensshbaseパッケージグループを導入する際には、カーネルパッケージ等LXCコンテ ナ内に必要ないパッケージも多数含まれるので、必要に応じて除外する。
:: There are 52 members in group base: :: Repository core 1) bash 2) bzip2 3) coreutils 4) cronie 5) cryptsetup 6) device-mapper 7) dhcpcd 8) diffutils 9) e2fsprogs 10) file 11) filesystem 12) findutils 13) gawk 14) gcc-libs 15) gettext 16) glibc 17) grep 18) gzip 19) heirloom-mailx 20) inetutils 21) iproute2 22) iputils 23) jfsutils 24) less 25) licenses 26) linux 27) logrotate 28) lvm2 29) man-db 30) man-pages 31) mdadm 32) nano 33) netcfg 34) pacman 35) pciutils 36) pcmciautils 37) perl 38) ppp 39) procps-ng 40) psmisc 41) reiserfsprogs 42) sed 43) shadow 44) sysfsutils 45) systemd-sysvcompat 46) tar 47) texinfo 48) usbutils 49) util-linux 50) vi 51) which 52) xfsprogsLXCパッケージのデフォルトでは各コンテナは/var/lib/lxc以下に置かれるの だが、パスが長くて面倒だという場合は以下のようにシンボリックリンクを張っ ておく。(LXC側で設定を変更することもできるが、lxcパッケージ側で /var/lib/lxcにハードコートされているものが存在するようでエラーとなるた め)
miku@host% sudo ln -s /var/lib/lxc /lxc
コンテナ内の設定
コンテナを起動しssh経由にてログインする際に必要な設定を行う。
sshdの有効化とユーザアカウントの設定が必須で、必要に応じてロケール等の
設定を行う。
miku@host% sudo chroot /var/lib/lxc/arch/rootfs /bin/bash root@host(chroot)# ln -s /usr/lib/systemd/system/sshd.service \ > /etc/systemd/system/multi-user.target.wants/sshd.service root@host(chroot)# passwd Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully root@host(chroot)# groupadd -g 3939 miku root@host(chroot)# useradd -g miku -u 3939 -s /bin/bash -m miku root@host(chroot)# passwd miku Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully root@host(chroot)# exitデバイスノードの管理はsystemd-udevdが行うため、後述するLXCのconfigでの 許可ルール設定のみ注意すればよい。また、/tmpのtmpfsや/devのdevtmpfs、 /sysのsysfs、/procのprocfs等もsystemdが自動でマウントを行うため、LXCの configやfstabへの記述は特に必要ない。
コンテナ設定ファイルの作成
今回設定するコンテナの設定ファイルは、"/var/lib/lxc/arch/config"である。
ここでは、コンテナに割り当てられるネットワークとファイルシステム、デバ
イスのルールについて定義を行う。
設定ファイルの詳細については、lxc.conf(5)や/usr/share/doc/lxc/examples
以下のファイル、デバイス番号の一覧は以下のドキュメントを参照。
http://www.kernel.org/pub/linux/docs/device-list/devices.txt
# ホスト名とネットワークの設定 lxc.utsname = arch lxc.network.type = veth lxc.network.name = eth0 lxc.network.flags = up lxc.network.link = br0 lxc.network.ipv4 = 10.3.93.11/24 lxc.network.ipv4.gateway = 10.3.93.1 # ファイルシステムの設定 lxc.rootfs = /var/lib/lxc/arch/rootfs # デバイスの設定 lxc.pts = 1024 lxc.tty = 4 # deny all devices lxc.cgroup.devices.deny = a # /dev/tty0..3 lxc.cgroup.devices.allow = c 4:0 rwm lxc.cgroup.devices.allow = c 4:1 rwm lxc.cgroup.devices.allow = c 4:2 rwm lxc.cgroup.devices.allow = c 4:3 rwm # /dev/tty lxc.cgroup.devices.allow = c 5:0 rwm # /dev/console lxc.cgroup.devices.allow = c 5:1 rwm # /dev/ptmx lxc.cgroup.devices.allow = c 5:2 rwm # /dev/null lxc.cgroup.devices.allow = c 1:3 rwm # /dev/zero lxc.cgroup.devices.allow = c 1:5 rwm # /dev/random lxc.cgroup.devices.allow = c 1:8 rwm # /dev/urandom lxc.cgroup.devices.allow = c 1:9 rwm # /dev/pts/* lxc.cgroup.devices.allow = c 136:* rwm # /dev/rtc lxc.cgroup.devices.allow = c 254:0 rwm最終的に許可されたデバイスの一覧は "/sys/fs/cgroup/devices/lxc/コンテナ名/devices.list" から参照できる。
コンテナ内のArch Linuxの起動と終了
コンテナ内のinitの起動にはlxc-startを用いる。このシステムの場合はコン
テナ名がarch、コマンドは/usr/lib/systemd/systemdとなる。
早速起動した所、pivot_root(2)が失敗する問題に遭遇した。
早速起動した所、pivot_root(2)が失敗する問題に遭遇した。
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd lxc-start: Invalid argument - pivot_root syscall failed lxc-start: failed to setup pivot root lxc-start: failed to set rootfs for 'arch' lxc-start: failed to setup the container lxc-start: invalid sequence number 1. expected 2 lxc-start: failed to spawn 'arch'これはsystemdとLXCの組み合わせで発生する問題で、/以下をprivate mountす ることで解決できるようだ。
miku@host% sudo mount --make-rprivate /このprivate mountの詳細については、以下のページが詳しい。
- https://access.redhat.com/knowledge/docs/ja-JP/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/sect-Using_the_mount_Command-Mounting-Bind.html
- http://www.ibm.com/developerworks/jp/linux/library/l-mount-namespaces.html
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd lxc-start: No such file or directory - failed to mount a new instance of '/dev/pts' lxc-start: failed to setup the new pts instance lxc-start: failed to setup the container lxc-start: invalid sequence number 1. expected 2 lxc-start: failed to spawn 'arch' miku@host% sudo mkdir -m 755 /var/lib/lxc/arch/dev/pts以上2つの問題を解決し、ようやくsystemdとsshdが起動した。
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd miku@host% lxc-ps -n arch CONTAINER PID TTY TIME CMD arch 1113 ? 00:00:00 systemd arch 1124 ? 00:00:00 systemd-udevd arch 1132 ? 00:00:00 systemd-journal arch 1243 ? 00:00:00 sshd arch 1245 ? 00:00:00 dbus-daemon arch 1246 ? 00:00:00 systemd-logind arch 1253 ? 00:00:00 agetty arch 1254 tty1 00:00:00 agettyデーモンとして動作させる場合は、以下のように-dオプションとログ出力オプ ションを設定し起動する。
miku@host% sudo lxc-start -n arch -d \ > --logfile=/var/lib/lxc/arch/lxc.log \ > --console=/var/lib/lxc/arch/console.log -- /usr/lib/systemd/systemdLXCコンテナを終了する場合は、lxc-stopコマンドを利用する。
miku@host% sudo lxc-stop -n archArch Linux上のLXCコンテナ内でArch Linuxを動かし、基本的な操作(起動と終了)が 行えることが確認できた。
その他の問題
今回作成した環境には、lxc-consoleにてコンソールにアクセスできない問題
がある。LXCが想定する/dev以下の扱いとsystemd-udevdの挙動の問題なように
見受けられるので、そのあたりを探っておこうと思う。
(LXC側で掴んだデバイスノードと別に/devにmountされたdevtmpfs上のデバイ
スノードをsystemd側でgettyしているのが原因?)
0 件のコメント:
コメントを投稿