如何拯救一个无法进入的容器

Posted by JC on January 15, 2020

容器在使用时经常会出现手动修改系统参数导致无法启动的情况,这篇文章主要介绍一下相关的注意事项和方法。

基本原则

基本原则1: 不经常变动或者变动很少的设定信息应该固化至Dockerfile或者镜像之中。

基本原则2: 有定制需要的设定配置文件应该以挂载等允许的方式进行外部持久化存储

具体示例

比如修改了MySQL容器中的max_allowed_packet参数,导致MySQL无法启动。执行docker start之后,容器无法启动,docker logs确认日志信息如下所示:

[root@devops docker]# find . -type f |grep mysqld.cnf |xargs grep max_allowed
./overlay/d9357e5213354f05bc076e4e2b68b6b8ca662428f2857398e2e78d87070b75ac/upper/etc/mysql/mysql.conf.d/mysqld.cnf:max_allowed_packet = 50*1024*1024
[root@devops docker]# pwd
/var/lib/docker
[root@devops docker]#

看到原因是试图在配置文件中设定max_allowed_packet,但是设定是使用5010241024的方式,写法出现错误,导致无法启动。

对应方式1: 配置文件在容器外

如果此配置文件挂载出来了,直接修改挂出来的文件,然后重启即可。这里不做过多介绍。

对应方式2: 配置文件在容器内

如果此文件在容器内,一般需要docker exec进入到容器之内进行修改,像本例中就是比较极端的例子,因为容器本身已经无法启动,更谈不上进入了。如果能够访问到容器存储的目录,并且存储的方式非二进制方式,则还有一种解决的方法。比如缺省安装的情况下,启动的容器的各层内容都存储在/var/lib/docker下,在其中搜索修改的设定文件,比如此例:

[root@devops docker]# find . -type f |grep mysqld.cnf |xargs grep max_allowed
./overlay/d9357e5213354f05bc076e4e2b68b6b8ca662428f2857398e2e78d87070b75ac/upper/etc/mysql/mysql.conf.d/mysqld.cnf:max_allowed_packet = 50*1024*1024
[root@devops docker]# pwd
/var/lib/docker
[root@devops docker]#

可以看到了错误修改信息的文件内容,进行修改如下:

[root@devops docker]# vi ./overlay/d9357e5213354f05bc076e4e2b68b6b8ca662428f2857398e2e78d87070b75ac/upper/etc/mysql/mysql.conf.d/mysqld.cnf
[root@devops docker]# grep max_allowed_packet ./overlay/d9357e5213354f05bc076e4e2b68b6b8ca662428f2857398e2e78d87070b75ac/upper/etc/mysql/mysql.conf.d/mysqld.cnf
max_allowed_packet = 52428800
[root@devops docker]#

然后重启容器,即可发现容器已经能够正常运行了。

[root@devops docker]# docker start dp20_mysql_1
dp20_mysql_1
[root@devops docker]# docker exec dp20_mysql_1 mysql --version
mysql  Ver 14.14 Distrib 5.7.16, for Linux (x86_64) using  EditLine wrapper
[root@devops docker]# 

对应方式3: 配置内容在Dockerfile中

如果配置内容被固化在Dockerfile中,或者本身修改的内容非常少,这时重新生成一个容器则是更为推荐的做法。