4. containerd 运行时故障排查:服务状态检查、日志分析与常见错误处理
在自动化发布流水线中,containerd 作为容器运行时的核心组件,其稳定性直接决定镜像拉取、容器创建与销毁等关键操作的成败。本章聚焦 containerd 服务状态检查、日志分析以及 shim 异常等高频故障的处理方法,帮助运维与开发人员快速定位并恢复运行时故障。
4.1 containerd 服务状态检查
故障排查的第一步是确认 containerd 服务是否正常运行。以下命令用于检查服务状态、监听端口与 gRPC 接口健康度。
| 检查项 | 命令 | 预期输出 |
|---|---|---|
| systemd 服务状态 | systemctl status containerd |
Active: active (running) |
| 监听端口 | ss -tlnp | grep containerd |
LISTEN 0 128 *:9090 *:* |
| gRPC 健康检查 | ctr version |
Client/Server 版本号正常返回 |
| 命名空间列表 | ctr namespace ls |
至少包含 default、k8s.io 等 |
排查要点:如果
systemctl status containerd 显示 Active: failed,立即查看 journalctl -u containerd --no-pager -n 50 获取最后 50 行日志;若端口未监听,检查 containerd 配置文件 /etc/containerd/config.toml 中的 grpc.address 是否正确。
4.2 日志分析:结构化定位故障根因
containerd 日志默认输出到 systemd journal,日志级别从 debug 到 fatal。以下表格列出常见日志模式及其对应的故障类型。
| 日志模式 | 故障类型 | 典型错误片段 |
|---|---|---|
level=error msg="failed to start shim" |
shim 启动失败 | exec: "containerd-shim-runc-v2": executable file not found |
level=warning msg="image garbage collection failed" |
镜像 GC 异常 | unlinkat /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs: device or resource busy |
level=error msg="failed to dial" |
gRPC 连接中断 | connection refused: tcp 127.0.0.1:9090 |
level=info msg="stop container with signal" |
容器被强制终止 | signal: killed (OOM 或超时) |
日志分析三步法:
1. 使用
2. 过滤特定级别:
3. 结合时间戳与容器 ID 交叉关联:
1. 使用
journalctl -u containerd -f 实时跟踪日志流。2. 过滤特定级别:
journalctl -u containerd -p err --since "5 min ago"。3. 结合时间戳与容器 ID 交叉关联:
grep "container_id" /var/log/containerd.log。
4.3 常见错误处理:shim 异常深度剖析
shim 是 containerd 与 runc 之间的中间层,负责管理容器进程的生命周期。shim 异常是流水线中最常见的运行时故障之一,表现为容器创建失败、容器无故退出或残留僵尸进程。
4.3.1 shim 异常典型场景
| 场景 | 错误日志 | 根因 |
|---|---|---|
| shim 二进制缺失 | exec: "containerd-shim-runc-v2": stat /usr/bin/containerd-shim-runc-v2: no such file or directory | containerd 安装不完整或升级后未同步 shim 二进制 |
| shim 进程 OOM | shim process killed: signal: killed (OOM) | shim 内存限制过低或节点内存不足 |
| shim 与 runc 版本不兼容 | failed to create shim task: runc version mismatch | containerd 与 runc 版本组合不匹配 |
| shim 僵尸进程残留 | failed to reap shim pid: waitid: no child processes | 容器异常退出后 shim 未正确清理 |
4.3.2 shim 异常恢复步骤
- 确认 shim 二进制完整性:检查
/usr/bin/containerd-shim-runc-v2是否存在且可执行;若缺失,重新安装 containerd 或手动复制二进制。 - 检查 shim 进程状态:
ps aux | grep containerd-shim,查看是否有大量僵尸进程(状态 Z)。 - 清理残留 shim 进程:使用
kill -9 <PID>强制终止异常 shim,然后执行ctr tasks kill --signal 9 <container_id>清理对应容器。 - 验证 runc 版本兼容性:
runc --version与containerd --version对比,确保大版本一致。 - 重启 containerd 服务:
systemctl restart containerd,重启后立即检查日志确认 shim 正常启动。
注意:强制终止 shim 进程可能导致容器数据丢失或文件系统损坏。在生产环境中,优先尝试
ctr container delete <container_id> 优雅删除,再处理残留 shim。
4.4 其他常见错误处理
4.4.1 镜像拉取超时
流水线中镜像拉取超时会导致构建失败。排查步骤:
- 检查网络连通性:
curl -I https://registry-1.docker.io/v2/。 - 查看 containerd 配置中的
max_concurrent_downloads和timeout参数。 - 临时增加超时:修改
/etc/containerd/config.toml中[plugins."io.containerd.grpc.v1.cri".registry]下的timeout为300s。
4.4.2 容器启动后立即退出
常见于入口命令错误或依赖缺失。排查方法:
- 使用
ctr container list确认容器状态为STOPPED。 - 查看容器日志:
ctr task logs <container_id>。 - 检查 shim 日志中是否有
exit code 127(命令未找到)或exit code 1(通用错误)。
自动化流水线集成建议:在 CI/CD 流水线中加入 containerd 健康检查步骤,例如:
#!/bin/bash
if ! systemctl is-active --quiet containerd; then
echo "containerd 服务异常,触发自动恢复"
systemctl restart containerd
sleep 3
if ! systemctl is-active --quiet containerd; then
echo "自动恢复失败,请人工介入"
exit 1
fi
fi
4.5 故障排查清单
| 步骤 | 操作 | 验证命令 |
|---|---|---|
| 1 | 检查 containerd 服务状态 | systemctl status containerd |
| 2 | 查看最近错误日志 | journalctl -u containerd -p err --since "1 hour ago" |
| 3 | 确认 shim 二进制存在 | which containerd-shim-runc-v2 |
| 4 | 清理僵尸 shim 进程 | ps aux | grep defunct | grep -v grep |
| 5 | 验证 gRPC 接口 | ctr version |
| 6 | 重启 containerd 服务 | systemctl restart containerd |
通过以上系统化的状态检查、日志分析与 shim 异常处理流程,运维人员可以在自动化发布流水线中快速恢复 containerd 运行时故障,保障容器编排的连续性与稳定性。