
先说结论升级前别急着改包源生产环境里升级失败很少只因为“版本装不上”。更常见的是节点升级后containerd看起来是running但 kubelet 连不上 CRIPod 卡在ContainerCreating最后发现 pause 镜像拉不到节点变成NotReady根因是 kubelet 和 containerd 的 cgroup driver 没对齐。今天 A 篇已经把升级链路讲完整[[2026-07-01 Kubernetes 1.36 containerd 2.3 生产升级实战CRI、版本兼容与避坑清单]]。这篇 B 篇只做一件事把升级前最该跑的检查命令整理成一张可执行清单。执行顺序建议固定为先确认升级对象控制面、kubelet、containerd 当前版本。再确认控制面看到的节点状态是否可信。接着检查 kubelet 到 containerd 的 CRI 入口。然后看 containerd 配置、pause 镜像、cgroup。最后看日志和备份条件确认可以灰度、可以回滚。组件边界这 12 条命令到底覆盖哪条链路升级前检查的对象不是单个二进制而是这条链路kubectl / apiserver - kubelet - CRI endpoint - containerd - runc / snapshotter / Pod sandboxkubectl get nodes看到的是控制面视角crictl info看到的是 CRI 视角containerd config dump看到的是运行时配置视角journalctl看到的是服务现场。它们不能互相替代。1.kubectl versionkubectl version用途确认客户端和服务端版本避免拿错误 kubeconfig 或错误 kubectl 客户端操作生产集群。重点看Server Version是不是这次计划升级的控制面基线。Client Version是否明显落后尤其是跨多个小版本时不要直接拿旧客户端做关键变更。异常判断如果命令连不上 apiserver先处理访问、证书或 kubeconfig 问题不要进入节点升级。如果客户端和服务端版本偏差过大先换匹配版本的kubectl再继续检查。2.kubelet --versionkubelet --version用途确认当前节点 kubelet 版本判断节点是否已经被人手工升级过或者不同批次节点版本是否混乱。正常现象同一升级批次内节点版本一致且符合 Kubernetes 版本偏差策略。异常判断同一批次里 kubelet 版本不一致先分组不要全量一起升级。如果节点上没有kubelet命令或路径异常先确认发行版安装方式和 systemd 单元文件。3.containerd --versioncontainerd --version用途确认当前 containerd 版本和打包来源避免目标版本、OS 仓库、节点实际版本三者不一致。重点看版本号是否符合升级计划。是否来自发行版仓库、官方包、还是历史手工安装。异常判断如果containerd不存在但节点仍上报 containerd runtime先用systemctl status containerd和which containerd查路径。如果不同节点版本散乱先记录版本盘点表再决定升级批次。4.kubectl get nodes -o widekubectl get nodes -o wide用途从控制面视角确认节点状态、kubelet 版本、节点 IP、OS 镜像和容器运行时汇报。重点看STATUS是否全是Ready。VERSION是否和节点本机kubelet --version对得上。CONTAINER-RUNTIME是否显示预期运行时例如containerd://...。异常判断已经存在NotReady节点时先排障不要把升级和旧故障混在一起。控制面看到的 runtime 和节点本机不一致优先查 kubelet 汇报和 CRI endpoint。5.kubectl describe node node-namekubectl describe node node-name用途确认 Node Conditions、Events、资源压力和 kubelet 最近上报的异常。重点看Ready、MemoryPressure、DiskPressure、PIDPressure、NetworkUnavailable。Events 里是否有PLEG、container runtime、cgroup、image、network相关提示。异常判断有资源压力时先处理磁盘、inode、内存或 PID 问题。有 runtime 相关 Event 时继续跑第 6 到第 12 条命令定位 CRI、containerd 和日志。CRI 入口检查先确认 kubelet 连的是谁6.cat /etc/crictl.yamlcat /etc/crictl.yaml用途确认crictl默认连接哪个 CRI endpoint。虽然 kubelet 不一定直接读取这个文件但它能帮你快速发现节点上常用排障入口是否还指向旧 runtime。建议内容runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false正常现象runtime-endpoint和image-endpoint都指向 containerd socket。异常判断如果还指向 Docker shim、CRI-O 或不存在的 socket先修正/etc/crictl.yaml否则后面的crictl info结论不可信。修改前保留旧文件cp -a /etc/crictl.yaml /etc/crictl.yaml.$(date %F-%H%M%S).bak。7.ls -l /run/containerd/containerd.sockls -l /run/containerd/containerd.sock用途确认 containerd CRI socket 文件是否存在以及权限是否异常。正常现象能看到一个 socket 文件通常类似srw-rw---- 1 root root ... /run/containerd/containerd.sock异常判断No such file or directory先查systemctl status containerd再看 containerd 是否启动失败。权限异常普通用户跑crictl失败不代表 CRI 不通生产节点建议用sudo crictl info验证。8.sudo crictl infosudo crictl info用途直接验证 CRI 连通性确认 kubelet 所依赖的 runtime 信息能被正常返回。正常现象返回 JSON能看到 runtime、config、sandbox image、cgroup、snapshotter 等信息。异常判断connection refused优先查 socket 和 containerd 服务状态。context deadline exceeded查 containerd 是否卡死、节点 IO 是否异常、CRI 插件是否可用。no such file or directory回到第 6、7 条检查 endpoint 和 socket 路径。containerd 配置检查服务 running 不代表配置正确9.sudo containerd config dump | grep -n sandbox_imagesudo containerd config dump | grep -n sandbox_image用途确认 Pod Sandbox 使用的 pause 镜像。升级后 Pod 卡在ContainerCreating常见原因之一就是 pause 镜像不可达。正常现象sandbox_image指向当前网络环境可拉取的镜像地址企业环境里最好是内网 registry 或已验证的 mirror。异常判断指向外网且节点不能访问时先配置 mirror 或私有仓库。指向历史私仓但镜像已被清理时先补镜像再升级。10.sudo containerd config dump | grep -n SystemdCgroup -A 5 -B 5sudo containerd config dump | grep -n SystemdCgroup -A 5 -B 5用途确认 containerd 侧 runtime 的 cgroup 配置避免 kubelet 和 containerd 在 cgroup driver 上不一致。正常现象containerd 侧配置与 kubelet 侧cgroupDriver对齐。使用 systemd 的生产节点通常应让 kubelet 和 containerd 都走 systemd cgroup。异常判断如果 containerd 是SystemdCgroup false但 kubelet 是systemd不要直接全量改。先选单节点 drain备份配置灰度重启再验证 Pod 创建。如果输出里找不到字段先确认 containerd 配置版本和 runtime 配置路径不要按旧版本路径硬改。11.grep -n cgroupDriver /var/lib/kubelet/config.yamlgrep -n cgroupDriver /var/lib/kubelet/config.yaml用途确认 kubelet 使用的 cgroup driver。正常现象能看到类似cgroupDriver: systemd异常判断如果文件不存在先用systemctl cat kubelet查 kubelet 启动参数确认--config指向哪里。如果 kubelet 和 containerd 不一致先备份/var/lib/kubelet/config.yaml和/etc/containerd/config.toml再灰度修正。日志检查升级前先看最近 200 行12.journalctl -u kubelet -n 200 --no-pagerjournalctl -u kubelet -n 200 --no-pager用途确认升级前 kubelet 是否已经持续报错。已有故障不处理升级后只会把问题扩大。重点看关键词PLEGcontainer runtimeCRIcgroupfailed to create pod sandboxImagePullBackOffx509NetworkPluginNotReady异常判断看到 CRI 或 runtime 错误回到第 6 到第 10 条。看到镜像拉取或证书错误先处理 registry、mirror、CA 或 imagePullSecret。看到 CNI 错误先查 CNI 配置和插件不要把问题归因到 containerd 升级。补充命令systemctl status containerd --no-pager journalctl -u containerd -n 200 --no-pager用途确认 containerd 是否反复重启是否有 registry、snapshotter、runtime、shim 相关错误。配置变更前必须做的备份只要涉及/etc/containerd、/var/lib/kubelet/config.yaml、systemd drop-in 或 runtime endpoint升级前必须先保留现场。sudo mkdir -p /root/k8s-upgrade-backup/$(date %F)用途创建当天备份目录。sudo cp -a /etc/containerd /root/k8s-upgrade-backup/$(date %F)/containerd用途备份 containerd 配置、证书目录和 registry 配置。sudo cp -a /var/lib/kubelet/config.yaml /root/k8s-upgrade-backup/$(date %F)/kubelet-config.yaml用途备份 kubelet 主配置。sudo systemctl cat kubelet /root/k8s-upgrade-backup/$(date %F)/kubelet-systemd.txt sudo systemctl cat containerd /root/k8s-upgrade-backup/$(date %F)/containerd-systemd.txt用途保留 systemd 启动参数和 drop-in 现场便于回滚对比。sudo crictl info /root/k8s-upgrade-backup/$(date %F)/crictl-info-before.json sudo containerd config dump /root/k8s-upgrade-backup/$(date %F)/containerd-config-before.toml用途保留 CRI 和 containerd 生效配置而不只是备份静态文件。一页式升级前检查表检查项命令正常现象异常现象下一步控制面版本kubectl version客户端、服务端版本符合升级计划连不上 apiserver或版本偏差过大先确认 kubeconfig、证书和版本偏差规则kubelet 版本kubelet --version同批节点版本清楚可分批管理节点版本散乱先按版本分组不要全量升级containerd 版本containerd --version当前版本和来源明确包源、目标版本、实际版本不一致先确认 OS 仓库和安装方式节点列表kubectl get nodes -o wide节点 Readyruntime 汇报为预期 containerdNotReady 或 runtime 汇报异常先查 kubelet 汇报和 CRINode 详情kubectl describe node node-nameConditions 正常无持续异常 EventsPressure、PLEG、runtime、CNI 异常先解决现有故障CRI endpointcat /etc/crictl.yaml指向unix:///run/containerd/containerd.sock指向旧 Docker/CRI-O socket 或空配置修正 endpoint 后再验证socket 文件ls -l /run/containerd/containerd.socksocket 存在且权限合理文件不存在或权限异常查 containerd 服务和启动日志CRI 连通性sudo crictl info返回 runtime 信息refused、timeout、no such file查 endpoint、socket、服务和 CRI 插件pause 镜像containerd config dump | grep sandbox_image镜像地址可从节点拉取外网不可达或私仓缺镜像配置 mirror/私仓并先验证拉取containerd cgroupcontainerd config dump | grep SystemdCgroup与 kubelet cgroup driver 对齐SystemdCgroup与 kubelet 不一致先单节点灰度修正kubelet cgroupgrep cgroupDriver /var/lib/kubelet/config.yaml与 containerd 侧一致文件缺失或配置不一致查 kubelet--config备份后修正kubelet 日志journalctl -u kubelet -n 200 --no-pager无持续 runtime、CRI、cgroup、image 错误PLEG、CRI、cgroup、镜像错误持续出现先排障再进入升级窗口异常怎么判断如果 12 条命令里有异常先按下面顺序处理不要直接进入升级异常类型常见信号先查什么处理建议版本不一致kubectl get nodes与本机版本不一致kubelet --version、节点分组拆批次先升一组不要混合全量升级CRI 连不上crictl inforefused / timeout/etc/crictl.yaml、socket、systemctl status containerd先修 endpoint 或服务再继续cgroup 不对齐kubelet 是systemdcontainerd 不是kubelet config、containerd runtime 配置备份后单节点灰度修正pause 镜像不可达Pod sandbox 创建失败sandbox_image、crictl pull、containerd 日志配置 mirror 或私仓镜像日志已有错误PLEG、runtime、CNI、image pull 持续出现kubelet/containerd 最近 200 行日志先排障不把旧故障带进升级发布前执行 checklist12 条命令已在每一类节点上跑过控制面节点、普通工作节点、GPU/特殊运行时节点。节点按版本、OS、运行时、业务重要性分组升级批次清楚。/etc/containerd、/var/lib/kubelet/config.yaml、systemd drop-in 已备份。crictl info和containerd config dump的升级前输出已保存。pause 镜像、业务镜像、Harbor/mirror、CA 证书在节点侧验证过。kubelet 和 containerd 日志没有持续 CRI、PLEG、cgroup、镜像拉取错误。已确定 drain、升级、验证、uncordon、回滚的操作人和窗口。总结升级 Kubernetes 和 containerd 之前最怕的是“以为只是升级包实际上动了整条运行时链路”。这 12 条命令的价值不在于复杂而在于把升级前最容易漏的入口固定下来版本、节点、CRI、containerd 配置、cgroup、日志和备份。建议把本文作为升级窗口前的执行单。只有当这些检查都能解释清楚才进入 drain、升级、重启、验证和放量。遇到不一致不要用“具体情况具体分析”糊过去先定位到版本、CRI、cgroup、镜像仓库或日志其中一层再决定是否继续。下一篇建议阅读crictl 实战指南没有 docker 命令后Kubernetes 节点该怎么排障参考资料Kubernetes 文档Container RuntimesContainer Runtimes | KubernetesKubernetes 文档Debugging Kubernetes nodes with crictlDebugging Kubernetes nodes with crictl | KubernetesKubernetes 文档Version Skew PolicyVersion Skew Policy | Kubernetescontainerd 文档CRI plugin configurationhttps://github.com/containerd/containerd/blob/main/docs/cri/config.md