KVM+libvirt な仮想化ホストに、ブリッジ I/F で固定IPな docker ホストを boot2docker で作る試行錯誤のメモ。
なお boot2docker は新しい Docker のリリースや kernel の更新以外では更新されないメンテナンスモードになっているようです。
userdata.tar で SSH 鍵を配置
boot2docker は最初のブート時に先頭が boot2docker, please format-me
という文字列で始まっているブロックデバイスを tar ファイルとして取り出して、ブートの都度 /home/docker
に展開します。
tar を取り出した後のそのデバイスは永続データの領域として自動的にフォーマットされます。
そのようなブロックデバイスのためのディスクイメージはは次のように作成できます。
mkdir -p .ssh chmod 700 .ssh/ curl https://github.com/ngyuki.keys -o .ssh/authorized_keys chmod 600 .ssh/authorized_keys echo "boot2docker, please format-me" > "boot2docker, please format-me" tar cvf userdata.img "boot2docker, please format-me" .ssh truncate -s 1G userdata.img qemu-img convert -f raw -O qcow2 userdata.img userdata.qcow2
docker-machine
はこの仕組を用いて authorized_keys
を配置しているようですが、tar ファイルは /home/docker
に展開されるだけなので固定IPを付与するような処理は行なえません。
bootsync.sh でブート時に固定IPを付与
boot2docker はブート時に /var/lib/boot2docker/bootsync.sh
や /var/lib/boot2docker/bootlocal.sh
があればそれを sh
で実行します。
/var/lib/boot2docker/
は永続データの領域なので、/var/lib/boot2docker/bootsync.sh
に次のように書いておけばブートの都度、固定IPが付与されます。
killall udhcpc sleep 1 ip addr flush dev eth0 ip addr add 192.168.0.100/24 dev eth0 ip route add default via 192.168.0.1 dev eth0 echo nameserver 192.168.0.1 > /etc/resolv.conf
しかし、初回ブート時にこのファイルを作成する術がありません。コンソールで作業すればいいだけですが・・
boot2docker-data
boot2docker はブート時に boot2docker-data
というラベルのついたパーティションを探して、見つかればそれを永続データの領域としてマウントします。見つからなければ boot2docker, please format-me
という文字列で始まっているブロックデバイス、またはパーティション未作成なブロックデバイスを自動的にフォーマットしてマウントします。
普通は初回ブート時に自動フォーマットされるときに、このラベルがついたファイルシステムとしてフォーマットされるのですが、あらかじめフォーマット済で boot2docker-data
というラベルのついたパーディションを含むディスクファイルを用意すれば、任意のカスタマイズされた永続データ領域を初回ブート時から使用できます。
boot2dockerswap
boot2docker はブート時に boot2dockerswap
というラベルのついたパーティションを探して、見つかればそれをスワップとして使います。見つからなくても警告が出力されるだけで起動はするようです。
普通は初回ブート時に自動フォーマットされるときに、永続データ用のパーティションをフォーマットするついでにこのラベルの付いたスワップパーティションも作成されますが、あらかじめ boot2dockerswap
というラベルの付いたスワップパーティションを含むディスクファイルを用意すれば、自動フォーマットが行われなくてもスワップが有効になります。
やってみる
# 固定IPのためのスクリプトを作成 mkdir -p ./rootfs/var/lib/boot2docker/ cat <<'EOS'> ./rootfs/var/lib/boot2docker/bootsync.sh killall udhcpc sleep 1 ip addr flush dev eth0 ip addr add 192.168.0.100/24 dev eth0 ip route add default via 192.168.0.1 dev eth0 echo nameserver 192.168.0.1 > /etc/resolv.conf EOS chmod -x ./rootfs/var/lib/boot2docker/bootsync.sh # SSH公開鍵を含む userdata.tar を作成 mkdir -p ./userdata/.ssh/ curl -s https://github.com/ngyuki.keys -o ./userdata/.ssh/authorized_keys chmod 700 ./userdata/.ssh/ chmod 600 ./userdata/.ssh/authorized_keys tar cvf ./rootfs/var/lib/boot2docker/userdata.tar -C ./userdata/ .ssh/ # ↑が保持ぞんされたファイルシステムを含むディスクファイルを作成 virt-make-fs --format=raw --partition=gpt --size=1G --type=ext4 --label=boot2docker-data ./rootfs/ data.img # スワップのディスクファイルを作成 truncate -s 1G swap.img parted -s -a optimal swap.img -- mklabel gpt mkpart primary 1 -1 guestfish -a swap.img run : mkswap /dev/sda1 label:boot2dockerswap # 確認 virt-df -h -a data.img -a swap.img #=> Filesystem Size Used Available Use% #=> data.img+:/dev/sda1 992M 2.5M 922M 1% # 確認 virt-filesystems --all --long -h -a data.img -a swap.img #=> Name Type VFS Label MBR Size Parent #=> /dev/sda1 filesystem ext4 boot2docker-disk - 1.0G - #=> /dev/sdb1 filesystem swap boot2dockerswap - 1022M - #=> /dev/sda1 partition - - - 1.0G /dev/sda #=> /dev/sdb1 partition - - - 1022M /dev/sdb #=> /dev/sda device - - - 1.0G - #=> /dev/sdb device - - - 1.0G - # boot2docker.iso をダウンロード wget https://github.com/boot2docker/boot2docker/releases/download/v18.09.1/boot2docker.iso # ゲストを作成 virt-install \ --import \ --name boot2docker \ --hvm \ --virt-type kvm \ --ram 1024 \ --vcpus 1 \ --arch x86_64 \ --os-type linux \ --boot cdrom \ --disk "$PWD/data.img,device=disk,bus=virtio,cache=writeback" \ --disk "$PWD/swap.img,device=disk,bus=virtio,cache=none" \ --disk "$PWD/boot2docker.iso,device=cdrom" \ --network network=default,model=virtio \ --graphics none \ --serial pty \ --console pty
動作確認します。
env DOCKER_HOST=ssh://docker@192.168.0.100 docker run --rm hello-world env DOCKER_HOST=ssh://docker@192.168.0.100 docker run -d -p 80:80 nginx curl http://192.168.0.100/
さいごに
クラスタ化しないシングルの Docker 環境をサッと作れるように試行錯誤したのですが、boot2docker.iso
が
On the other hand, the boot2docker distribution (as in, boot2docker.iso) is in "maintenance mode".
とのことらしいので、別の Docker ホスト用の軽量 Linux を使うのが良いですかね。。
ただ、Container Linux (CoreOS) や Atomic Host はクラスタにする前提な気がして敷居が高く感じたので、RancherOS とかがいいんでしょうかね。