Docker 版本 17.06.0-ce
我正在通过观看视频课程学习 Docker。
讲师展示:
sudo docker run -ti ubuntu /bin/bash
使用镜像 ubuntu 运行 docker。让我困扰的是/bin/bash\
。
man docker run
显示这/bin/bash
是一个命令。那是docker run IMAGE [COMMAND]
。好吧,没问题。但是两者之间有什么区别
sudo docker run -ti ubuntu
和
sudo docker run -ti ubuntu /bin/bash
对我来说没有。而且讲师没有把注意力集中在命令上。他说我们只是运行docker。这是他在课程中的第一个命令。然后他展示了我们已经与主机隔离,我们可以自由地破坏我们想要的东西而不会造成任何损害(例如rm -rf /bin)。
我检查了:
$ sudo docker run -ti ubuntu
root@aaf7cd26fe18:/# echo $SHELL
/bin/bash
$ sudo docker run -ti ubuntu /bin/bash
root@6b2570958216:/# echo $SHELL
/bin/bash
好吧,我自己决定将这/bin/bash
部分扔掉作为垃圾。
但无论如何,我决定问你:这两种运行 Docker 的方式可能存在一些差异吗?如果有,那是什么?
答案1
Docker 镜像可以指定默认运行某个命令,使用CMD
Dockerfile 中的指令。 和:
如果用户指定了参数,
docker run
那么它们将覆盖中指定的默认值CMD
。
事实上,为Ubuntu Dockerfile实际上是 bash:
CMD ["/bin/bash"]
所以,对于 Ubuntu 镜像的具体情况来说,docker run ... ubuntu /bin/bash
与没有什么不同docker run ... ubuntu
。
当然,这不一定总是正确的。数据库引擎的 Dockerfile 可能默认运行数据库命令。在这种情况下,如果您需要交互式 shell,则需要执行docker run ... /bin/bash
。
一般来说,你不能假设这会给你一个交互式的 shell。如果你需要 shell,docker run
最好指定一下。/bin/bash
答案2
当您不提供命令(在您的情况下为)时/bin/bash
,在使用-ti
(i
交互式,t
终端)时,您将被附加到已定义为在使用run
命令时执行的默认程序DockerFile
。
比如说,一个镜像在前台运行了一个web服务器,run
那么不使用之后你看到的/bin/bash
就是该web服务器(默认已经运行的程序)的日志。
在指定命令时,您告诉我,我不关心正在发生什么或正在图像上运行什么,而是通过运行此“命令”给我一个交互式终端。
在 Ubuntu 中,默认命令是bash
,如果您不提供,-ti
容器将在运行后立即停止。因为它以非交互模式运行 bash,并且完成后容器不再需要执行任何操作。
答案3
尝试运行以下命令你就能理解差异
sudo docker run -ti python
sudo docker run -ti python /bin/bash