返回首页

K8s 故障排查实战 — 20 个生存法则

📅 创建于 2026-08-31 🔄 更新于 2026-08-31 📝 1171 字

K8s 故障排查实战 — 20 个生存法则

来源:微信公众号「云上架构」《Kubernetes 故障排查实战:从真实事故中提炼的 20 个生存法则》

定位:面向中高级开发者/架构师/技术负责人的生产排障手册。重点不是命令大全,而是遇到故障时如何快速缩小范围、判断根因、做出正确修复。全文案例取自真实事故:电商平台「速卖商城」(日活 2300 万、核心链路峰值 QPS 8.5 万、微服务 200+、3 个集群 260 节点、RocketMQ 日处理 14 亿条,K8s 1.27 + Containerd,Nginx + Spring Cloud Gateway + Nacos + Redis Cluster + MySQL 8.0 分库分表 + Prometheus/Grafana/EFK)。

核心思维模型:声明式系统的收敛差

Kubernetes 是声明式系统。绝大多数故障本质上都可还原为一句话:期望状态已写进系统,但实际状态没有按预期收敛。

排障时不要上来就 kubectl delete pod,先判断问题卡在控制链路的哪一段:

用户提交 YAML → API Server → etcd → Scheduler → Controller Manager → Kubelet → Container Runtime → CNI → CSI

对应可操作的排查顺序(五问):

  1. 资源对象是否已正确写入 API Server
  2. 控制器是否已生成下游资源
  3. Scheduler 是否完成调度决策
  4. Kubelet 是否在目标节点执行成功
  5. 容器、网络、存储是否真正进入可用状态

先回答「故障是配置没生效、资源没调度、容器没启动,还是流量没切换」,很多问题 5 分钟内就能缩到很小范围。

5 分钟分诊法(首轮并行四连)

遇到业务报警,先做这四步而非直接深入某组件:

命令 目的
kubectl get pods -A 看故障范围:单 Pod、单服务、单节点,还是全局异常
kubectl get events -A --sort-by=.lastTimestamp \| tail -n 50 看最新事件:调度/挂载/探针失败、驱逐,线索直接在 Events 里
kubectl get nodes 看节点状态:NotReady、DiskPressure、MemoryPressure
kubectl top pods -A 看资源形态:负载突增、资源争抢,还是某类 Pod 集体不健康

分诊不能替代深入分析,但能避免一开始就钻错方向。

一、节点与集群层(法则 1-4)

法则 1:节点 NotReady,先看心跳链路,不要先怀疑业务 Pod

业务层异常往往只是结果,不是起点。根本问题通常是 kubelet 无法继续上报状态。

第一轮检查固定为:kubectl get nodeskubectl describe node <node-name>systemctl status kubeletjournalctl -u kubelet -f

真正要看的是:NodeDiskPressure/NodeMemoryPressure、kubelet 与 API Server 通信失败、证书过期、容器运行时无响应、节点级 OOM 杀掉 kubelet。

常见真实场景:日志未轮转,/var 分区打满,触发 imagefs/nodefs 驱逐阈值,节点先进入压力状态,再被控制面标记不可调度。修复顺序:先恢复节点基本可用性(清磁盘、恢复 containerd)→ 确认 kubelet 心跳恢复 → 最后处理被驱逐/重建的业务 Pod。防复发:日志轮转、镜像回收阈值前置、kubelet/containerd/磁盘使用率单独建告警。

详见 node-troubleshootingk8s-pod-evicted-troubleshooting

法则 2:Pod Pending ≠ 集群没资源,很多时候是资源碎片化

看到调度失败最容易犯的错误动作是立即扩容节点。先看 kubectl describe pod 的调度事件:

0/26 nodes are available: 5 Insufficient cpu, 10 Insufficient memory, 3 node(s) had taint...

重点不是「26 台都不行」,而是「为什么不行的原因分散在不同节点上」——这通常意味着资源不是总量不足,而是 request 设置过大,大量零散资源无法被利用

排查同时看两组数据:kubectl top pods -A(实际使用量)与 kubectl describe nodes(被 request 预留的已分配容量)。差异大 = 资源声明长期失真。更有效动作:按历史使用重新校准 request;对高估服务灰度调整;核心服务保留稳定 request,普通服务避免拍脑袋留大。VPA 可作参考工具,但别当自动正确答案,尤其是流量有明显波峰波谷的业务。

详见 k8s-pod-pending-troubleshooting-guidek8s-resource-limits-configuration

法则 3:kubectl 变慢、控制器反应迟钝,先查 etcd,而不是先怪 API Server

大集群最被低估的问题之一:etcd 延迟拖慢整条控制链路。常见现象:kubectl get 偶发卡顿、控制器收敛明显变慢、调度/更新延迟放大、API Server 日志出现 etcd request took too long

确认命令:etcdctl endpoint health + etcdctl endpoint status --write-out=table。etcd 是强一致存储,慢 IOPS、网络抖动、过大的后端数据文件都会放大写放大和选举成本。它的问题表现为「一切都有点慢,但又没完全挂」。治理重点:etcd 用独立 SSD 不与业务 IO 争抢;定期关注数据库膨胀与碎片整理;用 API Priority & Fairness 保护高优先级请求。规模不大但控制面频繁抖动时,警惕控制器/Operator 高频更新对象制造写压力。

详见 k8s-production-incident-case-studies(etcd 磁盘写满案例)。

法则 4:高并发网络超时,别只盯应用线程池,conntrack 表满同样拖死服务

服务间出现连接超时、Cannot assign requested address、偶发调用失败时,常见第一反应是下游变慢/线程池不够/连接池打满——这些不一定错,但若故障范围跨多个服务、多个节点,应同步检查 conntrack。

sysctl net.netfilter.nf_conntrack_max + cat /proc/sys/net/netfilter/nf_conntrack_count。当短连接、高并发、重试放大同时出现时,连接跟踪表很容易被打爆;表逼近上限后新连接建立抖动,业务侧表现为「什么都没变,但超时开始随机出现」。治理:调 nf_conntrack_max、优化客户端连接复用减少无意义短连接、故障期间避免叠加过激重试。用 DaemonSet 做节点统一调优,把这些参数配置管理起来,不要依赖人工 SSH 修机器。

详见 k8s-dns-conntrack-5s-timeoutk8s-load-balancing-deep-practice

二、网络层(法则 5-9)

法则 5:502/503 先拆成「名字解析 → 端点选择 → 连接建立」三层看

「偶发 502,重启后又好了」是最怕的模糊描述。不要直接猜某个服务不稳定,先拆三层:① DNS 是否拿到正确结果;② Service/Endpoints 是否切到正确后端;③ 客户端连接池是否仍握着旧连接。

检查顺序:kubectl get svc <service>kubectl get endpoints <service>kubectl exec -it <client-pod> -- nslookup <service>kubectl logs -n kube-system -l k8s-app=kube-dns

典型滚动发布故障:Service 后端 Pod 已变化、老 Pod 正在退出、客户端连接池仍在复用指向老 Pod 的连接——业务视角就是「新旧版本切换期间持续冒 502/503」。问题不总是 CoreDNS,而是流量切换与连接生命周期没配合好。可靠修复:readinessProbe 只在真正可接流量时通过;preStop 留足时间让旧连接自然排空;客户端启用连接失败重建与健康检查。headless service + 客户端负载均衡场景更关键,地址下线不等于客户端及时感知。

详见 k8s-service-access-troubleshootingk8s-rolling-update-pitfalls

法则 6:NetworkPolicy 断联,不要只看 YAML,要沿着实际数据路径排

网络策略问题最容易出现「看配置像对的,但业务就是不通」。只反复看仓库里的 YAML 无效,要确认:目标 Pod 是否真的被 selector 选中;namespace 标签是否符合策略条件;流量是被入口拦、出口拦,还是 DNS 根本没放行。Calico 环境结合宿主机抓包:kubectl describe networkpolicy + nsenter -t -n tcpdump -i eth0 port 3306。

生产上最容易漏的不是数据库端口,而是:DNS 的 53 端口、跨 namespace 的 egress、sidecar/代理组件的额外通信端口。防复发:关键服务策略发布前验证;默认拒绝前先补齐最小放行清单;把 DNS、监控、日志、服务治理等基础依赖列入白名单基线。

详见 container-networking-troubleshootingk8s-service-access-troubleshooting

法则 7:Ingress 502,有时是端口定义根本没对上

很多 502 根因不是运行时问题,而是对象定义不一致:Ingress 写数字端口但 Service 用命名端口;Service targetPort 指向端口名但容器没有定义该名称;业务监听 8080 而 Service 转发到错误端口。特点是 Pod Running、Service 存在,但 Ingress 到后端一直握不上

最省心做法是统一端口命名规范——容器端口、Service、Ingress 统一用命名端口:

ports:
  - name: http
    containerPort: 8080

一旦规范成这套,很多发布期低级故障直接消失。

详见 k8s-service-access-troubleshooting

法则 8:跨 namespace 服务发现失败,通常不是「DNS 偶发抽风」

..svc.cluster.local 无法解析时,先确认三件事:① namespace 和 service 是否真实存在;② 客户端所在 Pod 是否能访问 kube-dns;③ CoreDNS 自身是否因资源过小被 OOM 或频繁重启。

资源紧张集群里很常见:DNS 组件常被当「很轻」的系统服务,request/limit 配得过低,查询量一上来 CoreDNS 先不稳定,业务侧大面积「名字找不到」。核心集群的 DNS 本身是关键基础设施:监控查询延迟和错误率;给 CoreDNS 足够 CPU/内存余量;将 DNS 故障与应用故障分开告警。

详见 k8s-dns-troubleshooting-sopk8s-coredns-custom-domain-resolution

法则 9:用了 Service Mesh,排障入口就不能只看业务容器

引入 Istio 后,很多「应用层超时」实为代理层配置、就绪或重试问题。真实常见现象:应用容器已启动,但 istio-proxy 尚未完全就绪,出站流量被 sidecar 接管后直接返回 503——只盯业务容器日志会误以为代码有问题。

更有效检查:kubectl exec -it -c istio-proxy -- curl localhost:15000/config_dump + istioctl proxy-status。两个特别注意:默认超时和默认重试未必符合业务语义;下游已变慢时 mesh 层重试会进一步放大故障。非幂等接口的重试策略必须经业务确认,不能只为「提升成功率」统一开启。

详见 k8s-multicluster-istio-canary

三、调度与生命周期(法则 10-13)

法则 10:CrashLoopBackOff 第一怀疑对象,往往是启动依赖而不是应用本体

服务启动即退出,不一定是代码崩了,也可能是依赖还没准备好:启动阶段强依赖 Redis/MySQL/配置中心,依赖未就绪时启动脚本立即失败,kubelet 反复拉起形成 CrashLoopBackOff。关键判断不是「怎么让 Pod 重启成功」,而是「这个失败是否应该发生在启动期」。

短期止血用 initContainer 等待依赖:

initContainers:
  - name: wait-for-redis
    image: busybox
    command: ["sh", "-c", "until nc -z redis 6379; do sleep 2; done"]

长期治理:应用自身具备重连和退避能力;用 startupProbe 给冷启动足够时间;避免把可恢复依赖写成「连不上就退出」。否则依赖一抖,K8s 会把可恢复的短暂故障放大成整个 Deployment 的持续重启。

详见 k8s-troubleshooting-quick-referencek8s-probes-guide

法则 11:优雅终止不是配个 preStop 就够,关键是「停接流量」和「处理存量」要衔接上

Pod 收到 SIGTERM 不代表一定会优雅退出。删除 Pod 时,端点摘除、探针变化、SIGTERM 发送、负载均衡刷新不是强一致原子动作。任一环节没配好:新请求还在打进旧 Pod;旧 Pod 已停止处理;请求中途被 SIGKILL 打断。

稳妥配置示例:terminationGracePeriodSeconds: 60 + preStop 缓冲(如 sleep 10 && nginx -s quit)。但应用本身行为才是关键:收到 SIGTERM 先拒绝新请求、保留排空窗口、超时前完成存量请求。Spring Boot 场景优雅停机只是基础,需结合网关超时、下游调用时长、平均请求耗时一起评估 terminationGracePeriodSeconds 是否足够。

详见 k8s-rolling-update-pitfalls(6.1 优雅终止 / 6.2 连接排空)。

法则 12:HPA 没动作时,本质上要看「它有没有可信数据」

kubectl get hpa 出现 unknown/100m 这类状态,问题通常不在业务,而在指标链路或资源声明。高频原因:metrics-server 没正常工作;Pod 没设 CPU request,利用率无法计算。HPA 两个前提缺一不可:指标采集连续可信;目标资源有明确 request 作为计算基准

排障同时检查:HPA 事件、metrics-server 状态、Deployment 的 resources 配置。伸缩故障里最危险的不是完全不扩容,而是扩得慢、缩得快——流量波动场景下制造持续震荡,修复用 stabilizationWindowSeconds: 300 降缩容抖动(详见下方事故复盘)。

详见 k8s-capacity-planning-qos-cost-optimization

法则 13:亲和性、污点、容忍配错,会把服务锁死在一个角落

为性能把服务放到特定机器而加节点亲和性/污点/拓扑限制,思路没错,但全写成刚性约束(required),容灾能力急剧下降。常见事故模式:服务只允许调度到一组特定节点 → 那组节点统一故障或容量不足 → Pod 永远 Pending。这不是调度器失灵,而是规则本身过于绝对。

工程上更好:能用 preferredDuringScheduling 就别一上来全用 required;为关键服务保留降级后的可落位节点池;把「性能最优」和「活着」拆成两个优先级。真硬依赖 GPU/本地 SSD/NUMA 就明确说明这是架构边界,而不是默认所有服务都往复杂调度策略上靠。

详见 k8s-scheduling-strategy-guide

四、存储与状态(法则 14-16)

法则 14:Pod 卡在 ContainerCreating,优先怀疑卷挂载链路

镜像、命令、探针往往是下意识先看的东西,但状态长时间停在 ContainerCreating,要先确认卷是否根本没挂上来。典型事件:Warning FailedAttachVolume ... AttachVolume.Attach failed。这类故障集中在:CSI driver 未注册或异常、云盘和节点不在同一可用区、StorageClass 绑定策略不合理。

跨可用区集群中 volumeBindingMode: WaitForFirstConsumer 很关键——把卷的实际绑定延后到调度决策之后,避免先分配出 Pod 根本到不了的盘。看到这类错误不要先删 Pod 反复试,先确认:PVC 是否已绑定、VolumeAttachment 状态是否正常、目标节点和存储拓扑是否匹配。

详见 storage-troubleshootingk8s-storage-production-pitfalls

法则 15:StatefulSet 的稳定标识是优点,也是恢复时最易踩的坑

StatefulSet 保证固定 Pod 名称和稳定存储绑定,意味着 删 Pod 不等于换数据。真实误判:mysql-0 所挂 PVC 数据损坏 → 运维删除 mysql-0 → 新 Pod 起来继续挂同一个坏卷 → 故障毫无改善。因为设计核心就是「身份稳定」(名称 + 卷绑定关系),不能用无状态「删掉重建」思路。

恢复必须回到数据层面:通过快照恢复 PVC;或在明确风险后调整 StatefulSet 管理方式。工程习惯:先确认故障发生在「Pod」还是「数据」;对 StatefulSet 维护明确备份/恢复/演练流程;不把「重建 Pod」当状态服务的默认修复动作。

详见 k8s-statefulset-guide

法则 16:emptyDir 很方便,但本质是借节点磁盘做局部缓存

emptyDir 常用于临时日志、中间文件、sidecar 共享目录,问题是太方便就容易忘记成本最终落在节点上。典型故障:sidecar 或业务进程持续写 emptyDir,没有大小限制也没有轮转,节点磁盘被单个 Pod 慢慢打满,最终触发驱逐、影响同节点其他业务。

至少显式限制。emptyDir 适合临时数据,不适合不可丢失数据;节点级磁盘监控要能追到 Pod 维度;日志和缓存都要有轮转与清理策略。

volumes:
  - name: log
    emptyDir:
      sizeLimit: 500Mi

详见 k8s-pod-evicted-troubleshootingk8s-resource-limits-configuration

五、应用与配置(法则 17-19)

法则 17:ConfigMap/Secret 已更新,不代表应用真正感知

这类问题很容易被误解成「K8s 没刷新配置」,很多时候 K8s 已把新文件投递进容器,真正没更新的是应用进程。需要区分三件事:① 对象是否已更新;② 卷挂载文件是否已刷新;③ 应用是否会重新读取。应用只在启动时读一次配置,kubelet 同步周期内更新挂载文件也无效。

另一个高频坑是 subPath:直接挂目录时配置更新通常能同步;用 subPath 挂单文件时更新不会自动反映到容器里的文件路径。稳妥做法:动态配置用目录挂载不用 subPath;需要重载的服务明确实现配置刷新能力;无法热更新的配置配套自动滚动发布机制。

详见 configmap-mount-pitfalls

法则 18:Java 容器 OOMKilled,不要只看堆大小,真正超限的往往是总内存

退出码 137 时很多 Java 团队第一反应是「堆设太大了」,这经常只说对一半。容器内存限制看到的是整个进程空间:Java Heap、Metaspace、Direct Memory、线程栈、JIT/Native Library 等额外开销。即使 -Xmx 没碰到 limit,总内存仍可能超限被 cgroup 杀掉。

更可靠思路:用 MaxRAMPercentage 控制堆占比、给非堆内存预留余量、结合线程数/直接内存/框架特征一起评估。示例:ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "/app.jar"]运行 Netty、大量异步线程或依赖本地库的服务,75% 也不一定安全,仍要结合实际负载压测。

详见 k8s-java-directmemory-oom-diagnosisjvm-container-oom-offheap-troubleshooting

法则 19:livenessProbe 配错,比没有探针更危险

探针目标是帮系统识别「是否还能继续提供服务」,不是把一切短暂失败判成必须重启。最危险的错误是把外部依赖检查放进 livenessProbe:数据库短暂抖动、下游 RPC 偶发超时、第三方接口失败直接触发存活探针失败,K8s 会把本可自恢复的应用全杀一遍,形成典型「死亡循环」。

更合理分工:livenessProbe 只判断进程是否卡死/失去基本响应;readinessProbe 判断当前是否适合继续接流量;startupProbe 处理慢启动。拆分开的生产实践:

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080

详见 k8s-probes-guide

六、可观测性(法则 20)

法则 20:监控面板只展示 CPU 和内存,故障时基本等于没有面板

多数团队不是没监控,而是监控无法支撑排障。真正有用的面板至少把三类信息串起来:业务信号(延迟/流量/错误率/饱和度)、K8s 信号(Pod 重启/驱逐/调度失败/探针失败/卷挂载失败)、链路信号(日志/追踪/关键下游耗时)。

文中 Grafana 排障面板做法:顶部服务级 SLO 与错误预算消耗;中间直接展示对应时间段 Warning Events;下方联动 Pod 日志与慢请求追踪。落地后平均故障定位时间从 45 分钟降到 8 分钟。核心经验:如果排障仍严重依赖某位同事记住一堆命令和历史经验,说明可观测性体系还没产品化。

详见 online-troubleshooting-checklist

事故复盘:ConfigMap 更新引发的滚动发布雪崩

回到开头事故(订单接口成功率 99.97% → 72%,网关大量 502,订单服务 Pod 持续重启,数据库连接池打满):

时间点 事件 影响
02:15 运维更新订单服务 ConfigMap 暂无直接影响
02:16 Deployment 开始滚动更新 旧 Pod 进入终止流程
02:17 网关侧出现 502 成功率明显下降
02:17:30 新 Pod 尚未稳定承接流量,HPA 同时触发缩容 剩余健康 Pod 压力陡增
02:18 订单服务 CPU 飙升,上游开始超时和熔断 大量订单请求失败

为什么误判成数据库瓶颈: 报警最明显的是订单错误率和数据库连接池打满;业务监控看到请求大量堆积在数据库调用阶段;网关 502 只是入口表象,无法直接暴露发布链路问题。而连接池打满实为连锁反应——旧 Pod 退出不优雅,部分请求被截断触发上游重试;新 Pod 预热不足就开始接流量,线程/连接池/CPU 同时受压;HPA 缩容过于激进,本就不多的健康副本继续减少。

根因是一串配置共同成立,不是单点: ① ConfigMap 更新触发滚动发布 → ② preStop 没给足摘流排空时间 → ③ terminationGracePeriodSeconds 过短,旧 Pod 被提前终止 → ④ readinessProbe 过早通过,新 Pod 在缓存/连接池未预热完成时就接流量 → ⑤ HPA 依据 CPU 迅速缩容,制造副本震荡。典型特征是:单个配置看着都「能用」,组合到一起就在发布窗口里形成系统性脆弱。

修复动作: 止血 = 暂停发布 + 手动扩容订单副本数 + 提高网关限流阈值并关闭部分非必要重试。配置修正 = preStop 增加 10 秒缓冲 + 调整应用优雅停机逻辑 + readinessProbe 延迟到 15 秒且成功阈值改为 2 次 + HPA 加 stabilizationWindowSeconds: 300

为什么没提前发现: 发布前没演练「新 Pod 预热慢于流量切换」场景;监控没把 Pod 生命周期事件和网关错误率联动;HPA 策略上线前缺少波动流量下的稳定性验证。问题早就存在,只是平时没在最差时间点一起触发。

从救火到治理:真正该升级的不是命令熟练度

排障能力长期差距在治理方式,演进四阶段:

  1. 纯人工救火——人工看日志、删 Pod、重启,高度依赖个别人经验,恢复质量不稳定
  2. 脚本化排查——常用 kubectl/日志检索/资源检查一键脚本,本质仍是「报警后再响应」
  3. 自动识别与自动修复——Node Problem Detector 标记异常节点、Draino 自动驱逐问题节点工作负载、Descheduler 处理长期资源倾斜,把人肉发现前移为系统识别
  4. 把高风险配置挡在上线之前——OPA/Kyverno 禁止危险探针与不合理资源配置上线、Chaos Mesh 定期演练节点/网络/存储故障、eBPF 提升网络可观测性

平台成熟的标志不是「出故障时救得回来」,而是「很多故障根本进不了生产」。

可执行的排障检查清单

发布或流量切换后异常: 是否刚发生 Deployment/ConfigMap/Secret/Ingress 变更?readinessProbe 是否过早放量?preStop 与优雅停机是否真的生效?客户端连接池是否仍复用旧连接?HPA 是否同时发生扩缩容震荡?

Pod 起不来: 是 Pending、ContainerCreating、CrashLoopBackOff 还是 OOMKilled?Events 里是调度失败、挂载失败、探针失败还是镜像拉取失败?节点是否存在 DiskPressure/MemoryPressure?request/limit 是否与真实负载严重偏离?

服务调用异常: DNS、Endpoints、Ingress/Service 端口映射是否一致?NetworkPolicy 是否拦住 DNS 或数据库流量?是否存在 Service Mesh 默认超时或重试放大?节点 conntrack 是否逼近上限?

状态服务异常: 问题在 Pod、PVC、CSI 还是底层存储拓扑?StatefulSet 对应数据是否有备份和恢复路径?是否误把「删 Pod」当作状态数据恢复手段?

适用边界

20 条法则最适合:已有一定规模 K8s 生产环境、微服务多发布频繁、流量波动明显、团队已经历过节点/网络/探针/HPA 典型故障。规模还小(少量服务、发布不频繁、无复杂 sidecar/mesh/StatefulSet)时,最优先不是引入高级治理组件,而是打牢基础:request/limit 配准、探针配置合理、发布过程可观测、节点资源与系统组件有清晰告警。复杂度本身也是成本——很多 K8s 故障恰恰是「为了更高级的能力引入了超出团队消化能力的复杂度」。

总结:五条最值得记住的原则

  1. 先确认故障范围,再深入单点
  2. 先看 Events 和状态变化,再看业务猜测
  3. 先修复流量切换和生命周期,再迷恋「重启大法」
  4. 任何自动化能力都建立在可信监控和合理资源声明之上
  5. 真正成熟的平台,不是不会出故障,而是故障不会再以同样方式重复出现

当团队把这些经验沉淀成探针规范、发布策略、监控面板、策略校验和演练机制时,Kubernetes 才真正从「一个会编排容器的系统」变成「一个可以承载生产稳定性的工程平台」。

关联页面

页面关联点
k8s-troubleshooting-principlesK8s 生产排障基本原则与快速定位五步法(分层排查/先状态后日志/不轻易重启)
k8s-troubleshooting-quick-reference现象到根因速查:黄金五步思维模型、Pod 常见故障、Node NotReady、Service/Ingress 502
k8s-top10-troubleshooting-checklistK8s 高频问题一站式排查清单(10 大故障场景)
k8s-production-incident-case-studiesK8s 生产 10 大故障复盘(etcd 写满/API Server OOM/证书过期/HPA 抖动等)
k8s-rolling-update-pitfalls滚动更新无损发布误区:Ready ≠ 可用、优雅终止与连接排空
k8s-probes-guide三探针职责、探测方式、生产配置模板与踩坑点
k8s-pod-pending-troubleshooting-guidePod Pending 排障:资源碎片化/污点/亲和性/存储/配额/选择器
k8s-pod-evicted-troubleshootingPod Evicted 驱逐机制:驱逐信号、硬软阈值、QoS 优先级、四步排查
k8s-statefulset-guideStatefulSet 完全指南:稳定标识、volumeClaimTemplates、排障
k8s-scheduling-strategy-guide调度策略:nodeAffinity/污点容忍/topologySpread/亲和性反亲和
k8s-service-access-troubleshooting服务访问排查十步工作流:Pod→Service→Ingress
k8s-dns-troubleshooting-sopDNS 故障排查与高可用 SOP(含 conntrack 与 CoreDNS 优化)
k8s-dns-conntrack-5s-timeoutDNS 间歇 5s 解析超时:conntrack 竞态 + ndots 放大
k8s-multicluster-istio-canary多集群 + Istio 灰度发布与流量治理(mesh 排障入口)
k8s-capacity-planning-qos-cost-optimization容量规划与弹性伸缩协同(HPA/VPA/CA/Karpenter)
k8s-java-directmemory-oom-diagnosisJava DirectMemory OOM:-Xmx ≠ 总内存、OOMKilled 与标准配置
node-troubleshootingNode 排障:NotReady、kubelet/容器运行时/证书/资源压力
storage-troubleshooting存储排障:PVC Pending、挂载失败、CSI
container-networking-troubleshooting容器网络 6 层模型(NetworkPolicy/CNI/kube-proxy)
configmap-mount-pitfallsConfigMap 挂载踩坑:只读/符号链接/热更新/subPath