环境配置#
- 操作系统:CentOS 7.9.2009
- Docker 版本:18.09.9
问题复现#
安装 Rancher#
docker pull rancher/rancher:v2.3.5
docker run -d \
--restart=unless-stopped \
--name rancher \
-p 80:80 -p 443:443 \
--privileged \
rancher/rancher:v2.3.5

升级 Rancher#
示例将 v2.3.5 升级至 v2.5.0
创建数据备份#
docker stop rancher
docker create --volumes-from rancher --name rancher-data rancher/rancher:v2.5.0
docker run --volumes-from rancher-data -v $PWD:/backup busybox tar zcvf /backup/rancher-data-backup-rancher2.3.5-20210116.tar.gz /var/lib/rancher
启动新版本容器#
docker rename rancher rancher_old
docker run -d --name rancher --volumes-from rancher-data \
--restart=unless-stopped \
-p 80:80 -p 443:443 \
--privileged \
rancher/rancher:v2.5.0
docker logs -f --tail 100 rancher
docker update --restart=no rancher_old
问题现象#
升级完成后,系统重启或手动重启 Docker 服务时,Docker 卡死无法启动。

错误表现:
/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # 手动启动报错
Error starting daemon: pid file found, ensure docker is not running or delete /var/run/docker.pid
ps -ef|grep dockerd # 存在僵尸进程
root 4081 1 0 13:49 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
问题分析与修复#
问题原因#
此问题是 Docker 18.x 版本中存在的一个 Bug。当系统中存在过多无关容器时,会导致 Docker 服务无法正常启动。
解决方案#
删除系统中无关的容器,只保留有用的容器(如本例中的 rancher_old 和创建数据卷备份时使用的容器)。
修复步骤#
清理僵尸进程#
首先停止 Docker 服务并清理僵尸进程:
注意:执行停止 Docker 服务命令时可能会卡住,使用
Ctrl + C终止即可。
service docker stop
yum install psmisc # 安装 killall 工具
killall dockerd
ps -ef|grep dockerd # 检查僵尸进程是否清理完成
清理无用容器#
进入 Docker 容器数据目录(默认路径为 /var/lib/docker/containers):
cd /var/lib/docker/containers && ls

可以看到系统中存在四个容器,本例中只保留名为
rancher的容器。
查找并保留指定容器:
cd /var/lib/docker/containers
# 查找名为 rancher 的容器 ID
for i in `ls */config.v2.json`;do grep -l '"Name":"/rancher"' "$i";done|awk -F '/' '{print $1}'
96d6ea117475ffab7c5651812163ca45feded54463d93e992f9195964ae81282 # 找到的容器 ID
# 删除其他容器(请谨慎确认后执行)
rm -rf !(96d6ea117475ffab7c5651812163ca45feded54463d93e992f9195964ae81282)
验证修复结果#
清理完成后,重新启动 Docker 服务:
service docker start

可以看到 Docker 服务已能正常启动。
总结#
问题特征#
- 影响版本:Docker 18.x 系列存在此 Bug
- 触发条件:系统中存在过多无用容器时,升级后可能导致 Docker 服务无法启动
预防措施#
- 及时清理:升级容器后及时清理无用的旧容器
- 做好备份:升级过程中做好相应的数据备份,避免数据丢失
- 版本选择:考虑升级到更稳定的 Docker 版本以避免此类问题
