1. 问题现场
在尝试重启 Docker 容器时,系统抛出了一个无法连接到守护进程的错误:
Bash
[root@localhost ~]# docker restart -t1 tools-nginx-1
Error response from daemon: Cannot restart container tools-nginx-1: connection error: desc = "transport: Error while dialing: dial unix /run/containerd/containerd.sock: connect: connection refused": unavailable
该报错直指 Docker 的底层运行时 containerd。当 Docker 无法通过 Unix Socket 访问 containerd 时,所有的容器操作都会陷入瘫痪。
2. 深入排查
检查服务状态
首先检查 containerd 的系统服务状态:
Bash
systemctl status containerd
输出显示服务处于 activating (auto-restart) 状态,并且错误代码为 status=2。这意味着 containerd 在尝试启动后立即崩溃并进入了死循环重启。
调取底层日志
简单的 systemctl 输出信息有限,我们需要通过 journalctl 查看 containerd 崩溃瞬间的 Panic 信息:
Bash
journalctl -u containerd -n 50 --no-pager
在日志的末尾,我们抓到了“真凶”:
Plaintext
Dec 22 18:40:57 localhost containerd[50977]: containerd successfully booted in 0.043640s
Dec 22 18:40:57 localhost containerd[50977]: panic: invalid page type: 2: 10 // [!code highlight]
Dec 22 18:40:57 localhost containerd[50977]: goroutine 114 [running]:
Dec 22 18:40:57 localhost containerd[50977]: go.etcd.io/bbolt.(*Cursor).search...
原因分析:
日志中的 panic: invalid page type 是 containerd 使用的元数据库 bbolt 抛出的。这通常意味着位于 /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db 的数据库文件因异常断电或磁盘写满导致了物理损坏。
3. 解决方案
由于 metadata 数据库损坏属于不可逆的逻辑错误,最直接的办法是清理受损的数据库文件,让 containerd 重新初始化。
执行以下操作前,务必知晓:删除 /var/lib/containerd 下的数据会导致本地已拉取的镜像列表和容器元数据丢失。重启后你可能需要重新拉取镜像。
第一步:备份数据(防备万一)
Bash
第二步:清理并重建
直接删除 containerd 的运行数据目录。containerd 启动时发现目录为空,会自动重建空的数据库文件。
Bash
4. 验证结果
再次检查 containerd 状态,发现已经恢复 active (running):
Bash
测试容器操作,容器已能正常启动:
Bash
5. 总结
当遇到 connection refused 且 containerd 无法启动时,不要盲目重启服务器。通过 journalctl 定位是否属于 bbolt 数据库 Panic 是关键。
如果生产环境不能接受镜像丢失,可以尝试使用 bbolt 官方工具进行数据库修复,但对于大多数场景,清理 /var/lib/containerd 并重新拉取镜像是最高效的“止损”方案。
笔者注: 建议在服务器上配置好磁盘空间预警。很多时候,数据库损坏的根源其实是磁盘被日志刷爆后的强制写入失败。











暂无评论内容