华为云 CCE 集群里 Pod 频繁重启,怎么定位根因
重启不等于崩溃
Pod 频繁重启是最容易被误判的一类问题。很多人一看到 RESTARTS 数字变大就去翻应用日志找 panic,但实际上一半以上的场景根本没有 panic。先分清三种情况,能省掉很多无用功。
第一步:看重启原因到底是哪个
kubectl describe pod <pod-name> -n <namespace>
重点看容器的 Last State 和 Reason 字段:
OOMKilled:内存超了被内核杀掉,不是应用 bug,是 limits 设小了Error+ 退出码 1:应用自己退出的,这时才需要看日志Completed:进程正常结束。如果容器主进程是前台脚本跑完就退出,K8s 会一直重启它ContainerCannotRun:镜像或启动命令有问题
第二步:分清是容器重启还是 Pod 重建
这两件事经常被混为一谈。看 RESTARTS 列是容器重启(同一个 Pod 内),看 Pod 的 AGE 和 NAME 后缀变化才是重建。
- 容器重启:同一个 Pod,可能被 liveness 探针杀掉、被 OOM 杀掉、进程自己退出
- Pod 重建:调度失败、节点 NotReady、被 HPA 缩容再扩容
如果是第二种,去看 kubectl get events 和节点状态,跟应用代码无关。
第三步:liveness 探针是重灾区
最常见的坑是把 liveness 和 readiness 配成一个接口、一样的超时。
livenessProbe失败会重启容器。如果探针接口依赖数据库,数据库慢一下容器就被杀了,然后启动又要重新连数据库,越滚越糟readinessProbe失败只会摘流量,不会重启
经验值:liveness 的 initialDelaySeconds 要留足冷启动时间,Java 应用经常要 60 秒以上。timeoutSeconds 默认 1 秒太短,网络抖动就会误判。探针接口不要依赖外部依赖。
第四步:OOMKilled 别急着调大 limit
先确认是真的内存用量高,还是堆外内存或 page cache 吃掉的。Java 应用没设 -Xmx 的情况下会按宿主机内存算堆大小,在容器里就很容易超。
docker stats # 或在 CCE 控制台看容器内存监控
kubectl top pod <pod-name> -n <namespace>
如果是 JVM,-XX:MaxRAMPercentage 比固定 -Xmx 更适合容器环境。另外 limit 设成和 request 相等可以拿到 Guaranteed QoS,被驱逐的概率低很多。
第五步:看是不是被节点驱逐
节点内存或磁盘压力大时会驱逐 Pod,事件里能看到 Evicted。这种情况改应用没用,要扩容节点或者调整调度策略。
一个容易被忽略的点
CCE 集群里如果开了弹性伸缩,缩容时 Pod 被终止也会计入重启统计。排查时先确认时间点有没有发生过扩容缩容事件,否则会把正常的调度行为当成故障。
排查顺序建议固定下来:describe 看 reason,再分清容器重启还是 Pod 重建,最后才深入应用。顺序反了容易在日志里绕很久。
- 点赞
- 收藏
- 关注作者
评论(0)