crictl info 连不上 containerd 怎么办?endpoint、socket 与权限一次查清
crictl info 报错先别急着重启 kubelet这类问题通常发生在三个场景新装 Kubernetes 节点后执行sudo crictl info直接报错。Docker 迁移到 containerd 后原来能查容器的节点突然查不到运行时信息。kubelet 日志里出现 CRI 连接异常手动用crictl验证也连不上。最常见的报错长这样FATA[0000] connect: no such file or directory或者FATA[0000] connect: connection refused还有一种更容易误判FATA[0000] permission denied这三类报错看起来都像“containerd 坏了”但原因可能完全不同。生产环境里不要一上来就重启 kubelet、重装 containerd先把路径走完配置 - socket - 服务 - 日志 - kubelet 端点。如果你还不熟悉kubectl、crictl、ctr的边界建议先阅读当天 A 篇[[2026-07-02 A crictl 实战指南没有 docker 命令后Kubernetes 节点该怎么排障]]。本文只聚焦一个单点问题crictl info连不上 containerd 时怎么定位。先划边界crictl 连的是 CRI endpoint不是随便一个 containerd 路径crictl不是直接替代docker的通用客户端它面向的是 CRI endpoint。对 containerd 节点来说常见 endpoint 是unix:///run/containerd/containerd.sock这个 endpoint 要同时满足三个条件/etc/crictl.yaml里写的是这个 endpoint。/run/containerd/containerd.sock这个 socket 文件真实存在。containerd 正在运行并且 CRI 插件能提供服务。一张表先定位报错方向报错或现象常见原因先跑的命令判断标准处理方向no such file or directoryendpoint 路径写错或 socket 不存在sudo cat /etc/crictl.yamlruntime-endpoint是否指向真实 socket修正/etc/crictl.yaml再查 socketno such file or directorycontainerd 没有创建 socketsudo ls -l /run/containerd/containerd.sock文件是否存在类型是否为 socket检查 containerd 服务和日志connection refusedsocket 存在但服务未正常监听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 [k]ubelet--container-runtime-endpoint是否一致修正 kubelet 配置后灰度重启第一步检查/etc/crictl.yaml先看crictl到底准备连哪里sudo cat /etc/crictl.yaml用途确认runtime-endpoint和image-endpoint。 判断标准containerd 节点通常应看到下面这种配置runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false如果文件不存在或者 endpoint 还是旧路径例如 Docker shim 时代的路径就先补齐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。生产提醒如果这是别人维护的节点修改前先备份sudo cp -a /etc/crictl.yaml /etc/crictl.yaml.$(date %F-%H%M%S).bak 2/dev/null || true用途保留原配置便于回滚。 判断标准如果原文件存在应生成一个带时间戳的备份文件。第二步确认 socket 文件是否存在endpoint 写对了不代表 socket 一定存在。继续查文件sudo ls -l /run/containerd/containerd.sock用途确认 containerd socket 是否真实存在。 判断标准正常情况下应看到类似srw-rw---- 1 root root 0 Jul 2 15:00 /run/containerd/containerd.sock关注三点第一位是s说明它是 socket。路径和/etc/crictl.yaml完全一致。用sudo能访问。如果返回No such file or directory不要直接改权限先判断 containerd 是否运行。还可以确认 containerd 是否真的监听这个 socketsudo ss -xl | grep containerd.sock用途检查本机 Unix socket 监听状态。 判断标准能看到/run/containerd/containerd.sock说明 socket 被进程监听如果文件存在但没有监听继续查服务状态和日志。第三步检查 containerd 服务状态查看服务sudo systemctl status containerd --no-pager用途确认 containerd 是否处于运行状态。 判断标准Active: active (running)是基本前提如果是failed、inactive、activating继续看日志不要只看状态行。如果服务未运行先不要立刻在生产节点上反复重启。先看最近日志sudo journalctl -u containerd -n 200 --no-pager用途查看 containerd 最近 200 行日志。 判断标准重点搜索这些关键词关键词可能方向下一步failed to load plugin插件加载失败可能是配置或依赖问题查/etc/containerd/config.tomlpermission denied目录、socket、镜像存储权限异常查目录属主和 SELinux/AppArmoraddress already in usesocket 或端口被占用查监听进程invalid plugin configcontainerd 配置字段不兼容备份后修正配置no space left on device磁盘满导致运行时异常清理镜像/日志前先确认影响需要重启时先确认维护窗口或至少灰度到单个节点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仍失败时打开 debugsudo crictl --debug info用途打印更详细的 CRI 连接过程。 判断标准关注它实际使用的 endpoint、报错发生在 dial 阶段还是 runtime service 返回阶段。如果 debug 输出里显示它尝试了多个默认 endpoint说明/etc/crictl.yaml没被正确读取或者当前用户环境下配置文件不是你以为的那个。此时重新确认sudo crictl config runtime-endpoint用途查看当前crictl生效的 runtime endpoint。 判断标准应返回unix:///run/containerd/containerd.sock。如果返回为空或不是预期路径直接设置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 进程参数ps -ef | grep [k]ubelet用途确认 kubelet 是否带了--container-runtime-endpoint。 判断标准如果看到参数应与crictl配置一致例如--container-runtime-endpointunix:///run/containerd/containerd.sockkubeadm 集群还要看这个文件sudo cat /var/lib/kubelet/kubeadm-flags.env用途检查 kubeadm 写入的 kubelet 启动参数。 判断标准KUBELET_KUBEADM_ARGS里不要残留旧 runtime endpoint。如果修改 kubelet 配置先备份sudo cp -a /var/lib/kubelet/kubeadm-flags.env /var/lib/kubelet/kubeadm-flags.env.$(date %F-%H%M%S).bak用途保留 kubelet 参数文件便于回滚。 判断标准生成带时间戳的备份文件。修正后再重启 kubeletsudo systemctl restart kubelet用途让 kubelet 重新读取 runtime endpoint。 判断标准sudo journalctl -u kubelet -n 100 --no-pager不再持续出现 CRI 连接错误节点状态逐步恢复。命令速查表按这个顺序跑顺序命令用途看什么1sudo cat /etc/crictl.yaml查 crictl endpoint 配置runtime-endpoint是否指向 containerd socket2sudo crictl config runtime-endpoint查实际生效 endpoint是否为unix:///run/containerd/containerd.sock3sudo ls -l /run/containerd/containerd.sock查 socket 文件文件是否存在是否是 socket4sudo ss -xl | grep containerd.sock查 socket 监听是否有进程监听该 socket5sudo systemctl status containerd --no-pager查服务状态是否active (running)6sudo journalctl -u containerd -n 200 --no-pager查 containerd 日志插件、配置、权限、磁盘错误7sudo crictl --debug info查 crictl 连接细节实际连接哪个 endpoint在哪一步失败8ps -ef | grep [k]ubelet查 kubelet 参数runtime endpoint 是否一致9sudo cat /var/lib/kubelet/kubeadm-flags.env查 kubeadm 写入参数是否残留旧 endpoint10sudo 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 权限时必须先备份、再灰度、最后保留回滚路径。最小排障路径可以把这段当成值班时的一页式 checklistsudo 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判断顺序也固定endpoint 配置不对先修/etc/crictl.yaml。socket 不存在先查 containerd 是否启动。socket 存在但连接拒绝查监听和服务状态。服务 running 但仍失败查 containerd 日志和 debug 输出。crictl 正常但 kubelet 异常查 kubelet runtime endpoint 是否一致。参考资料Kubernetes 官方文档Debugging Kubernetes nodes with crictlDebugging Kubernetes nodes with crictl | Kubernetescri-tools 项目crictl 使用与配置https://github.com/kubernetes-sigs/cri-toolscontainerd 项目文档https://github.com/containerd/containerd