概要
公式のDockerイメージなどをPullして
docker run -it [イメージ名] /bin/bash
とすると、まれに
/bin/bash: /bin/bash: cannot execute binary file
となる問題について。
なぜ起きるのか
結論を先に言うと、Dockerfile上のENTRYPOINTが原因。
※ENTRYPOINTとは
コンテナ起動時に実行したいコマンドを設定できる。
詳しくは公式のリファレンス参照
http://docs.docker.jp/engine/reference/builder.html#entrypoint
ENTRYPOINTとCMDの違いについて
実行コマンドを設定できるものとして、CMDというのも存在する。
http://docs.docker.jp/engine/reference/builder.html#cmd
ENTRYPOINTとCMDの違いについて、よく話題にあがるので説明する。
わかりやすいよう、比較用のDockerfileを用意する。
.
├── cmd
│ └── Dockerfile
└── entrypoint
└── Dockerfile
./cmd/Dockerfile
FROM centos:latest
CMD ["/bin/bash"]
./entrypoint/Dockerfile
FROM centos:latest
ENTRYPOINT ["/bin/bash"]
それぞれビルド。
$ docker build -t entry_centos ./entrypoint/
$ docker build -t cmd_centos ./cmd/
それぞれdocker runさせてみる。
→違う結果に。
$ docker run -it --rm cmd_centos /bin/bash
[root@627d9a396552 /]#
$ docker run -it --rm entry_centos /bin/bash
/bin/bash: /bin/bash: cannot execute binary file
なぜ上のようなログが出るのか?
→CMDは設定したコマンドを上書きできるのに対して、ENTRYPOINTのコマンドはデフォルトとして設定される(上書きがされない)ため。
http://docs.docker.jp/engine/reference/builder.html#cmd-entrypoint
なので、entry_centosでは**/bin/bash /bin/bash**というコマンドが実行されたような状態となっている。
ということでタイトルの原因に繋がる。
補足
ENTRYPOINTとCMDですが、下記のように組み合わせて、デフォルトの振る舞いを設定するという書き方がよく出てきます。↓例
FROM centos:latest
ENTRYPOINT ["/bin/bash"]
CMD ["-c", "ls"]
$ docker run -it --rm cmd_entry_sample
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
$ docker run -it --rm cmd_entry_sample -c "cat /etc/redhat-release"
CentOS Linux release 7.5.1804 (Core)
まとめ
なんかコンテナがうまく起動しないときはめんどくさがらずDockerfileを確認する。(自戒)