crictl info 连不上 containerd 怎么办?endpoint、socket 与权限一次查清

crictl info 报错,先别急着重启 kubelet

这类问题通常发生在三个场景:

  • 新装 Kubernetes 节点后,执行 sudo crictl info 直接报错。

  • Docker 迁移到 containerd 后,原来能查容器的节点突然查不到运行时信息。

  • kubelet 日志里出现 CRI 连接异常,手动用 crictl 验证也连不上。

最常见的报错长这样:

bash 复制代码
FATA[0000] connect: no such file or directory

或者:

bash 复制代码
FATA[0000] connect: connection refused

还有一种更容易误判:

bash 复制代码
FATA[0000] permission denied

这三类报错看起来都像"containerd 坏了",但原因可能完全不同。生产环境里不要一上来就重启 kubelet、重装 containerd,先把路径走完:配置 -> socket -> 服务 -> 日志 -> kubelet 端点。

如果你还不熟悉 kubectlcrictlctr 的边界,建议先阅读当天 A 篇:\[2026-07-02 A crictl 实战指南:没有 docker 命令后,Kubernetes 节点该怎么排障?]。本文只聚焦一个单点问题:crictl info 连不上 containerd 时怎么定位。

先划边界:crictl 连的是 CRI endpoint,不是随便一个 containerd 路径

crictl 不是直接替代 docker 的通用客户端,它面向的是 CRI endpoint。对 containerd 节点来说,常见 endpoint 是:

bash 复制代码
unix:///run/containerd/containerd.sock

这个 endpoint 要同时满足三个条件:

  1. /etc/crictl.yaml 里写的是这个 endpoint。

  2. /run/containerd/containerd.sock 这个 socket 文件真实存在。

  3. containerd 正在运行,并且 CRI 插件能提供服务。

一张表先定位报错方向

报错或现象 常见原因 先跑的命令 判断标准 处理方向
no such file or directory endpoint 路径写错,或 socket 不存在 sudo cat /etc/crictl.yaml runtime-endpoint 是否指向真实 socket 修正 /etc/crictl.yaml,再查 socket
no such file or directory containerd 没有创建 socket sudo ls -l /run/containerd/containerd.sock 文件是否存在,类型是否为 socket 检查 containerd 服务和日志
connection refused socket 存在但服务未正常监听 sudo systemctl status containerd --no-pager 是否 active (running) 重启前先看日志,避免掩盖启动失败原因
context deadline exceeded 服务卡住、CRI 插件异常、节点负载过高 sudo journalctl -u containerd -n 200 --no-pager 是否有插件、磁盘、权限、镜像存储错误 按日志关键字继续定位
permission denied 当前用户无权访问 socket 或目录 sudo ls -ld /run/containerd /run/containerd/containerd.sock 用户、组、权限是否允许访问 sudo 验证;生产上谨慎调整权限
crictl 能连,kubelet 仍报 CRI 错误 kubelet runtime endpoint 和 crictl 不一致 `ps -ef grep 'kubelet'` --container-runtime-endpoint 是否一致 修正 kubelet 配置后灰度重启

第一步:检查 /etc/crictl.yaml

先看 crictl 到底准备连哪里:

bash 复制代码
sudo cat /etc/crictl.yaml

用途:确认 runtime-endpointimage-endpoint。 判断标准:containerd 节点通常应看到下面这种配置:

bash 复制代码
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false

如果文件不存在,或者 endpoint 还是旧路径,例如 Docker shim 时代的路径,就先补齐:

bash 复制代码
sudo tee /etc/crictl.yaml >/dev/null <<'EOF'
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

用途:把 crictl 固定到 containerd 的 CRI socket。 判断标准:再次执行 sudo cat /etc/crictl.yaml,确认两个 endpoint 都是 unix:///run/containerd/containerd.sock

生产提醒:如果这是别人维护的节点,修改前先备份:

bash 复制代码
sudo cp -a /etc/crictl.yaml /etc/crictl.yaml.$(date +%F-%H%M%S).bak 2>/dev/null || true

用途:保留原配置,便于回滚。 判断标准:如果原文件存在,应生成一个带时间戳的备份文件。

第二步:确认 socket 文件是否存在

endpoint 写对了,不代表 socket 一定存在。继续查文件:

bash 复制代码
sudo ls -l /run/containerd/containerd.sock

用途:确认 containerd socket 是否真实存在。 判断标准:正常情况下应看到类似:

bash 复制代码
srw-rw---- 1 root root 0 Jul  2 15:00 /run/containerd/containerd.sock

关注三点:

  • 第一位是 s,说明它是 socket。

  • 路径和 /etc/crictl.yaml 完全一致。

  • sudo 能访问。

如果返回:

bash 复制代码
No such file or directory

不要直接改权限,先判断 containerd 是否运行。

还可以确认 containerd 是否真的监听这个 socket:

bash 复制代码
sudo ss -xl | grep containerd.sock

用途:检查本机 Unix socket 监听状态。 判断标准:能看到 /run/containerd/containerd.sock,说明 socket 被进程监听;如果文件存在但没有监听,继续查服务状态和日志。

第三步:检查 containerd 服务状态

查看服务:

bash 复制代码
sudo systemctl status containerd --no-pager

用途:确认 containerd 是否处于运行状态。 判断标准:Active: active (running) 是基本前提;如果是 failedinactiveactivating,继续看日志,不要只看状态行。

如果服务未运行,先不要立刻在生产节点上反复重启。先看最近日志:

bash 复制代码
sudo journalctl -u containerd -n 200 --no-pager

用途:查看 containerd 最近 200 行日志。 判断标准:重点搜索这些关键词:

关键词 可能方向 下一步
failed to load plugin 插件加载失败,可能是配置或依赖问题 /etc/containerd/config.toml
permission denied 目录、socket、镜像存储权限异常 查目录属主和 SELinux/AppArmor
address already in use socket 或端口被占用 查监听进程
invalid plugin config containerd 配置字段不兼容 备份后修正配置
no space left on device 磁盘满导致运行时异常 清理镜像/日志前先确认影响

需要重启时,先确认维护窗口或至少灰度到单个节点:

bash 复制代码
sudo systemctl restart containerd

用途:让修正后的 containerd 配置重新加载。 判断标准:重启后 sudo systemctl status containerd --no-pager 返回 active (running),并且 sudo crictl info 能返回运行时信息。

生产提醒:重启 containerd 前要评估节点上已有 Pod。不同环境下容器进程是否受影响、kubelet 是否重建 Sandbox、业务是否有 PDB 和多副本,不能靠一句"重启一下"跳过。

第四步:用 debug 模式看 crictl 连接细节

当配置、socket、服务都看起来正常,但 crictl info 仍失败时,打开 debug:

bash 复制代码
sudo crictl --debug info

用途:打印更详细的 CRI 连接过程。 判断标准:关注它实际使用的 endpoint、报错发生在 dial 阶段还是 runtime service 返回阶段。

如果 debug 输出里显示它尝试了多个默认 endpoint,说明 /etc/crictl.yaml 没被正确读取,或者当前用户环境下配置文件不是你以为的那个。此时重新确认:

bash 复制代码
sudo crictl config runtime-endpoint

用途:查看当前 crictl 生效的 runtime endpoint。 判断标准:应返回 unix:///run/containerd/containerd.sock

如果返回为空或不是预期路径,直接设置:

bash 复制代码
sudo crictl config runtime-endpoint unix:///run/containerd/containerd.sock

用途:通过 crictl config 写入 runtime endpoint。 判断标准:再次执行 sudo crictl config runtime-endpoint,确认输出一致。

第五步:对齐 kubelet 使用的 runtime endpoint

有时 crictl 已经能连,但 kubelet 仍报 CRI 连接错误。这个时候要查 kubelet 使用的是不是同一个 endpoint。

先看 kubelet 进程参数:

bash 复制代码
ps -ef | grep '[k]ubelet'

用途:确认 kubelet 是否带了 --container-runtime-endpoint。 判断标准:如果看到参数,应与 crictl 配置一致,例如:

bash 复制代码
--container-runtime-endpoint=unix:///run/containerd/containerd.sock

kubeadm 集群还要看这个文件:

bash 复制代码
sudo cat /var/lib/kubelet/kubeadm-flags.env

用途:检查 kubeadm 写入的 kubelet 启动参数。 判断标准:KUBELET_KUBEADM_ARGS 里不要残留旧 runtime endpoint。

如果修改 kubelet 配置,先备份:

bash 复制代码
sudo cp -a /var/lib/kubelet/kubeadm-flags.env /var/lib/kubelet/kubeadm-flags.env.$(date +%F-%H%M%S).bak

用途:保留 kubelet 参数文件,便于回滚。 判断标准:生成带时间戳的备份文件。

修正后再重启 kubelet:

bash 复制代码
sudo systemctl restart kubelet

用途:让 kubelet 重新读取 runtime endpoint。 判断标准:sudo journalctl -u kubelet -n 100 --no-pager 不再持续出现 CRI 连接错误,节点状态逐步恢复。

命令速查表:按这个顺序跑

顺序 命令 用途 看什么
1 sudo cat /etc/crictl.yaml 查 crictl endpoint 配置 runtime-endpoint 是否指向 containerd socket
2 sudo crictl config runtime-endpoint 查实际生效 endpoint 是否为 unix:///run/containerd/containerd.sock
3 sudo ls -l /run/containerd/containerd.sock 查 socket 文件 文件是否存在,是否是 socket
4 `sudo ss -xl grep containerd.sock` 查 socket 监听 是否有进程监听该 socket
5 sudo systemctl status containerd --no-pager 查服务状态 是否 active (running)
6 sudo journalctl -u containerd -n 200 --no-pager 查 containerd 日志 插件、配置、权限、磁盘错误
7 sudo crictl --debug info 查 crictl 连接细节 实际连接哪个 endpoint,在哪一步失败
8 `ps -ef grep 'kubelet'` 查 kubelet 参数 runtime endpoint 是否一致
9 sudo cat /var/lib/kubelet/kubeadm-flags.env 查 kubeadm 写入参数 是否残留旧 endpoint
10 sudo journalctl -u kubelet -n 100 --no-pager 查 kubelet 侧报错 是否还在报 CRI 连接失败

不建议的处理方式

不要看到 crictl info 失败就直接做这些事:

  • 直接重装 containerd。

  • 直接删除 /run/containerd

  • 在没有备份的情况下改 /etc/containerd/config.toml

  • 把 socket 权限随手改成 777

  • 同时重启 containerd、kubelet、网络插件,导致故障边界被打乱。

更稳的做法是:每次只验证一层,记录命令输出,再决定是否进入下一层。生产环境涉及 containerd 配置、kubelet 参数、socket 权限时,必须先备份、再灰度、最后保留回滚路径。

最小排障路径

可以把这段当成值班时的一页式 checklist:

bash 复制代码
sudo cat /etc/crictl.yaml
sudo crictl config runtime-endpoint
sudo ls -l /run/containerd/containerd.sock
sudo ss -xl | grep containerd.sock
sudo systemctl status containerd --no-pager
sudo journalctl -u containerd -n 200 --no-pager
sudo crictl --debug info
ps -ef | grep '[k]ubelet'
sudo cat /var/lib/kubelet/kubeadm-flags.env
sudo journalctl -u kubelet -n 100 --no-pager

判断顺序也固定:

  1. endpoint 配置不对,先修 /etc/crictl.yaml

  2. socket 不存在,先查 containerd 是否启动。

  3. socket 存在但连接拒绝,查监听和服务状态。

  4. 服务 running 但仍失败,查 containerd 日志和 debug 输出。

  5. crictl 正常但 kubelet 异常,查 kubelet runtime endpoint 是否一致。

参考资料

相关推荐
AKAMAI3 天前
每百万 Token 成本砍六成,出海 AI 团队开始重算推理这笔账
人工智能·云计算
tiancaijiben16 天前
阿里云Kubernetes集群托管完全指南:从创建到生产级运维
云计算
互联网推荐官16 天前
上海软件定制开发公司推荐:从PaaS工程化路径看D-coding的技术取舍
云原生·云计算·paas·软件开发·开发经验·上海
sbjdhjd16 天前
从零搭建企业级 CI/CD(下):Jenkins+GitLab+Harbor 全链路实战指南
git·servlet·ci/cd·云原生·云计算·gitlab·jenkins
tiancaijiben16 天前
阿里云应用实时监控服务ARMS完全接入指南:从探针部署到全链路可观测
云计算
xingyuzhisuan17 天前
算力租赁平台 GPU 资源隔离方案:显存抢占问题深度排查与解决
大数据·云计算·gpu算力
workbuddy小能手17 天前
腾讯云ADP Agent Portal vs 自建智能体:架构选型对比
架构·云计算·腾讯云
宸津-代码粉碎机17 天前
Spring AI 企业级实战|智能记忆摘要+自动遗忘机制落地,彻底解决上下文爆炸与Token冗余
java·大数据·人工智能·后端·python·spring·云计算