なぜこれをやろうと思ったか
Docker を aufs ではなく Device-mapper で使っていて、なんだか「おかしいな」と思うことがあった。
https://docs.docker.com/engine/installation/linux/ubuntulinux/
Docker の Ubuntu でのインストール方法によると、 Prerequisites by Ubuntu Version の項に
For Ubuntu Trusty, Wily, and Xenial, it’s recommended to install the linux-image-extra-* kernel packages. The linux-image-extra-* packages allows you use the aufs storage driver.
とある。
aufs を使うことを推奨し、そのために
linux-image-extra-$(uname -r)
と linux-image-extra-virtual
をインストールせよ、と記載されている。
探してみると このような Issue もある。
Device-mapper でディスクフル状態になると、 Docker イメージもコンテナも削除不能に陥ってしまい、
最終的にプロセスを止め、 Docker を完全リセットするために sudo rm -rf /var/lib/docker
するしかなくなってしまうという症状が報告されている。
Issue の状態は Closed になっていたが、コメント欄のやりとりを見るに、なんだか状態は続いているように読めたので、実際に試してみた。
(なお、今回はユーザを docker グループに入れている。グループに入れたくない場合は、すべて sudo をつけて sudo docker
のように実行する。)
再現方法
Ubuntu 14.04 で試してみた。
インストール
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ sudo add-apt-repository "deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release -s -c) main"
$ sudo apt-get update
$ sudo apt-get purge lxc-docker
$ sudo apt-get install -y docker-engine
$ sudo service docker start
$ sudo apt-get install -y linux-image-extra-$(uname -r) linux-image-extra-virtual
これを手順から抜いたものを Device-mapper 版、抜かないものを aufs 版とした。
コンテナの中でわざとディスクフルを引き起こす。
次のコマンドは 1G のファイルを作る。サイズはディスクフルになる量に bs と count を調整する。
$ dd if=/dev/urandom of=testdata bs=64M count=16 iflag=fullblock
このように dd コマンドを使いデータを書き込む。 /dev/zero からコピーすると、中身がゼロ埋めされていると、賢い aufs は実際に容量を消費してくれない。
なので適度にランダムなデータを書き込むため /dev/urandom をコピー元に使った。
これを
$ docker run -it ubuntu /bin/bash
でコンテナの中にログインし、エラーになるまで実行した。
エラーがでたらコンテナからログアウトする。
コンテナを削除する。
その後
$ docker ps
$ docker rm コンテナのID
を試みる。
結果
aufs 版
特に問題なくコンテナは削除できた。 df から見るストレージの使用状況も 100% から元の数値に戻った。
Device-mapper 版
次のようなエラーが出て、コンテナの削除ができない状態になった。 docker rm -f
でも同じ。
Error response from daemon: Driver devicemapper failed to remove root filesystem xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: devicemapper: Error running DeleteDevice dm_task_run failed
いろいろと試したものの、 Issue に書かれている通り、
悔しい思いをしながら sudo rm -rf /var/lib/docker
するぐらいしか、自分にはできることが思いつかなかった。
まとめ (未解決)
今のところインストール手順で推奨されている通り aufs をストレージドライバに使った方がよさそうだ。
Device-mapper を使う場合は、何か追加の設定が必要なのかもしれないが、その設定方法を私には見つけることができなかった。
もし設定方法を探しだすことができれば、この記事に追記する。
あるいは、もしソフトウェア上の原因を見つけることができれば報告したいと思う。