K8s故障处理实战:Pod异常与网络排查完整路径

发布时间:2026/10/12 9:35:36

K8s故障处理实战:Pod异常与网络排查完整路径 简介这份文档面向 Kubernetes 运维工程师、云计算从业者及正在准备相关认证的技术人员系统梳理了 k8s 集群在实际生产环境中常见的故障类型与排查思路。内容围绕连接异常、通信异常、节点内部异常和应用故障四大场景展开涵盖 pod 处于 ContainerCreating、Pending、ImagePullBackOff 等典型状态的成因分析与诊断流程并给出 node 节点重置重新入群、存储卷未挂载 pv、网络插件部署异常等具体处理方案配合 kubectl 常用命令与 kubelet 日志查看方法帮助读者建立从现象到根因的排错路径。资源包为 1 个 docx 文档约 11.58MB结构按故障章节组织便于按需查阅。目前已有 2878 人学习下载适合希望提升 k8s 故障定位效率、积累实战排错经验的运维人员参考。1. k8s 故障处理笔记从 Pod 起不来到底层网络排查的完整路径凌晨两点收到告警某个核心服务的 Pod 大面积重启kubectl get pods一看全是CrashLoopBackOff但业务代码昨天刚上线时还是好的。这种场景做 k8s 运维的人多少都遇到过。k8s 故障处理的核心难点不在于命令多复杂而在于故障现象往往指向多个可能原因排查路径如果不对很容易在错误的方向上浪费大量时间。这份笔记整理的是我在实际工作中反复用到的排查思路和操作步骤覆盖 Pod 异常、网络插件问题、控制节点初始化失败、存储挂载失败等高频场景。适合已经能跑起 k8s 集群、但在出问题时不知道从哪下手的人。每一条都尽量给出可复现的命令和判断依据而不是泛泛而谈“检查日志”。2. Pod 异常状态排查从 Pending 到 CrashLoopBackOff 的逐层定位2.1 先看状态再动手Pod 生命周期中的关键信号拿到一个异常 Pod第一步永远是kubectl describe pod而不是直接看应用日志。describe 的输出里包含了调度结果、容器启动过程、挂载信息和最近事件这些信息能快速把问题范围缩小到调度层、镜像层、存储层还是应用层。# 查看 Pod 详细状态重点关注 Events 部分 kubectl describe pod pod-name -n namespace # 只看事件按时间排序 kubectl get events -n namespace --sort-by.lastTimestampdescribe 输出中Status字段告诉你 Pod 当前处于哪个阶段Events则记录了从创建到现在的关键动作。比如FailedScheduling说明调度器找不到合适的节点FailedMount说明存储卷挂载有问题BackOff说明容器启动后退出被反复重启。先根据这些事件把问题归类再进入对应的排查分支。参数说明-n指定命名空间不指定则默认 default--sort-by按事件时间排序排查偶发问题时特别有用。2.2 Pending 状态调度器为什么不选这个节点Pending 意味着 Pod 已经被 API Server 接受但还没有被调度到任何节点上。常见原因有三类资源不足、节点选择器不匹配、污点和容忍度冲突。# 查看节点资源分配情况 kubectl describe node node-name | grep -A 5 Allocated resources # 查看节点标签确认 nodeSelector 是否能匹配 kubectl get nodes --show-labels # 查看节点污点 kubectl describe node node-name | grep Taints如果Allocated resources显示 CPU 或内存的 requests 已经接近容量调度器就不会再把新 Pod 放上去。这时候要么清理无用 Pod要么调整工作负载的 resource requests。如果是 nodeSelector 或 affinity 配置问题检查 Pod spec 里的nodeSelector字段和节点标签是否一致。污点问题则看 Pod 的tolerations是否覆盖了节点上的 taint。我一般会先用kubectl get pods -o wide确认 Pod 是否真的没有被分配节点再用kubectl describe pod看具体的调度失败原因。这两个命令组合能解决八成以上的 Pending 问题。2.3 CrashLoopBackOff容器反复重启的四个常见根因CrashLoopBackOff 是容器启动后退出kubelet 按指数退避策略反复重启。排查顺序建议是先看容器退出码再看应用日志最后检查探针配置。# 查看容器上一次退出的退出码和原因 kubectl get pod pod-name -o jsonpath{.status.containerStatuses[0].lastState.terminated} # 查看当前容器日志 kubectl logs pod-name -n namespace # 查看上一次崩溃的日志 kubectl logs pod-name -n namespace --previous退出码 0 通常意味着容器主进程正常结束但 k8s 期望它持续运行这种情况常见于启动命令写成了执行完就退出的脚本。退出码 1 一般是应用报错需要看日志定位。退出码 137 表示被 SIGKILL 杀死多半是 OOMKilled检查 Pod 的 memory limit 是否太小。退出码 143 是 SIGTERM通常是收到了终止信号。探针配置错误也容易导致 CrashLoopBackOff。livenessProbe 如果 initialDelaySeconds 设得太短应用还没启动完就被判定为不健康kubelet 会杀掉容器重启。readinessProbe 配置不当则会导致 Pod 一直不 Ready但不会重启。这两种情况在 describe 的 Events 里能看到Liveness probe failed或Readiness probe failed的记录。2.4 镜像拉取失败ImagePullBackOff 的排查清单ImagePullBackOff 说明 kubelet 无法拉取镜像。排查步骤很固定确认镜像地址是否正确、确认镜像仓库是否可达、确认拉取凭证是否配置。# 查看 Pod 事件中的具体拉取错误 kubectl describe pod pod-name | grep -A 10 Events # 查看已创建的 secret kubectl get secrets -n namespace # 检查 Pod 是否引用了 imagePullSecrets kubectl get pod pod-name -o jsonpath{.spec.imagePullSecrets}常见错误信息包括manifest unknown镜像 tag 不存在、unauthorized凭证无效或未配置、dial tcp timeout网络不通。如果是私有仓库确认 Secret 的 type 是kubernetes.io/dockerconfigjson并且 Pod spec 里通过imagePullSecrets引用了它。注意 Secret 必须和 Pod 在同一个 namespace。还有一个容易忽略的点如果节点上已经有该镜像的缓存但 tag 是latestkubelet 默认的 imagePullPolicy 是Always每次都会去仓库拉取。仓库不可达时就会失败。可以临时把 imagePullPolicy 改成IfNotPresent来验证是否是仓库问题但生产环境不建议长期这样配置。3. 网络插件故障Pod 跨节点不通与 DNS 解析失败的排查方法3.1 先确认 CNI 插件是否正常工作k8s 的网络模型要求每个 Pod 有独立 IP且跨节点 Pod 能直接通信。这个能力由 CNI 插件提供常见的有 Calico、Flannel、Cilium。网络问题的第一步是确认 CNI 插件的 Pod 是否全部 Running。# 查看 CNI 插件 Pod 状态以 Calico 为例 kubectl get pods -n kube-system | grep calico # 查看 CNI 配置文件是否存在 ls /etc/cni/net.d/ # 查看节点上的路由信息 ip route show如果 CNI Pod 本身就不健康先解决它。CNI Pod 起不来的常见原因是镜像拉取失败、RBAC 权限不足、或者节点上的 CNI 配置文件残留导致冲突。/etc/cni/net.d/目录下如果有多个 CNI 配置文件kubelet 会按字母顺序选择第一个可能选到错误的配置。路由信息能反映跨节点通信是否正常。Calico 使用 BGP 或 IPIP 模式Flannel 使用 VXLAN 或 host-gw 模式。如果路由表里缺少到其他节点 Pod 网段的路由跨节点通信就会失败。这时候需要检查 CNI 插件的配置和节点间的网络连通性。3.2 Pod 跨节点不通的抓包定位法当确认 CNI Pod 正常但跨节点仍然不通时抓包是最直接的定位手段。在源节点和目标节点上分别抓取 Pod 网卡和隧道网卡的流量对比数据包在哪个环节丢失。# 在源节点上抓取 Pod 网卡的流量 tcpdump -i pod-veth -nn icmp # 在源节点上抓取隧道网卡的流量 tcpdump -i tunl0 -nn icmp # 在目标节点上抓取对应 Pod 网卡的流量 tcpdump -i target-pod-veth -nn icmp如果源 Pod 网卡有包发出但隧道网卡没有说明 CNI 插件的路由规则没有生效。如果隧道网卡有包但目标节点没有收到说明节点间的底层网络有问题可能是防火墙拦截了 VXLAN 或 IPIP 协议。如果目标节点收到了但目标 Pod 网卡没有说明目标节点的路由或 iptables 规则有问题。这个方法的逻辑是逐跳验证把“不通”这个模糊现象拆解成具体的丢包位置。我一般会先用kubectl exec进入源 Pod ping 目标 Pod IP同时在两端抓包这样能快速定位。3.3 DNS 解析失败CoreDNS 排查的五个检查点DNS 问题表现为 Pod 内无法解析 Service 名称但直接 ping IP 是通的。排查 CoreDNS 需要按顺序检查以下五点。# 1. 检查 CoreDNS Pod 状态 kubectl get pods -n kube-system -l k8s-appkube-dns # 2. 检查 CoreDNS Service 是否存在 kubectl get svc -n kube-system kube-dns # 3. 检查 Pod 的 DNS 配置 kubectl exec pod-name -- cat /etc/resolv.conf # 4. 在 Pod 内测试 DNS 解析 kubectl exec pod-name -- nslookup kubernetes.default # 5. 查看 CoreDNS 日志 kubectl logs -n kube-system -l k8s-appkube-dns第一CoreDNS Pod 必须是 Running 且 Ready。第二kube-dns Service 的 ClusterIP 必须存在且 Endpoints 指向 CoreDNS Pod。第三Pod 的/etc/resolv.conf里 nameserver 应该是 kube-dns 的 ClusterIPsearch 域应该包含 Pod 所在 namespace 的域名后缀。第四如果 nslookup 超时说明 Pod 到 CoreDNS 的网络不通检查网络策略或 iptables 规则。第五CoreDNS 日志里如果有大量 SERVFAIL可能是上游 DNS 不可达或 CoreDNS 配置了错误的 forward 地址。一个常见坑是 NetworkPolicy 默认拒绝所有入站流量如果给 CoreDNS 所在 namespace 加了策略但没有放行 DNS 端口所有 Pod 的 DNS 都会挂。这种情况在启用网络策略的集群里特别容易翻车。4. 控制节点初始化失败kubeadm init 报错的排查与恢复4.1 the api server is not healthy 的常见原因kubeadm init过程中如果看到the api server is not healthy after 4m0.00747357s说明 kubelet 启动了 API Server 静态 Pod但健康检查一直没通过。这个报错本身信息量很少需要去看 kubelet 日志和容器运行时日志。# 查看 kubelet 日志 journalctl -xeu kubelet --no-pager | tail -100 # 查看容器运行时状态以 containerd 为例 systemctl status containerd # 查看 API Server 容器是否创建 crictl ps -a | grep kube-apiserver # 查看 API Server 容器日志 crictl logs container-id常见原因有四个。第一容器运行时没配好kubelet 无法创建容器。检查 containerd 的配置文件/etc/containerd/config.toml里SystemdCgroup是否设为 true这个参数在 k8s 1.24 之后必须和 kubelet 的 cgroup driver 一致。第二镜像拉取失败kubelet 拉不到kube-apiserver镜像。可以用kubeadm config images pull提前拉取观察具体报错。第三端口冲突6443 端口被占用。用ss -tlnp | grep 6443检查。第四证书问题如果之前 init 过又没清理干净残留的证书会导致新 API Server 启动失败。用kubeadm reset清理后重试。4.2 kubeadm reset 之后必须清理的残留文件kubeadm reset不会自动清理所有文件残留的配置和证书会导致下一次 init 失败。我一般会手动清理以下目录。# 停止 kubelet systemctl stop kubelet # 清理 kubeadm 相关目录 rm -rf /etc/kubernetes/ rm -rf /var/lib/etcd/ rm -rf $HOME/.kube/ # 清理 CNI 配置 rm -rf /etc/cni/net.d/ # 清理 iptables 规则 iptables -F iptables -t nat -F iptables -t mangle -F iptables -X # 重启容器运行时和 kubelet systemctl restart containerd systemctl restart kubelet这些目录里/etc/kubernetes/存放了证书和静态 Pod 清单/var/lib/etcd/存放 etcd 数据$HOME/.kube/存放 kubeconfig。不清理干净就重新 initetcd 可能因为数据不一致而启动失败API Server 可能因为证书不匹配而拒绝连接。iptables 规则清理也很重要。kube-proxy 和 CNI 插件会写入大量规则reset 后这些规则可能残留导致新集群的网络行为异常。清理后重启容器运行时和 kubelet让它们重新生成必要的配置。4.3 初始化成功后的验证步骤kubeadm init成功不代表集群就能用了还需要验证几个关键组件。# 确认节点状态 kubectl get nodes # 确认核心组件 Pod 状态 kubectl get pods -n kube-system # 确认 API Server 健康 kubectl get --raw /healthz # 确认 DNS 可用 kubectl run test-dns --imagebusybox:1.28 --rm -it -- nslookup kubernetes.default节点状态应该是 Readykube-system 下的 Pod 应该全部 Running。如果有 Pod 处于 Pending 或 CrashLoopBackOff先解决它们再继续。/healthz返回 ok 说明 API Server 正常。DNS 测试能解析出 ClusterIP 说明 CoreDNS 工作正常。如果节点状态是 NotReady通常是 CNI 插件还没装。kubeadm init 完成后需要手动安装 CNI 插件否则节点不会进入 Ready 状态。这是新手最容易卡住的地方因为 kubeadm 的输出里不会明确提示这一点。5. 避坑与常见问题那些让我加班到凌晨的 k8s 故障5.1 节点 NotReady 但 kubelet 日志没有明显报错现象kubectl get nodes显示 NotReady但journalctl -u kubelet里没有 ERROR 级别的日志。原因kubelet 与 API Server 的通信正常但容器运行时或 CNI 插件有问题。kubelet 的日志级别默认只记录关键错误一些警告信息被淹没了。解决用journalctl -u kubelet --no-pager | grep -i cni\|runtime\|failed过滤关键词。同时检查systemctl status containerd和crictl ps的输出。如果是 CNI 问题确认/etc/cni/net.d/下有配置文件且 CNI 插件的二进制文件存在于/opt/cni/bin/。5.2 Pod 内无法访问 Service但直接访问 Pod IP 正常现象在 Pod 内curl service-name超时但curl pod-ip正常。原因kube-proxy 没有正确写入 iptables 或 IPVS 规则或者 Service 的 Endpoints 为空。解决先kubectl get endpoints service-name确认 Endpoints 是否有 Pod IP。如果为空检查 Service 的 selector 是否匹配 Pod 标签。如果 Endpoints 正常检查 kube-proxy Pod 是否 Running以及节点上的 iptables 规则是否有对应的 Service 转发规则。用iptables -t nat -L KUBE-SERVICES -n | grep service-ip查看。5.3 存储卷挂载失败导致 Pod 一直 ContainerCreating现象Pod 状态一直是 ContainerCreatingdescribe 显示FailedMount或Unable to attach or mount volumes。原因PV 和 PVC 不匹配、StorageClass 配置错误、或者节点上缺少对应的挂载工具。解决先kubectl get pvc确认 PVC 是否 Bound。如果 Pending检查 StorageClass 是否存在且 provisioner 正常工作。如果 PVC 已 Bound 但挂载失败检查节点上是否安装了 NFS 客户端、iSCSI 工具等依赖。用kubectl describe pod看具体挂载错误信息常见的有mount: wrong fs type或timeout。5.4 节点磁盘压力导致 Pod 被驱逐现象Pod 突然被 Evicted节点状态显示DiskPressure。原因节点上的镜像和容器日志占满了磁盘kubelet 触发驱逐策略。解决先清理无用镜像crictl rmi --prune再清理容器日志。长期方案是配置 kubelet 的--eviction-hard和--eviction-soft参数以及定期清理镜像。用df -h确认哪个分区满了通常是/var/lib/containerd或/var/log。5.5 Service 的 ClusterIP 无法 ping 通现象在 Pod 内 ping Service 的 ClusterIP 不通但 curl 对应的端口是通的。原因ClusterIP 是虚拟 IP由 iptables 或 IPVS 规则实现转发不响应 ICMP 请求。ping 不通是正常现象。解决不要用 ping 测试 Service 连通性用curl或nc测试具体端口。如果端口也不通再按 5.2 的方法排查。6. 进阶技巧用临时容器和事件流快速定位疑难故障6.1 临时容器不重启 Pod 也能进去排查k8s 1.23 之后临时容器Ephemeral Container成为稳定特性。当 Pod 里的容器没有 shell 或者已经崩溃无法进入时可以用临时容器挂载到同一个 namespace 里排查。# 给运行中的 Pod 添加一个临时容器 kubectl debug -it pod-name --imagebusybox:1.28 --targetcontainer-name # 直接复制一个 Pod 并修改启动命令 kubectl debug pod-name -it --copy-todebug-pod --containerdebug -- sh--target参数让临时容器共享目标容器的进程命名空间可以直接看到目标容器的进程和网络。--copy-to则是创建一个 Pod 副本可以修改镜像或命令来绕过原 Pod 的启动问题。这两个用法在排查“容器起不来但又想看里面状态”的场景下特别有用。参数说明--image指定临时容器使用的镜像建议用带调试工具的镜像如nicolaka/netshoot--target指定要共享命名空间的容器名--copy-to创建的新 Pod 名称需要唯一。6.2 用事件流和审计日志做故障回溯k8s 的 Event 默认只保留一小时对于偶发故障事后排查往往找不到线索。我一般会部署一个事件收集工具把 Event 持久化到外部存储。如果没有这个条件至少可以用kubectl get events -w实时观察。# 实时观察所有 namespace 的事件 kubectl get events -A -w # 按资源类型过滤事件 kubectl get events -A --field-selector involvedObject.kindPod # 查看审计日志如果启用了 tail -f /var/log/kubernetes/audit.log | grep resource-name审计日志记录了所有 API 请求能回答“谁在什么时候改了什么”的问题。对于配置被误改导致的故障审计日志是唯一的后悔药。启用审计需要在 API Server 的启动参数里配置--audit-policy-file和--audit-log-path生产环境建议至少记录 RequestResponse 级别。6.3 一个我反复用到的排查习惯每次处理完故障我会把kubectl describe和关键日志的输出保存到一个按日期命名的文件里。下次遇到类似现象时先翻之前的记录对比。这个习惯帮我省了很多重复排查的时间因为 k8s 的故障模式其实很有限大部分问题都是那几种原因换了个表现形式。另外我习惯在集群里常备一个netshoot的 DaemonSet需要抓包或测网络时直接kubectl exec进去不用临时拉镜像。这个镜像里 tcpdump、nslookup、curl、ss 都有排查网络问题时能省不少事。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/12 9:35:36

REA企业本体模型:用资源、事件、主体重构业务数据架构

这个标题只有三个字母,没有正文、没有关键词、没有任何背景交代。乍一看像随手敲出来的占位符,但既然丢到我面前,我就按一个最能产出的方向来啃:把“rea”理解成被很多开发者念叨了很多年、却少有人真正讲透的东西——REA&#xf…

2026/10/12 10:56:23

智能体记忆系统设计:分层存储、混合检索与遗忘机制实战

1. 记忆系统到底在解决什么问题智能体做任务的时候,最让人头疼的一件事就是“聊完就忘”。你上一轮告诉它用户偏好、任务背景、已经排除的方案,下一轮它就像第一次见面一样,重新问一遍。这不是模型不够聪明,而是它压根没有一套像样…

2026/10/12 10:56:23

AI日报的诞生逻辑:从信息筛选到决策参考的完整实操

1. 一份AI日报的诞生逻辑:为什么信息筛选比信息获取更难 每天早上七点,我的信息采集脚本准时跑完最后一轮抓取。屏幕上滚过几百条更新:某个开源社区凌晨合并了一个新分支,某篇预印本论文在六小时内被引用了四十次,某个…

2026/10/12 10:56:23

JavaWeb运动与健康管理系统:从环境搭建到数据库设计全解析

简介:面向JavaWeb学习者的运动与健康管理系统完整项目,包含源代码、数据库脚本及配套资源。系统覆盖用户注册登录、运动数据录入、健康指标跟踪、趋势分析及提醒建议等核心功能,数据库设计包含用户表、运动记录表、健康指标表,配套…

2026/10/12 10:56:23

Flink运行时状态机解析:从JobGraph到Checkpoint底层机制

简介:这是一份专为大数据开发与算法工程师面试打造的Flink流处理核心知识精要,覆盖从基础概念到源码级原理的110个高频考点,解决求职者在流批一体、实时计算、状态管理等方向的知识盲区与应答短板。资源为单文件PDF,共7.19MB&…

2026/10/12 10:56:23

Python测试实战:pytest自动化与接口回归测试指南

做技术这些年,最让我头疼的不是代码写不出来,而是代码改完不知道会不会把老功能弄坏。尤其是刚接触Python那会儿,写脚本全凭感觉,今天改一个函数,明天可能就把另一个模块带崩了。后来我养成了一个习惯:任何…

2026/10/12 10:51:22

九月开源项目盘点:20个值得细说的新项目与实操踩坑经验

1. 九月开源项目盘点的整体筛选逻辑九月份是开源社区一年中比较特殊的时间节点。北半球的开发者刚从暑期节奏中回归,各大基金会和社区开始为年底的版本发布做冲刺,很多团队会选择在这个窗口期把积攒了大半年的重构成果正式开源。我每年九月都会花几个晚上…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑