dockerなどのコンテナ環境を構築する際には、application container と system container との二つの志向性があるようだ。プロセスそれ自体が目的のサービスで、それ自体をコンテナに格納するスタイルを application container と呼び、サーバイメージに近いシステム全体としてコンテナに格納するスタイルを system container と呼ぶらしい。
今回は docker で system container やろうとして苦労する話。
docker は ubuntu 14 では標準でインストールできて、native driver でサービス起動する。ところが ubuntu image を落としてきて、system container として動作させようとしても失敗する。
$ docker.io pull ubuntu
$ docker.io run -ti ubuntu /sbin/init
init: Unable to create device: /dev/kmsg
/dev/kmsg
は単に mknod
で作ればよいようだが、linux の進化に合わせて誰がどう作るかが変わってきた経緯があるらしい。今は initramfs が作る?
こういう場合は、やはり lxc driver に一日の長がある様子。lxc もそのための細工を持っている。driver を lxc に変える。service docekr.io restart
で docker.io サービスを再起動しておく。
DOCKER_OPTS="--exec-driver=lxc"
upstart の Debug をする:docker.io run -ti $UBUNTU_WITH_SSHD /sbin/init -v
でやたらいっぱい出力が出るようになる。ファイルシステムのマウントまわりで止まっているのに気が付く。
$ docker.io run -ti ubuntu /sbin/init -v
<4>init: hostname main process (8) terminated with status 1
<4>init: plymouth-upstart-bridge main process (10) terminated with status 1
<4>init: plymouth-upstart-bridge main process ended, respawning
<4>init: hwclock main process (12) terminated with status 77
<4>init: plymouth-upstart-bridge main process (20) terminated with status 1
<4>init: plymouth-upstart-bridge main process ended, respawning
<4>init: ureadahead main process (13) terminated with status 5
<4>init: plymouth-upstart-bridge main process (25) terminated with status 1
<4>init: plymouth-upstart-bridge main process ended, respawning
* Starting Signal sysvinit that the rootfs is mounted [ OK ]
* Stopping Read required files in advance (for other mountpoints) [ OK ]
* Starting Clean /tmp directory [ OK ]
* Stopping Clean /tmp directory [ OK ]
sshd
は filesystem 完了のイベントで起動するので、このままでは sshd
サービスが起動しない。ログは出力されているので見てみよう。
$ docker.io diff $DOCKER_PS_LAST
C /dev
A /dev/kmsg
C /etc
A /etc/mtab
C /run
A /run/plymouth
C /var
C /var/log
C /var/log/upstart
A /var/log/upstart/hostname.log
A /var/log/upstart/hwclock.log
A /var/log/upstart/mountall.log
A /var/log/upstart/ureadahead-other.log
A /var/log/upstart/ureadahead.log
こんな有様だった。
mount: permission denied
mountall: mount /proc/sys/fs/binfmt_misc [59] terminated with status 32
mountall: Filesystem could not be mounted: /proc/sys/fs/binfmt_misc
mount: permission denied
mountall: mount /sys/fs/cgroup [60] terminated with status 32
mountall: Filesystem could not be mounted: /sys/fs/cgroup
mount: permission denied
mountall: mount /sys/fs/fuse/connections [61] terminated with status 32
mountall: Filesystem could not be mounted: /sys/fs/fuse/connections
mount: permission denied
mountall: mount /sys/kernel/debug [62] terminated with status 32
mountall: Filesystem could not be mounted: /sys/kernel/debug
mount: permission denied
mountall: mount /sys/kernel/security [63] terminated with status 32
mountall: Filesystem could not be mounted: /sys/kernel/security
mount: permission denied
mountall: mount /run [64] terminated with status 32
mountall: Filesystem could not be mounted: /run
mount: block device none is write-protected, mounting read-only
mount: cannot mount block device none read-only
mountall: mount /sys/fs/pstore [66] terminated with status 32
mountall: Filesystem could not be mounted: /sys/fs/pstore
libvirt もファイルシステム周りについては操作するらしく、なかなかどうして、システムコンテナ構築も手がかかるものだなぁ。
というわけで、docker での直接的なシステムコンテナ構築は未だ成功せず。みんなどうやってるの?