为何Busybox容器内启动httpd的命令失效?容器直接退出
为何Busybox容器内直接启动httpd命令会导致容器退出?
执行以下命令时,容器会直接退出,用docker ps看不到运行中的容器:
docker run -d --rm -it -p 8080:8080 --name webserver busybox /bin/httpd -p 8080
或者
docker run -d --rm -p 8080:8080 --name webserver busybox sh -c '/bin/httpd -p 8080'
但以下两种方式却能正常运行:
- 先启动容器再通过
exec启动httpd:
$ docker run -d --rm -it -p 8080:8080 --name webserver busybox $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ad92d0d4e9ac busybox "sh" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp webserver $ docker exec -it webserver /bin/sh / # httpd -p 8080 / # exit $ telnet localhost 8080 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
- 使用
nc模拟HTTP服务:
$ docker run -d --rm --name my-apache-container -p 80:80 busybox sh -c 'echo -e "HTTP/1.1 200 OK\n\nWelcome to Apache!" | nc -l -p 80' $ telnet localhost 80 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. HTTP/1.1 200 OK Welcome to Apache! Connection closed by foreign host.
问题根源:Docker容器生命周期绑定主进程,Busybox httpd默认后台运行
Docker容器的存活完全依赖于启动时指定的主进程:只要主进程退出,容器就会立刻停止。
- 直接执行
/bin/httpd -p 8080时,Busybox的httpd默认会以后台守护进程的方式启动,启动完成后它的父进程(也就是容器的主进程)就会退出,Docker检测到主进程没了,自然就把容器停了。 - 先启动
sh作为主进程时,sh会一直前台运行保持容器存活,此时再通过exec启动httpd,httpd的后台运行不会影响主进程sh,所以容器能正常持续运行。 - 用
nc -l -p 80能正常运行,是因为nc -l默认是前台阻塞模式,会一直占据主进程直到连接断开,所以容器不会退出。
解决方法:让httpd以前台模式运行
Busybox的httpd支持-f参数强制前台运行,修改命令即可:
# 直接启动httpd前台运行 docker run -d --rm -p 8080:8080 --name webserver busybox /bin/httpd -f -p 8080 # 或者用sh -c的方式 docker run -d --rm -p 8080:8080 --name webserver busybox sh -c '/bin/httpd -f -p 8080'
执行后再用docker ps就能看到容器正常运行,telnet连接也能正常访问了。
内容的提问来源于stack exchange,提问作者mon
相关产品推荐
相关产品推荐

