ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

K8s故障排查实战:从Pod异常到网络存储的完整路径

K8s故障排查实战:从Pod异常到网络存储的完整路径 简介这份文档面向 Kubernetes 运维工程师、云计算从业者及正在学习容器编排的开发者聚焦 k8s 集群在生产环境中常见的连接异常、通信异常、节点异常与应用故障四大类问题提供系统化的诊断思路与处理流程。资源包内含 1 个 docx 文档压缩包约 11.58MB内容以文字笔记与命令示例为主便于按章节查阅与整理。文档围绕 Pod 状态异常展开涵盖 ContainerCreating、Pending、ImagePullBackOff 等典型场景并给出 kubectl 查看节点、describe 排查详情、logs 定位日志、kubelet 服务状态检查等完整命令链路同时涉及节点重置重新加入集群、PV 存储卷挂载失败、网络插件部署问题等实战处理步骤。目前已有 2877 人学习下载适合需要快速定位故障根因、建立排错框架的运维人员参考也可作为日常巡检与应急处理的案头资料。1. k8s 故障处理笔记从 Pod 起不来到底层网络插件一份能照着排的实战路径线上 k8s 集群出问题最怕的不是报错而是不知道从哪一层开始查。Pod 一直 Pending、CrashLoopBackOff 反复重启、Service 访问不通、节点 NotReady这些现象背后可能横跨调度、容器运行时、网络插件、存储、DNS 好几个层面。我做过几年一线运维处理过的故障里真正靠“重启大法”解决的不到两成剩下八成都要顺着一条链路往下挖。这份笔记不是官方文档的复述而是把 k8s 常见故障按“现象 → 定位命令 → 根因 → 修复”串成一条可复现的排查路径覆盖 Pod、网络插件、节点、存储、DNS 几个高频故障域。适合已经搭过集群、能跑 kubectl 的运维和开发也适合正在准备 k8s 面试题、想把零散命令串成体系的人。下面从最常见的 Pod 异常开始一层层往下拆。2. Pod 异常排查Pending、CrashLoopBackOff、ImagePullBackOff 怎么定位Pod 是 k8s 里最小的调度单元也是故障暴露最集中的地方。绝大多数“服务挂了”的第一现场都是某个 Pod 状态不对。这一章把三类最高频的 Pod 异常拆开讲每类给出定位命令和判断依据。2.1 用 kubectl describe 和 events 锁定 Pending 的真实原因Pod 卡在 Pending意思是调度器没把它分配到任何节点。很多人第一反应是看节点资源但 Pending 的原因至少有四种资源不足、节点亲和性不满足、污点未容忍、PVC 未绑定。定位入口永远是 describe 看 Events。# 查看 Pod 状态和最近事件Events 段落是排查核心 kubectl describe pod pod-name -n namespace # 只看事件按时间排序适合事件很多时快速定位 kubectl get events -n namespace --sort-by.lastTimestamp # 查看节点可分配资源和已分配情况 kubectl describe node node-name | grep -A 5 Allocated resourcesdescribe 输出里 Events 段会直接告诉你调度器为什么放弃。常见提示对照Insufficient cpu是资源不够node(s) had taint是污点没容忍pod has unbound immediate PersistentVolumeClaims是 PVC 没绑上0/3 nodes are available后面跟的原因才是关键。参数上-n指定命名空间不能省跨命名空间查不到 Pod 是新手最常见的翻车点。--sort-by.lastTimestamp让事件按时间排集群事件多的时候能省不少眼力。定位到原因后修复方向就明确了资源不够就调 requests 或扩容节点污点问题就在 Pod spec 里加 tolerationsPVC 未绑定要去看 StorageClass 和 PV 的状态。这里有个容易忽略的点requests 设得过大即使节点实际空闲很多调度器也会因为“可分配量”不足而拒绝调度所以 requests 要贴近真实用量别拍脑袋写。2.2 CrashLoopBackOff 的日志分层容器日志、previous 日志、退出码CrashLoopBackOff 是容器起来了又挂、挂了又被拉起循环到退避。这个状态最坑的地方是你kubectl logs看到的可能是最后一次启动的日志而崩溃原因在更早的那次。所以第一步是看 previous 日志。# 看当前容器日志 kubectl logs pod-name -n namespace # 看上一次崩溃的日志CrashLoopBackOff 排查必用 kubectl logs pod-name -n namespace --previous # 多容器 Pod 要指定容器名 kubectl logs pod-name -n namespace -c container-name --previous # 查看容器退出码和重启次数 kubectl get pod pod-name -n namespace -o jsonpath{.status.containerStatuses[*].lastState}--previous是 CrashLoopBackOff 的后悔药没有它你很可能对着一份“正常启动然后被杀”的日志发呆。退出码也有讲究137 通常是 OOMKilled 或被 SIGKILL143 是 SIGTERM1 是应用自身报错退出。如果 lastState 里 reason 是 OOMKilled那就要调 memory limits 或者查应用内存泄漏而不是继续看日志。多容器 Pod 一定要带-c否则默认只取第一个容器查错容器等于白查。2.3 ImagePullBackOff 与 ErrImagePull镜像拉取失败的四个检查点镜像拉不下来Pod 会停在 ImagePullBackOff 或 ErrImagePull。这个故障排查路径很固定按顺序查四点镜像名和 tag 是否正确、镜像仓库是否可达、拉取凭证 secret 是否配置、节点上是否已有该镜像。# 看具体拉取失败信息 kubectl describe pod pod-name -n namespace | grep -A 10 Events # 检查 imagePullSecrets 是否挂上 kubectl get pod pod-name -n namespace -o jsonpath{.spec.imagePullSecrets} # 在节点上手动测试拉取确认是网络还是凭证问题 crictl pull image:tagdescribe 的 Events 里会写清楚是manifest unknowntag 不存在、unauthorized凭证问题还是dial tcp timeout网络不通。crictl pull在节点上直接拉一次能快速区分是集群配置问题还是节点到仓库的网络问题。凭证这块secret 必须和 Pod 在同一个 namespace跨 namespace 引用是无效的这个坑我踩过不止一次。另外注意 imagePullPolicytag 是 latest 时默认 Always固定 tag 默认 IfNotPresent如果节点上有旧镜像又用了固定 tag可能拉到旧版本排查时别忽略这一层。3. 网络插件故障Service 不通、DNS 解析失败、Pod 跨节点通信异常网络是 k8s 故障里最玄学的一块因为涉及 CNI 插件、kube-proxy、iptables/IPVS、CoreDNS 多个组件。现象往往是“Pod 能起但访问不通”排查要按“同节点 → 跨节点 → Service → DNS”的顺序逐层缩小范围。3.1 先分清 CNI 插件类型Calico、Flannel、Cilium 的排查差异不同网络插件的排查入口不一样。Flannel 走 VXLAN 覆盖网络问题多在 vxlan 接口和路由表Calico 支持 BGP 和 IPIP问题多在 BGP 邻居和 felix 状态Cilium 基于 eBPF排查要用 cilium 专用命令。先确认集群用的是哪个。# 查看 CNI 相关 Pod kubectl get pods -n kube-system | grep -E calico|flannel|cilium # Calico 查看节点 BGP 状态 kubectl exec -n kube-system calico-node-pod -- calicoctl node status # Cilium 查看端点状态 kubectl exec -n kube-system cilium-pod -- cilium status判断插件类型后排查方向就收窄了。Calico 的calicoctl node status如果显示 BGP 邻居不是 Established跨节点通信就会断。Flannel 要看节点上ip route里有没有到其他节点 Pod 网段的路由。Cilium 的cilium status会直接报健康度。这一步的价值在于不要用一套通用命令去查所有插件插件不同故障点完全不同。3.2 用临时 Pod 做连通性分层测试网络问题最有效的办法是分层测Pod 到 Pod 同节点、Pod 到 Pod 跨节点、Pod 到 Service、Pod 到外部。用一个带网络工具的临时 Pod 逐层测。# 起一个带工具的临时 Pod kubectl run nettest --imagenicolaka/netshoot --restartNever -- sleep 3600 # 测同节点 Pod IP 连通性 kubectl exec -it nettest -- ping target-pod-ip # 测 Service ClusterIP kubectl exec -it nettest -- curl -v service-name.namespace:port # 测 DNS 解析 kubectl exec -it nettest -- nslookup service-name.namespace.svc.cluster.local分层测试的逻辑是如果同节点通、跨节点不通问题在 CNI 覆盖网络或节点路由如果 Pod IP 通但 Service 不通问题在 kube-proxy 或 iptables 规则如果 Service 通但域名不通问题在 CoreDNS。netshoot 这个镜像自带 ping、curl、nslookup、tcpdump比临时装工具省事。测的时候注意用完整域名短域名在不同 namespace 下解析行为不同容易误判。3.3 CoreDNS 解析失败的排查顺序DNS 故障的典型现象是应用日志里大量no such host或解析超时。排查顺序是CoreDNS Pod 是否正常、Service 是否有 Endpoints、resolv.conf 配置是否正确、上游 DNS 是否可达。# 查看 CoreDNS 状态 kubectl get pods -n kube-system -l k8s-appkube-dns # 查看 kube-dns Service 的 Endpoints kubectl get endpoints kube-dns -n kube-system # 查看 Pod 内的 resolv.conf kubectl exec -it pod-name -- cat /etc/resolv.confEndpoints 为空是高频问题说明 CoreDNS Pod 没就绪或标签不匹配。resolv.conf 里 nameserver 应该指向 kube-dns 的 ClusterIPsearch 域要包含 Pod 所在 namespace。如果 CoreDNS 日志里有大量 SERVFAIL可能是上游 DNS 配置有问题或 conntrack 表满。conntrack 满导致 DNS 间歇性失败是个隐蔽坑表现为“时好时坏”要查节点conntrack -C和nf_conntrack_max。4. 节点与存储故障NotReady、磁盘压力、PVC 挂载失败节点是集群的地基节点出问题会连带一片 Pod 异常。存储故障则更隐蔽因为 Pod 可能正常 Running 但读写失败。4.1 节点 NotReady 的排查链路节点 NotReady先看 kubelet 状态再看容器运行时最后看网络和资源。# 查看节点状态和原因 kubectl describe node node-name | grep -A 10 Conditions # 登录节点看 kubelet 状态 systemctl status kubelet # 查看 kubelet 日志 journalctl -u kubelet -n 100 --no-pagerConditions 里会显示 Ready 为 False 的原因常见有 KubeletNotReady、NetworkUnavailable。kubelet 日志里如果出现PLEG is not healthy通常是容器运行时响应慢或节点负载过高。磁盘压力 DiskPressure 会触发 kubelet 驱逐 Pod表现为 Pod 被莫名 Evicted这时要清理节点镜像和日志crictl rmi --prune和清理/var/log是常规操作。4.2 PVC 挂载失败与存储插件排查PVC 一直 Pending 或 Pod 卡在 ContainerCreating存储问题居多。# 查看 PVC 状态 kubectl get pvc -n namespace # 查看 PV 绑定情况 kubectl get pv # 查看 Pod 事件里的挂载错误 kubectl describe pod pod-name -n namespace | grep -i volume\|mountPVC Pending 常见原因是 StorageClass 不存在或 provisioner 没工作。Pod 卡 ContainerCreating 且事件里有MountVolume.SetUp failed要去看存储插件如 CSI driver的 Pod 日志。NFS 类存储还要确认节点到 NFS 服务器的网络和权限。这里有个血泪经验StorageClass 的 reclaimPolicy 如果是 Delete删 PVC 会连带删底层存储测试环境误删数据的事故多半出在这。5. 避坑与排查那些让排查方向跑偏的常见误判排查最怕的不是没命令而是方向错了。这一章列几个我实际踩过的坑每条按现象、原因、解决写。现象Pod 一直 Pending节点明明有空闲资源。原因requests 设得过大调度器按可分配量算实际空闲不等于可分配。或者节点有污点但没配 tolerations。 解决kubectl describe node看 Allocated resources对比 requests检查节点 taints 和 Pod tolerations。现象CrashLoopBackOff日志看起来正常。原因看的是当前日志崩溃原因在上一次。或者多容器 Pod 看错了容器。 解决用--previous看上次日志多容器加-c指定容器名结合退出码判断是否 OOMKilled。现象Service 访问不通但 Pod IP 直连正常。原因Service 的 selector 和 Pod 标签不匹配Endpoints 为空或 kube-proxy 规则没同步。 解决kubectl get endpoints svc确认是否有后端检查 selector 与 Pod labels重启 kube-proxy 或查 iptables 规则。现象DNS 解析时好时坏间歇性失败。原因节点 conntrack 表满UDP DNS 查询丢包或 CoreDNS 副本数不足扛不住查询量。 解决查conntrack -C和nf_conntrack_max调大或优化CoreDNS 扩容并配 HPA。现象Pod 被莫名 Evicted应用没报错。原因节点 DiskPressure 或 MemoryPressure 触发 kubelet 驱逐。 解决清理节点镜像和日志检查驱逐阈值配置给关键 Pod 配 PriorityClass 降低被驱逐概率。6. 把排查经验固化成可复用的检查脚本与习惯故障处理做久了会发现真正省时间的不是记住所有命令而是把高频检查固化成脚本。我一般会写一个巡检脚本把节点状态、异常 Pod、PVC 状态、CoreDNS 健康度一次性拉出来出问题时先跑一遍缩小范围再深入。#!/bin/bash # k8s 快速巡检脚本出问题时先跑这个缩小范围 echo 节点状态 kubectl get nodes -o wide echo 非 Running 的 Pod kubectl get pods -A --field-selectorstatus.phase!Running,status.phase!Succeeded echo 重启次数高的 Pod kubectl get pods -A --sort-by.status.containerStatuses[0].restartCount | tail -20 echo Pending 的 PVC kubectl get pvc -A | grep -v Bound echo CoreDNS 状态 kubectl get pods -n kube-system -l k8s-appkube-dns echo 最近事件 kubectl get events -A --sort-by.lastTimestamp | tail -30这个脚本的价值在于把“先看什么”固定下来避免慌乱中漏查。参数上可以按需加-n限定命名空间生产环境事件多的时候 tail 行数调大。除了脚本还有个习惯值得养成每次处理完故障把现象、根因、修复命令记到自己的笔记里下次遇到同类问题直接翻。k8s 故障处理没有银弹靠的是对链路的熟悉和排查顺序的稳定。我自己从最早遇到 Pending 就重启节点到现在能按层定位靠的就是一次次踩坑后把路径记下来。希望帮到你。本文还有配套的精品资源点击获取
返回列表