K8s 排障:那次让我记忆犹新的 Pod CrashLoopBackOff

举报
yd_245825151 发表于 2026/10/22 05:46:53 2026/10/22
【摘要】 一、凌晨两点的告警那是去年双十一大促前的压测夜。凌晨两点,手机响了——Prometheus 告警:订单服务的 Pod 连续重启,状态 CrashLoopBackOff。我迷迷糊糊打开电脑,看到 6 个 Pod 里有 4 个在不断重启。每次起来撑 30 秒,然后被 kill,再起来,再 kill。K8s 的重启退避机制已经生效,间隔从 10 秒拉长到 5 分钟。线上压测环境,离大促只剩三天。二...

一、凌晨两点的告警

那是去年双十一大促前的压测夜。凌晨两点,手机响了——Prometheus 告警:订单服务的 Pod 连续重启,状态 CrashLoopBackOff。

我迷迷糊糊打开电脑,看到 6 个 Pod 里有 4 个在不断重启。每次起来撑 30 秒,然后被 kill,再起来,再 kill。K8s 的重启退避机制已经生效,间隔从 10 秒拉长到 5 分钟。

线上压测环境,离大促只剩三天。


二、第一层排查:看日志

老规矩,kubectl logs <pod> --previous。

日志只有三行:


纯文本


2026-11-08 02:03:11 INFO  Starting OrderServiceApplication...
2026-11-08 02:03:12 INFO  Loading application configuration...
2026-11-08 02:03:13 ERROR Failed to initialize DataSource

然后是堆栈,核心一行:


纯文本


Caused by: java.net.ConnectException: Connection refused (Address: mysql-order.default.svc.cluster.local:3306)

数据库连接不上。


三、第二层排查:网络通不通

kubectl exec -it <pod> -- nc -zv mysql-order.default.svc.cluster.local 3306

不通。

但 MySQL Pod 明明在跑啊?kubectl get pods 显示 mysql-order-0 是 Running 状态。

试试直接连 IP:kubectl exec -it <pod> -- nc -zv 10.0.3.47 3306——通了。

所以问题在 DNS 解析。


四、第三层排查:CoreDNS 怎么了

kubectl get pods -n kube-system | grep dns

输出让我心里一沉:


纯文本


coredns-7f9c4b9d6c-2xqk8   0/1   Running   0   3m
coredns-7f9c4b9d6c-8mnbv   1/1   Running   0   3m
coredns-7f9c4b9d6c-pqrst   0/1   Running   0   3m

3 个 CoreDNS Pod,2 个不健康。

kubectl logs coredns-7f9c4b9d6c-2xqk8 -n kube-system 里反复出现:


纯文本


[ERROR] plugin/errors: 2 mysql-order.default.svc.cluster.local. A: read udp 10.244.2.15:54321->10.0.0.2:53: i/o timeout

CoreDNS 上游 DNS 超时。


五、根因浮出水面

我们集群的 CoreDNS 配置了 forward . /etc/resolv.conf,而节点的 /etc/resolv.conf 里配的是公司内网 DNS 10.0.0.2。

压测期间,大量新 Pod 启动,每个都要做 DNS 解析。内网 DNS 扛不住了——不是完全挂,是间歇性超时。CoreDNS 把集群内域名解析也转发上去了(配置缺陷),导致内部服务发现跟着一起挂。

链路是这样的:


纯文本


Pod 启动 → 解析 mysql-order.default.svc.cluster.local
→ CoreDNS 收到请求
→ 按配置 forward 到 10.0.0.2(内网 DNS)
→ 内网 DNS 超时
→ Pod 拿不到 DB 地址 → 启动失败 → CrashLoopBackOff

六、止血与修复

止血(5 分钟):

给 CoreDNS 加 rewrite 规则,集群内域名直接走 K8s API,不转发:


corefile


.:53 {
    errors
    health
    rewrite continue {
        name regex (.*)\.default\.svc\.cluster\.local {1}.default.svc.cluster.local
    }
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
    }
    forward . /etc/resolv.conf
    cache 30
}

重启 CoreDNS,订单 Pod 陆续恢复。

根治(后续):

  • CoreDNS 配置改为:集群内域名走 kubernetes 插件,外部域名才 forward
  • 内网 DNS 扩容 + 加本地 cache 插件
  • 加 CoreDNS 监控:解析延迟、转发失败率、缓存命中率

七、这次故障教会我的几件事

1. CrashLoopBackOff 不可怕,可怕的是只看 Pod 不看链路

Pod 重启只是症状。根因可能在网络、DNS、存储、配置任何一个环节。排障要从 Pod 往外一层层剥,而不是盯着 Pod 本身。

2. CoreDNS 是集群的"隐形心脏"

它不出问题时没人注意,一出问题是全集群级联故障。值得单独做监控、做压测、做配置审计。

3. 排障顺序要形成肌肉记忆

我的固定流程:


纯文本


Pod 状态 → 容器日志 → 事件(Event) → 网络连通性 → DNS → 依赖服务 → 资源配额

每次都按这个顺序走,不会漏。

4. 压测不只是压应用,要压基础设施

那次如果提前对 CoreDNS 做过 DNS 压力测试,根本不会等到凌晨两点才暴露。


八、一个排障速查表(建议收藏)


症状

第一检查点

常用命令

CrashLoopBackOff

容器日志

kubectl logs <pod> --previous

ImagePullBackOff

镜像仓库

kubectl describe pod <pod>

Pending

资源/调度

kubectl describe pod <pod> + 看 Events

OOMKilled

内存限制

`kubectl get pod <pod> -o yaml

DNS 解析失败

CoreDNS

kubectl logs -n kube-system -l k8s-app=kube-dns

服务不通

网络策略/Service

kubectl get endpoints <svc>


九、写在最后

那次故障之后,我把整个排障过程写成了一页 A4 纸的"K8s 排障决策树",贴在工位上。后来团队里新来的人遇到类似问题,照着走一遍基本都能定位。

排障能力不是天生的,是一次次被坑出来的。​ 每踩一个坑,就把它变成团队的"免疫记忆"——这才是 SRE 文化的核心。

下次再聊一个更隐蔽的:那次 Pod Running 但 Ready 为 0 的 readiness probe 配置翻车现场。想看的扣 1。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。