重启Docker后容器自动退出的问题

云主机OS版本 CentOS 7.6 Docker版本 Docker CE 19.03.9

今天学习k8s的时候,实操过程中改了daemon的配置

#找到ExecStart=xxx,在这行上面加入一行,内容如下:(k8s的网络需要)
ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT

$ systemctl daemon-reload
$ service docker restart

之后便直接重启了docker.service,是的你没有听错,我没有去docker stop容器,而是直接重启docker.service,重启完之后我才意识到这样操作不对,因此就有一个容器死活就是启动不了,一启动过几秒就自动退出,然后自动重启...(ps.容器自动重启配置命令:docker container update --restart=always [CONTAINER NAME] 参考:docker内部容器自动重启配置 将docker容器设为自启动和取消容器自启动)

docker container update --restart=always 容器名字

操作实例如下:
[root@localhost mnt]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
46cdfc60b7a6        nginx               "nginx -g 'daemon ..."   About a minute ago   Up 42 seconds       80/tcp              n3
79d55a734c26        nginx               "nginx -g 'daemon ..."   About a minute ago   Up 42 seconds       80/tcp              n2
f7b2206c019d        nginx               "nginx -g 'daemon ..."   About a minute ago   Up 46 seconds       80/tcp              n1
[root@localhost mnt]# docker container update --restart=always n1
n1
[root@localhost mnt]# systemctl restart docker 
[root@localhost mnt]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
46cdfc60b7a6        nginx               "nginx -g 'daemon ..."   2 minutes ago       Exited (0) 5 seconds ago                       n3
79d55a734c26        nginx               "nginx -g 'daemon ..."   2 minutes ago       Exited (0) 5 seconds ago                       n2
f7b2206c019d        nginx               "nginx -g 'daemon ..."   2 minutes ago       Up 2 seconds               80/tcp              n1

一开始我还怀疑过容器假死的情况,但是根本不是这种情况,因为它不符合以下几种情况:

#在使用docker部署我们的服务时,偶尔会遇到这种情况,使用如下命令判断:
docker ps 显示容器状态正常,但是对外服务已经不可用
docker stats 没有任何反应
docker stop CONTAINER_ID 没有任何反应
docker restart CONTAINER_ID 也没有任何反应
docker exec -it –user root CONTAINER_ID /bin/bash 也没有任何反应
docker logs CONTAINER_ID --tail 111 -f 也没有任何反应
docker-compose命令也提示响应超时,不可用

所以排除假死的原因.

之后排查过程中,通过docker logs [CONTAINER ID]查看日志根本看不出启动过程中报的错误信息,一开始我怀疑的是容器内的服务端口被占用

#docker 查看端口被占用进程
lsof -i:8080(或者netstat -antp|grep 8080)

发现正常,没有被占用. (docker top [CONTAINER ID]命令也用过了,报错Error response from daemon: Container e08201b591cdccd198fa32c4eedbda4a9ca6c81ce2c066e885c592aede52a8a6 is not running,因为容器没运行.)

后面又开始觉得是容器内部服务里面占用8080端口,毕竟8080端口太容易被占用,所以尝试修改容器服务内部的配置文件,又一个问题冒出来了,就是进不去容器内部bash,因为容器没有运行,虽然有几秒的短暂时间可以进得去,但还没等你找到想改的端口配置文件就自动退出了,docker exec命令就这样,一旦容器挂了,exec也会跟着自动退出到宿主机.那怎么办呢?

为了验证是容器内部的报的错的想法,我把这个问题容器用docker commit提交到一个新的镜像,然后用docker run -itd --name xxx -p xxxx:8080 --restart=always [IMAGES NAME]:[TAG]基于新镜像运行一个新的容器进去改变(修复)配置文件。再通过新的容器再提交一个新的镜像,然后在基于新的镜像重新启动容器(同最初的容器)(参考:如何修复无法启动的docker容器).结果还是自动退出..

但是有一点肯定的,就是容器内部的服务有问题,可能是在启动过程中出了问题

那既然Docker容器无法启动,里面的配置文件如何修改?

运行命令 docker inspect [CONTAINER ID] ,可以找到如下的内容

记录一次docker重启后服务自动退出的问题.png

看到MergedDir, cd到MergedDir,你会惊奇的发现,他和我们容器里的目录结构是一样的(参考:Docker容器无法启动,里面的配置文件如何修改)

注意: 如果容器stop状态,cd是进不去的,会提示:-bash: cd: /var/lib/docker/overlay2/5f7b60d2ed5b419f72e76155e1a08f5e55b0b92cad46186eb5d847f25e0be432/merged: No such file or directory,那么这个时候可以docker start启动,启动后再次进去了不会像docker exec那样容器停了,会被迫退出. 记录一次docker重启后服务自动退出的问题2.png

继续cd到WORKDIR 比如我的是:/app/mblog (Dockerfile配置的工作目录),是不是和docker exec -it xxx bash 进去的目录一样呢?对!没错,一模一样!

记录一次docker重启后服务自动退出的问题3.png

事实上,本网站中的图片也可以利用这种方式通过登录sftp工具进行快速替换 记录一次docker重启后服务自动退出的问题7.png

于是我赶紧cd logs, tail -f blog-2022-09-22.log查看启动日志

记录一次docker重启后服务自动退出的问题4.png

果然在报错!!!

记录一次docker重启后服务自动退出的问题5.png

原来是一直连不上数据库,报Public Key Retrieval is not allowed错误.于是我用连接工具DBeaver连了一下数据库发现可以连上,然后再回头看日志的时候发现启动成功了?!!!(为什么又启动了,是因为前面配置了自动重启)

记录一次docker重启后服务自动退出的问题6.png

虽然很怪异,但是解决这个问题的心路历程还是有必要记录一下的,毕竟关于Docker这块又成长了一点.

(完)


已有 0 条评论

    感谢参与互动!