问题描述
在使用 ubuntu 20.04 的 docker image时, 通过docker run -d ubuntu:20.04
在后台运行 ubuntu 后, 通过 ps -a
看到刚才的容器的 status 是 exit
问题分析
通过 docer history ubuntu:20.04
可以看到一下内容:
IMAGE CREATED CREATED BY SIZE COMMENT
9df6d6105df2 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:e7cff353f027ecf0a… 72.8MB
<missing> 4 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 4 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
第一行的 CMD [“/bin/bash”]:
容器启动时默认执行 /bin/bash,即启动一个 Bash Shell。这个命令通常用于交互式模式下(如 docker run -it),让用户进入容器并与 Shell 进行交互。
为什么 CMD /bin/bash 会导致 docker run -d 后立即退出:
- Bash 退出机制:
docker run -d 选项是让容器在后台运行。因为 CMD /bin/bash 启动的是一个交互式的 Shell,但在 -d 模式下没有连接到标准输入、输出或任何交互终端,bash 发现没有任何交互任务后就会自动退出,导致容器停止。
- 容器生命周期与进程绑定:
Docker 容器的生命周期与其主进程(PID 1)绑定。docker run -d 背景运行容器,但 /bin/bash 在没有交互时会立即退出,容器因此停止。容器需要有一个持续运行的前台进程才能保持活跃状态。
解决方案
-
运行一个不会退出的命令
docker run -d ubuntu tail -f /dev/null
:tail -f
用于持续监视一个文件, 并输出文件的变化,/dev/null
是一个特殊的设备文件,通常被称为“空设备”或“黑洞”。任何写入它的内容都会被丢弃,读取它时也不会返回任何数据 -
分配一个tty
docker run -id/td/itd
:
通过-id
或-td
或-itd
分配一个伪终端, 伪终端是软件实现的终端,它允许一个进程模拟一个终端的行为.