crictl 实战指南:没有 docker 命令后,Kubernetes 节点该怎么排障? 📅 2026/7/3 1:01:39 docker 命令没了不代表节点不能查生产节点上最常见的卡点不是“不会 Kubernetes”而是值班时习惯性敲docker ps结果返回bash: docker: command not found或者 Docker 服务根本不存在。此时很多人会转去看kubectl get pod但kubectl只能告诉你集群对象状态不一定能回答节点上的容器运行时到底发生了什么。比如 Pod 一直ContainerCreating、节点日志里出现 CRI 错误、镜像已经拉下来了但容器没有起来这些问题最终都要落到 kubelet 和容器运行时之间的 CRI 层。在 containerd 节点上crictl就是这个入口。它不是 Docker 的完整替代品也不是 containerd 的万能管理工具。更准确地说crictl是直接面向 CRI 的排障工具看 Pod Sandbox、容器、镜像、日志、运行时信息验证 kubelet 看到的运行时状态是否正常。本文按生产排障顺序写先讲工具边界再配置 endpoint然后给出从docker迁移到crictl的命令表最后给出常见错误和节点排障最小命令集。概念边界kubectl、crictl、ctr 分别看什么先把边界划清楚后面的命令才不会乱用。工具主要连接对象适合查看什么不适合做什么kubectlkube-apiserverPod、Node、Event、Deployment 等集群对象直接判断节点本地 CRI socket 是否可用crictlkubelet 使用的 CRI endpointPod Sandbox、容器、镜像、容器日志、运行时信息管理非 CRI 视角下的 containerd 内部对象ctrcontainerd daemonnamespace、content、snapshot、底层镜像对象替代 kubelet/CRI 做日常 Kubernetes 排障journalctlsystemd 日志kubelet、containerd 服务错误直接列出 Pod 和容器对象一个实用判断先用kubectl判断“集群认为它是什么状态”。再用crictl判断“节点运行时实际有什么”。只有当crictl看不到、但你怀疑 containerd 内部状态异常时再用ctr深挖。不要一上来就用ctr替代crictl。Kubernetes 通过 CRI 管理 Pod 和容器crictl的视角更接近 kubelet。第一步确认 crictl 连接的是 kubelet 使用的 runtime endpointcrictl好不好用第一步看/etc/crictl.yaml。如果 endpoint 指错了后面所有命令都会误导你。推荐配置如下runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false pull-image-on-create: false disable-pull-on-run: false写入或修正配置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 pull-image-on-create: false disable-pull-on-run: false EOF用途固定crictl使用 containerd 的 CRI socket避免它逐个尝试默认 endpoint 造成误判。 判断标准后续sudo crictl info能返回runtimeType、runtimeName、lastCNILoadStatus等字段。确认配置内容sudo cat /etc/crictl.yaml用途检查runtime-endpoint和image-endpoint是否都是unix:///run/containerd/containerd.sock。 判断标准不要混入旧 Docker shim 路径也不要写成不存在的 socket。确认 socket 文件存在sudo ls -l /run/containerd/containerd.sock用途判断 containerd CRI socket 是否真实存在。 判断标准能看到 socket 文件且权限允许 root 访问如果显示No such file or directory先查 containerd 是否启动和配置是否加载 CRI 插件。确认 containerd 服务状态sudo systemctl status containerd --no-pager用途判断 containerd 是否正在运行。 判断标准Active: active (running)是基本前提如果是 failed、activating、inactive先看服务日志。查看 containerd 最近日志sudo journalctl -u containerd -n 200 --no-pager用途定位 CRI 插件、镜像仓库、snapshotter、shim 启动错误。 判断标准重点看failed、error、CRI、snapshotter、failed to start shim、failed to pull等关键词。第二步用 crictl info 判断 CRI 是否可用先不要急着查容器。最小入口是sudo crictl info用途确认crictl可以通过 CRI 连接 containerd并读取运行时状态。 判断标准输出 JSON 中应出现运行时信息和 CNI 状态。重点看runtimeName: containerd runtimeType: io.containerd.runc.v2 lastCNILoadStatus: OK networkReady: true如果crictl info失败先不要继续执行crictl ps。按这个顺序查报错现象常见原因检查命令下一步connection refusedcontainerd 未运行或 socket 不可用sudo systemctl status containerd --no-pager修复服务启动错误no such file or directoryendpoint 路径写错或 socket 不存在sudo ls -l /run/containerd/containerd.sock修正/etc/crictl.yaml或检查 containerdcontext deadline exceededruntime 卡死、IO 卡住或服务响应慢sudo journalctl -u containerd -n 200 --no-pager查 shim、snapshotter、磁盘、镜像拉取错误permission denied非 root 用户无权访问 socketls -l /run/containerd/containerd.sock用sudo执行或调整受控运维权限第三步把 docker 命令习惯迁移到 crictl/kubectl下面这张表可以直接收藏。生产排障时不要只找“等价命令”要同时看对象层级Kubernetes 里先有 Pod Sandbox再有容器。Docker 习惯crictl 命令kubectl 命令适用场景docker pssudo crictl pskubectl get pod -A -o wide看正在运行的容器和 Pod 分布docker ps -asudo crictl ps -akubectl describe pod -n ns pod看退出、创建中、异常容器docker logs idsudo crictl logs container_idkubectl logs -n ns pod -c container看容器 stdout/stderrdocker inspect idsudo crictl inspect container_idkubectl get pod -n ns pod -o yaml看容器运行时详情无直接常用习惯sudo crictl podskubectl get pod -A看 Pod Sandbox无直接常用习惯sudo crictl inspectp pod_idkubectl describe pod -n ns pod看 Sandbox 网络和元数据docker imagessudo crictl images不适用看节点本地 CRI 镜像列表docker pull nginx:1.25sudo crictl pull nginx:1.25kubectl create deployment触发拉取验证节点能否拉镜像docker exec -it id shsudo crictl exec -it container_id shkubectl exec -n ns -it pod -c container -- sh进入容器优先用kubectl execdocker rm/docker rmisudo crictl rm/sudo crictl rmi通常不建议直接删清理异常对象生产需谨慎注意生产集群里不要随手crictl rm、crictl rmi。如果 kubelet 仍在管理对应 Pod手工删除会被重新拉起或造成状态跳变。清理前至少确认 Pod 归属、业务窗口和回滚路径。第四步查看 Pod SandboxKubernetes 里每个 Pod 通常会先创建 Pod Sandbox。Pod 网络、命名空间和 pause 容器相关问题经常先体现在 Sandbox 层。sudo crictl pods用途列出节点上的 Pod Sandbox。 判断标准目标 Pod 应该能在列表中看到STATE通常应为Ready。如果 Pod 在 apiserver 里存在但节点上没有对应 Sandbox要继续看 kubelet 和 containerd 日志。按命名空间或 Pod 名过滤sudo crictl pods --name pod_name用途快速找到目标 Pod 的 Sandbox ID。 判断标准输出里NAMESPACE、NAME、STATE与目标 Pod 对得上。查看 Sandbox 详情sudo crictl inspectp pod_sandbox_id用途查看 Pod Sandbox 的元数据、网络状态、标签和创建信息。 判断标准重点看metadata.name、metadata.namespace、state、network、labels确认它是不是你要查的 Pod。如果crictl pods看不到目标 Pod按顺序查kubectl get pod -n ns pod -o wide确认 Pod 是否已调度到当前节点。kubectl describe pod -n ns pod看 Events 是否卡在调度、拉镜像、创建 Sandbox。sudo journalctl -u kubelet -n 200 --no-pager看 kubelet 是否向 runtime 发起创建。sudo journalctl -u containerd -n 200 --no-pager看 containerd 是否创建 Sandbox 失败。第五步查看容器状态查看正在运行的容器sudo crictl ps用途列出当前运行中的容器。 判断标准目标业务容器应为Running如果 Pod Ready 但这里没有容器要检查是否查错节点或查错 namespace。查看所有容器包括退出和创建失败的sudo crictl ps -a用途排查CrashLoopBackOff、创建失败、退出过快的容器。 判断标准重点看STATE、ATTEMPT、POD ID。同一个容器多次 attempt 增长说明 kubelet 一直重启它。按 Pod Sandbox ID 过滤容器sudo crictl ps -a --pod pod_sandbox_id用途只看某个 Pod 下的容器避免节点上容器太多。 判断标准能看到 init container、业务 container 的状态差异如果 init container 失败主容器通常不会启动。查看容器详情sudo crictl inspect container_id用途查看容器配置、状态、退出码、挂载、标签和运行时信息。 判断标准重点看status.state、status.exitCode、status.reason、info.runtimeSpec.mounts、labels。第六步查看日志与进入容器查看容器日志sudo crictl logs container_id用途直接读取容器 stdout/stderr。 判断标准适合查应用启动失败、参数错误、依赖连接失败如果没有输出要确认容器是否已经启动过以及日志是否写到了文件而不是 stdout。查看最近 100 行sudo crictl logs --tail100 container_id用途避免日志过大影响排障效率。 判断标准先看最近错误再决定是否扩大范围。进入容器sudo crictl exec -it container_id sh用途在节点本地进入容器。 判断标准容器必须处于运行状态镜像里也必须有sh或对应 shell。生产优先使用kubectl exec只有控制面访问受限或需要节点本地验证时再用crictl exec。优先推荐的 Kubernetes 入口kubectl exec -n namespace -it pod_name -c container_name -- sh用途从集群 API 视角进入容器审计和权限边界更清楚。 判断标准适合常规业务排障如果 apiserver 不通再考虑节点侧crictl exec。第七步查看镜像与拉取问题查看节点本地 CRI 镜像sudo crictl images用途确认镜像是否已经被 runtime 拉到节点。 判断标准目标镜像 tag 或 digest 应出现在列表中如果没有继续查 Pod Events 和 containerd 拉取日志。拉取镜像验证仓库链路sudo crictl pull nginx:1.25用途验证当前节点能否通过 CRI 拉取镜像。 判断标准成功会显示镜像拉取完成失败时根据错误判断 DNS、TLS、认证、镜像不存在还是仓库不可达。查看镜像详情sudo crictl inspecti nginx:1.25用途确认镜像 ID、repoTags、repoDigests、size、uid/gid 等信息。 判断标准如果业务要求固定 digest重点看repoDigests是否符合发布记录。删除确认无用镜像sudo crictl rmi image_id_or_ref用途释放节点磁盘或清理错误镜像。 判断标准生产执行前先确认没有运行中 Pod 依赖该镜像建议先用crictl ps -a和crictl inspect交叉确认。第八步常见故障与判断路径现象先看哪里命令判断标准Pod 一直ContainerCreatingEvents 与 Sandboxkubectl describe pod -n ns pod、sudo crictl podsEvents 里是否有 Sandbox、CNI、镜像拉取错误crictl info失败endpoint 和 socketsudo cat /etc/crictl.yaml、sudo ls -l /run/containerd/containerd.sockendpoint 存在且指向 containerd socket容器反复重启容器 attempt 和日志sudo crictl ps -a --pod pod_id、sudo crictl logs container_idattempt 增长日志中有启动失败原因镜像拉不下来镜像列表和 containerd 日志sudo crictl pull image、sudo journalctl -u containerd -n 200 --no-pager判断是 DNS、TLS、认证、仓库地址还是镜像不存在kubectl 看到 Podcrictl 看不到调度节点和 kubeletkubectl get pod -n ns pod -o wide、sudo journalctl -u kubelet -n 200 --no-pager确认 Pod 是否真的调度到当前节点crictl 能看见容器业务仍不通Pod 网络和应用日志sudo crictl inspectp pod_id、sudo crictl logs container_id先区分容器启动失败、网络失败、应用健康检查失败生产排障时最容易犯的错是只看一个层面。kubectl get pod显示Pending、ContainerCreating、CrashLoopBackOff只是入口真正原因往往需要结合 kubelet 日志、containerd 日志、CRI 对象状态和镜像拉取错误。节点排障最小命令集下面这组命令适合直接做成值班手册。执行前先确认你在目标节点上且具备对应运维权限。kubectl get pod -A -o wide | grep node_name用途确认哪些 Pod 调度到目标节点。 判断标准目标 Pod 的NODE字段必须是当前要排查的节点。kubectl describe pod -n namespace pod_name用途查看 Pod Events、容器状态和调度信息。 判断标准先定位是调度、镜像、Sandbox、探针还是应用退出。sudo crictl info用途确认 CRI runtime 可访问。 判断标准能返回 containerd 运行时信息和 CNI 状态。sudo crictl pods --name pod_name用途定位 Pod Sandbox ID。 判断标准能看到目标 Pod 的 Sandbox且 namespace 匹配。sudo crictl ps -a --pod pod_sandbox_id用途查看该 Pod 下所有容器状态。 判断标准区分 init container、业务容器、退出容器和重启次数。sudo crictl logs --tail100 container_id用途查看容器最近日志。 判断标准重点找启动失败、配置缺失、依赖不可达、权限拒绝等明确错误。sudo crictl inspect container_id用途查看容器 runtime 详情。 判断标准看退出码、挂载、标签、Pod 归属和 runtimeSpec。sudo crictl inspectp pod_sandbox_id用途查看 Pod Sandbox 详情。 判断标准看网络、namespace、metadata、labels 是否符合预期。sudo crictl images用途查看节点本地镜像列表。 判断标准目标镜像 tag/digest 是否存在。sudo journalctl -u kubelet -n 200 --no-pager用途查看 kubelet 与 CRI 交互错误。 判断标准重点看FailedCreatePodSandBox、CreateContainer、ImagePull、PLEG、runtime。sudo journalctl -u containerd -n 200 --no-pager用途查看 containerd 服务层错误。 判断标准重点看failed to pull、failed to start shim、snapshotter、permission denied、certificate。一页式 checklist检查项命令正常结果异常时下一步Pod 是否在本节点kubectl get pod -A -o wideNODE是当前节点查调度、污点、资源CRI 是否可连接sudo crictl info返回 containerd 信息查/etc/crictl.yaml和 socketSandbox 是否存在sudo crictl pods --name pod有目标 Sandbox查 kubelet 创建 Sandbox 日志容器是否启动sudo crictl ps -a --pod pod_id业务容器Running查退出码和日志日志是否有明确错误sudo crictl logs container_id无启动异常查应用配置、依赖、探针镜像是否存在sudo crictl images目标镜像存在查仓库、TLS、认证、DNSkubelet 是否报 CRI 错sudo journalctl -u kubelet -n 200 --no-pager无 runtime 错误对照 Events 修复containerd 是否报底层错sudo journalctl -u containerd -n 200 --no-pager无 shim/pull/snapshotter 错误查运行时、磁盘、仓库生产注意事项不要把crictl当成业务发布工具。它适合排障不适合绕过 Kubernetes 控制面管理生产容器。不要在未确认归属的情况下执行crictl rm、crictl rmi。先确认 Pod、namespace、业务窗口和是否会被 kubelet 重建。涉及 containerd 配置变更时先备份sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.$(date %F-%H%M%S).bak用途修改 containerd 配置前保留回滚点。 判断标准备份文件存在且可读。重启 containerd 前先评估节点上的工作负载。生产建议先 cordon 节点再按业务窗口灰度处理kubectl cordon node_name用途阻止新的 Pod 调度到该节点。 判断标准kubectl get node node_name显示SchedulingDisabled。需要重启服务时先在测试节点验证再灰度到生产sudo systemctl restart containerd用途让 containerd 重新加载配置或恢复异常服务。 判断标准执行后sudo systemctl status containerd --no-pager为 running且关键 Pod 状态恢复。生产执行前必须确认回滚方案。总结没有 Docker 命令后节点排障入口不是消失了而是从 Docker daemon 视角切换到了 Kubernetes CRI 视角。一条可靠路径是用kubectl确认集群对象和 Pod 调度节点。用crictl info确认 CRI endpoint 可用。用crictl pods看 Pod Sandbox。用crictl ps -a看容器状态。用crictl logs、inspect、inspectp定位容器和 Sandbox 细节。用journalctl -u kubelet、journalctl -u containerd收敛到服务层错误。把这条链路跑熟后docker ps不存在不会影响你排障反而会逼你更接近 Kubernetes 真实的运行时边界。参考资料Kubernetes 官方文档Debugging Kubernetes nodes with crictl Debugging Kubernetes nodes with crictl | KubernetesKubernetes 官方文档Container Runtimes Container Runtimes | Kubernetescri-tools / crictl GitHub 仓库 https://github.com/kubernetes-sigs/cri-toolscontainerd 官方文档 containerd docs – containerd Overview