Docker守护进程连接失败,containerd 数据库损坏

Docker守护进程连接失败,containerd 数据库损坏

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

cp -r /var/lib/containerd /var/lib/containerd.bak

第二步:清理并重建

直接删除 containerd 的运行数据目录。containerd 启动时发现目录为空,会自动重建空的数据库文件。

Bash

# 停止相关服务
systemctl stop docker
systemctl stop containerd

# 清理受损数据
rm -rf /var/lib/containerd/*

# 重新启动服务
systemctl start containerd
systemctl start docker

4. 验证结果

再次检查 containerd 状态,发现已经恢复 active (running)

Bash

[root@localhost ~]# systemctl status containerd
● containerd.service - containerd container runtime
   Active: active (running) since Sun 2024-12-22 18:47:08 CST; 4s ago

测试容器操作,容器已能正常启动:

Bash

[root@localhost ~]# docker restart tools-nginx-1
tools-nginx-1
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE        STATUS          NAMES
0b68949ab785   nginx:latest Up 8 seconds    tools-nginx-1

5. 总结

当遇到 connection refused 且 containerd 无法启动时,不要盲目重启服务器。通过 journalctl 定位是否属于 bbolt 数据库 Panic 是关键。

如果生产环境不能接受镜像丢失,可以尝试使用 bbolt 官方工具进行数据库修复,但对于大多数场景,清理 /var/lib/containerd 并重新拉取镜像是最高效的“止损”方案。


笔者注: 建议在服务器上配置好磁盘空间预警。很多时候,数据库损坏的根源其实是磁盘被日志刷爆后的强制写入失败。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容