本文共 2415 字,大约阅读时间需要 8 分钟。
docker 容器默认会把容器内部第一个进程,也就是 pid=1
的程序作为docker容器是否正在运行的依据,如果docker容器中 pid = 1 的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。
为了验证这一点,我写了两个go程序并静态编译为可执行程序,common 和 daemon ,他们即可前台运行也可后台运行
前台运行
./common ./daemon
后台运行
./common serve -d ./daemon -d
我们通过这两个程序来构建镜像,看他们是如何运行的。
Dockerfile 文件内容:
FROM alpineADD daemon /data/www/ADD common /data/www/WORKDIR /data/wwwCMD cd /data/www/ && ./daemon -d && ./common
执行命令
docker build -t common .docker run --name common -d common docker exec -it common sh ps -ef PID USER TIME COMMAND 1 root 0:00 ./common 9 root 0:00 ./daemon 16 root 0:00 sh 26 root 0:00 ps -efexit docker stop common docker rm common docker rmi common
修改 Dockerfile 文件的 CMD 指令,重新构建,并运行
CMD cd /data/www/ && ./common -d && ./daemon
ps -efPID USER TIME COMMAND 1 root 0:00 ./daemon 9 root 0:00 ./common 16 root 0:00 sh 21 root 0:00 ps -ef
再次修改 Dockerfile 文件的 CMD 指令,重新构建,并运行
CMD cd /data/www/ && ./common && ./daemon
ps -efPID USER TIME COMMAND 1 root 0:00 ./common && ./daemon 16 root 0:00 sh 20 root 0:00 ps -ef
由此可见docker容器运行后,会将CMD中的第一个前台进程作为pid=1的进程
,而不管在它之前是否还有别的进程。
所以,如果想在一个容器里面启动多个后台进程加一个前台进程
,那么这个前台进程要写在最后面。
这也是为什么,Docker容器启动web服务时,都指定了前台运行的参数。
例如apache:ENTRYPOINT [ "/usr/sbin/apache2" ]CMD ["-D", "FOREGROUND"]
又例如nginx:
ENTRYPOINT [ "/usr/sbin/nginx", "-g", "daemon off;" ]
进入nginx容器,查看进程
ps -ef |grep nginxroot 1 0 0 Oct16 ? 00:00:00 nginx: master process nginx -g daemon off;nginx 19 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 20 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 21 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 22 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 23 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 24 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 25 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 26 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 27 1 0 Oct16 ? 00:00:00 nginx: worker processnginx 28 1 0 Oct16 ? 00:00:00 nginx: worker process
从这个意义上来讲,一个程序从宿主机迁到docker容器,程序是需要做一些调整的。
或者启动额外的进程来充当pid=1的前台进程,例如上面的 daemon 进程。
当然 linux 系统下也提供了一些阻塞的指令,比如:
tali -f xxx 或者 top但是不管怎么样,pid=1的进程必须存在。
转载地址:http://djaui.baihongyu.com/