AUFS の 40(42?) レイヤ問題
ノーマルの boot2docker で動作する Docker デーモンはストレージに AUFS を使用しているので、AUFS の制限によって Dockerfile でビルドするステップ(レイヤ)が多いと失敗する。
自分の Dockerfile だったら、ステップを減らしたりして調節出来るけど、既に作られた Docker Hub にあるやつだったりすると困ったことに。。。
当の boot2docker.iso のビルドも、以前までは boot2docker 上で出来ていたのに、最近ではステップが多すぎてビルドに失敗するようになってしまいました。
[訂正]
AUFS の 42 レイヤ問題は、ある条件下で発生し、それを回避する方法があることがわかりました。
また、boot2docker 自体には問題が無く、boot2docker.box (boot2docker の Vagrant 用 box) のビルドに問題があることもわかりました。
下記の対策でも問題はありませんが、boot2docker の本家にならい、yungsang/boot2docker
を更新しました。
https://github.com/boot2docker/boot2docker/issues/531
https://github.com/mitchellh/boot2docker-vagrant-box/pull/72
https://github.com/YungSang/boot2docker-vagrant-box/commit/b85b91a3622ab713e94114ad254115d375552070
対策
これは以前から知られている問題で、こんな時は boot2docker ではなくて、CoreOS を使う(BTRFS なので制限が無い)ってのが自分の定番。
ところが先日 GitHub の Isuue でこの問題が上げられたので、
exec: "/bin/sh": stat /bin/sh: no such file or directory · Issue #11
https://github.com/YungSang/boot2docker-vagrant-box/issues/11
どうにか boot2docker でも別のストレージが使えないかと調べてみたら、
いけそうなので、BTRFS 版、Device Mapper 版をそれぞれ作ってみました。
VAGRANTFILE_API_VERSION = "2"
STORAGE = "btrfs" # btrfs or devicemapper
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define "boot2docker-#{STORAGE}"
config.vm.box = "boot2docker-#{STORAGE}"
config.vm.box_url = "https://github.com/YungSang/boot2docker-vagrant-box/releases/download/#{STORAGE}-v1.3.1/boot2docker-virtualbox.box"
config.vm.synced_folder ".", "/vagrant"
end
以下のようにレイヤが多い Dockerfile を作って試してみて下さい。
#!/bin/bash
echo "FROM busybox" >Dockerfile
for i in $(seq 1 42); do
echo "RUN echo layer=$i" >>Dockerfile
done
$ vagrant up
$ chmod +x make-dockerfile.sh && ./make-dockerfile.sh
$ docker build .
それぞれのストレージでの動作の違いも分かって勉強にもなりました。
しかも、CoreOS を使うより軽量だし、VirtualBox Guest Additions もあるし、
なかなかいいかも。