K8s运维日记:半夜被ImagePullBackOff报警吵醒,我是这样排查的(附排查清单)
K8s运维日记半夜被ImagePullBackOff报警吵醒我是这样排查的附排查清单凌晨2:17手机突然震动起来——Prometheus的报警通知像一盆冷水浇在脸上。眯着眼看到Pod状态异常ImagePullBackOff的告警标题瞬间清醒。作为K8s集群的守夜人这种场景早已不陌生。但每次遇到依然需要像侦探破案一样在最短时间内抽丝剥茧找到症结。下面记录的是我处理这类问题的标准流程以及沉淀下来的排查清单。1. 第一响应建立问题全景图被报警惊醒后的前5分钟最为关键。此时需要快速建立问题全景图而不是盲目操作。我的标准动作是三步走# 第一步确认异常Pod范围 kubectl get pods --all-namespaces --field-selectorstatus.phase!Running # 第二步获取Pod详细状态替换pod_name和namespace kubectl describe pod pod_name -n namespace | grep -A 10 Events: # 第三步检查集群级别事件 kubectl get events --sort-by.lastTimestamp -A | grep -i fail这三个命令的输出会告诉我是单个Pod还是批量出现异常具体报错信息如权限拒绝、镜像不存在等是否伴随其他关联事件注意凌晨处理问题时要特别注意命令准确性误操作可能导致二次事故。建议将常用命令保存为脚本或kubectl别名。上周处理的一个案例中通过describe pod发现事件日志显示Failed to pull image: x509: certificate signed by unknown authority。这直接指向了镜像仓库的TLS证书问题省去了后续的网络排查环节。2. 镜像源问题深度排查当确认是ImagePullBackOff后我会按照以下优先级进行验证2.1 镜像地址准确性验证先检查最基本的镜像地址配置是否正确kubectl get pod pod_name -n namespace -o jsonpath{.spec.containers[*].image}常见问题包括镜像tag拼写错误如v1.0.0写成v1.o.0私有仓库地址缺少前缀如company/image应为registry.company.com/image误用latest标签导致版本漂移2.2 私有仓库认证检查对于私有仓库需要验证Secret配置# 查看Pod引用的imagePullSecrets kubectl get pod pod_name -n namespace -o jsonpath{.spec.imagePullSecrets[*].name} # 检查Secret内容替换secret_name kubectl get secret secret_name -n namespace -o yaml | grep \.dockerconfigjson我曾遇到过一个典型情况集群从测试环境迁移到生产环境时忘记更新docker-registry secret中的认证信息导致所有Pod都无法拉取镜像。解决方法很简单# 重新创建docker-registry secret kubectl create secret docker-registry regcred \ --docker-serveryour-registry \ --docker-usernameusername \ --docker-passwordpassword \ -n namespace3. 网络层问题定位如果镜像配置无误就需要排查网络连通性。我的网络诊断工具包通常包括工具检查目标示例命令dig/nslookup域名解析dig registry.company.comtelnet/nc端口连通性telnet registry.company.com 443curlHTTPS访问能力curl -v https://registry.company.com/v2/traceroute网络路径诊断traceroute registry.company.com提示在K8s节点上执行这些测试时建议使用kubectl debug创建临时调试容器避免直接登录节点kubectl debug node/node_name -it --imagenicolaka/netshoot4. 集群组件健康检查当上述检查都通过但问题依旧时就需要查看集群组件状态# 检查kubelet日志需要在节点上执行 journalctl -u kubelet --since 30 min ago | grep -i pull # 检查容器运行时状态 sudo crictl ps -a | grep -i pause最近遇到的一个棘手案例某节点上的containerd存储驱动异常导致所有镜像拉取请求都超时。通过以下命令发现了问题sudo ctr --namespacek8s.io images list | grep -i error解决方法也很直接——重启containerd服务sudo systemctl restart containerd5. 终极排查清单经过多次深夜故障的洗礼我整理了一份完整的排查清单打印出来贴在工位上基础信息确认[ ] 获取Pod名称和所在命名空间[ ] 记录完整的错误信息[ ] 确认K8s集群版本和节点OS镜像配置检查[ ] 验证镜像地址拼写[ ] 检查tag是否存在可手动docker pull测试[ ] 确认镜像架构匹配如arm64 vs amd64认证配置验证[ ] 检查imagePullSecrets引用[ ] 确认Secret中的认证信息有效[ ] 测试直接使用docker login网络连通性测试[ ] 域名解析是否正常[ ] 443端口是否开放[ ] 是否能够完成HTTPS握手[ ] 检查网络策略(NetworkPolicy)限制集群组件诊断[ ] kubelet日志有无异常[ ] 容器运行时状态是否健康[ ] 节点存储空间是否充足df -h高级场景检查[ ] 镜像仓库是否开启内容信任(Docker Content Trust)[ ] 是否配置了镜像拉取速率限制[ ] 是否存在IP黑名单限制这份清单不仅适用于ImagePullBackOff问题稍加调整也能用于其他Pod启动故障的排查。把它分享给团队后我们的平均故障恢复时间(MTTR)缩短了40%。