Docker容器一启动就挂,要怎么排查?
Docker容器一启动就挂,要怎么排查?
1. 分析镜像信息
通过
1 | docker inspect 镜像ID |
可以查看当前镜像的属性信息,那么我们重点需要关注的是Entrypoint
这个属性的信息。
关于entrypoint是什么,你可以参考Dockerfile reference | Docker Documentation
我这里获取到的Entrypoint
信息如下:
1 | "Entrypoint": [ |
这个Entrypoint
可以说是非常的简单,但是又非常的复杂。
简单在于就一行,是直接去执行/docker-entrypoint.sh
这个脚本,但是复杂在于我们并不能直接看到这个docker-entrypoint.sh
的内容。
2. 分析Entrypoint
一般来说,我们有几种方法可以看到这个/docker-entrypoint.sh
文件:
- 挂载:通过
docker run -v
将这个目录挂载到宿主机上,就算这个容器一启动就死,我们也不用担心拿不到文件; - 交互命令(这个词是我自己想的,可能不是很准确):通过
docker run -it 镜像ID sh -c "cat /docker-entrypoint.sh"
去查看内容。这个方法其实还是需要容器启动的,如果是启动立刻挂的情况,这个方法应该是会失效的; - 跳过entrypoint:通过`docker run –entrypoint sh 镜像ID -c “cat /docker-entrypoint.sh”,即可覆盖镜像中的entrypoint,覆盖以后,容器并没有去运行entrypoint脚本,所以也就不会挂了。
3. 覆盖entrypoint
既然都可以覆盖entrypoint了,那我们为啥要局限于通过交互命令去查看文件呢?
1 | docker run -d --entrypoint sh 镜像ID -c "ping 127.0.0.1" |
通过这个命令,给容器一个不可完成的任务,那么这个容器将一直存活。然后再通过
1 | docker exec -it 容器ID sh |
进入容器,岂不是美哉?
如果你的镜像比较简单,可能会没有
ping
命令,那么你可能需要tail
或者其他命令来保证容器可长期存活
4. 手动执行entrypoint
容器不会被自动杀掉以后,我们就可以一步一步的去分析这个entrypoint到底是死在哪儿了?
这里就没有办法展开讲了,因为每个人的情况都是不同的,只要有点耐心,我相信一定是可以解决的。