Dockerコンテナがstart出来なかったりRemoval In Progressってなって消せなかったりした時の対処法

最近ずっとDocker介助おじさんとなっていますこんにちは。

Docker、便利なんですけどつらいことも色々多い。

Dockerを運用していると、コンテナの再起動や削除時にコンテナのステータスがRemoval In Progressとなってコンテナを削除できなくなったりすることがちょいちょいあります。

こういう時は大体Dockerデーモン再起動しか無くて本当につらいのですが*1、再起動したらしたで、今度は止まったコンテナ立ち上げようとして下記みたいに言われてstartが失敗したりするわけです。

Error response from daemon: rpc error: code = 6 desc = "mkdir /run/containerd/{container id}: file exists"

こうなるともうコンテナ削除するしか無いですし、削除したら部署の皆さんに「コンテナ起動できなかったので再デプロイお願いします」って頼まなきゃいけないのでだるいのです。

で、今日もつらいつらいと言いながらいろいろガチャガチャやっていたらデーモン再起動無しに状況を切り抜けられたのでそのメモです。

ちなみにDockerは1.11です。

Removal In Progressとなって削除できないコンテナを削除する

ググると、 /var/lib/docker/container/{container id} 消せとか出てくるんですけど、僕の状況だと既にそんなディレクトリ無かったり、安全のためにデーモン止めてから作業しろとあったりして、いや止めたくないんじゃみたいな気持ちがあったのですが、そういう場合、当該コンテナが実行しているプログラム(CMDとかENTRYPOINTに指定されているやつ)を何とか探して

$ ps aux | grep {プログラム名}

でコンテナ内のプロセスを探します。
その親プロセスが多分

docker-containerd-shim {container id} /var/run/docker/libcontainerd/{container id} docker-runc

みたいなやつになっていると思うので、このコンテナIDを指定してdocker stopします。恐らくdocker ps -aしてもこのコンテナIDはいないと思うんですが、何か知らないですけど通ります。
多分何らかの原因でコンテナ(プロセス)の停止に失敗してリソース掴みっぱなしになってるとかで削除できなかったんでしょうね。
これで僕の環境だとRemoval In Progressが消えました。

startしようとするとエラーになるコンテナをstartする

エラーになるコンテナIDを控えておいて

$ ps aux | grep {container id}

でプロセスを探します。
そうすると多分上記と同じく

docker-containerd-shim {container id} /var/run/docker/libcontainerd/{container id} docker-runc

みたいなプロセスが出てくると思うんですが、今度はさっきと逆で、このプロセスの子プロセスをみます。

それがこのコンテナのCMDやらENTRYPOINTやらで指定したコンテナ内で動いてるPID 1だと思うんですが、そのPID 1と思われるプロセスをkillすると、そのプロセスと一緒に上記のdocker-containerdほげほげみたいなプロセスも一緒に死ぬとおもいます。
killしても死なない場合は kill -KILLで殺しますが、その場合、docker-containerdほげほげが残るのでそいつもkillします。

この状態で、さっきstartに失敗したコンテナを再度docker startすると起動に成功します。
これもきっとなんかしらの原因でプロセス殺すのに失敗してたんでしょうね…。

まとめ

社会は厳しいやっていくしか無い

おまけ

と言う話もあるんですが、overlayfsはinode食い潰すという問題があり、問題が改善されているoverlayfs2はDocker1.12以降かつカーネル4以上となっておりこちらも色々厳しい。CentOSカーネルが4以上になるのはいつですかね…。

*1:弊社のDocker環境は1ホスト辺りに複数のアプリ、APIが雑多に乗っているのでデーモン落とそうと思うと色々だるい