服务覆盖:昆明·曲靖·玉溪·保山·昭通·丽江·普洱·临沧·楚雄·红河·文山·西双版纳·大理·德宏·怒江·迪庆

查看当前容器日志

eycit 2026-04-20 -2 次阅读 系统安装
---

theme: default themeName: "默认主题" title: "K8s Pod反复重启业务崩溃?掌握这四步排查思路,彻底搞定不断重启"


前言

Pod反复重启是Kubernetes日常运维中最让人头疼的问题之一。它不像服务器宕机那样一眼就看出问题,而是偷偷摸摸地restart、restart、再restart,等你发现时,业务可能已经断断续续不可用了。很多新手面对Pod不断重启,第一反应是重启大法——删掉Pod重建,但往往是治标不治本。本文给你一套系统化的排查思路,下次遇到Pod重启问题,照着流程走一遍,保管药到病除。

Pod重启的四种原因

在动手排查之前,先搞清楚Pod为什么会重启。Kubernetes中Pod的重启由Liveness Probe(存活探针)失败触发,总结下来无非四种原因:

应用自身崩溃:程序抛出未捕获的异常、OOM被杀、收到SIGTERM/SIGKILL信号 健康检查失败:Liveness/Readiness探针连续多次检测失败 依赖服务不可用:数据库/缓存/下游API连接超时/拒绝 资源不足被驱逐:Node资源紧张时K8s会主动驱逐Pod

排查第一步:查看Pod状态和事件

最直接的信息来源是kubectl describe,百分之八十的问题在这里就能找到答案:

kubectl describe pod  -n 

重点关注这几个区域:

Events:事件列表,看最后几行
Events:

Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 5m default-scheduler Successfully assigned default/myapp-xyz to node-1 Normal Pulling 5m kubelet Pulling image "myapp:latest" Normal Pulled 4m kubelet Successfully pulled image "myapp:latest" Normal Created 4m kubelet Created container myapp Normal Started 4m kubelet Started container myapp Warning BackOff 2m kubelet Back-off restarting failed container

看到`Back-off restarting failed container`就说明容器启动后失败了,K8s在自动重试。这是第一个信号——容器根本没有正常跑起来。

排查第二步:查看容器日志

容器启动失败了,那就看日志:

# 查看当前容器日志

kubectl logs -n

如果Pod重启过,加上--previous看上次失败的日志

kubectl logs -n --previous

日志会告诉你具体是什么错误。常见几类:

端口绑定失败
listen tcp 0.0.0.0:8080: bind: address already in use

端口被占用了,可能是程序配置问题或者同一Pod内多个容器端口冲突。

配置文件找不到
Error: failed to start container ... Error response ... "container "myapp" in pod "xxx": not found: configmap "app-config" not found"

依赖的ConfigMap或Secret没挂载进来。

数据库连接失败
panic: failed to connect to database: dial tcp 10.244.1.5:5432: connect: connection refused

依赖的服务还没ready或者网络不通。

OOMKilled

如果日志里没内容,直接看容器退出码:

kubectl get pod  -n  -o jsonpath='{.status.containerStatuses[].lastState.terminated.exitCode}'

退出码137 = 收到SIGKILL信号,通常是OOM。退出码143 = 收到SIGTERM,优雅退出。

排查第三步:检查资源限制和探针配置

如果日志看起来正常,容器也能启动,但运行一段时间后就挂——可能是资源不够被OOM,或者健康检查失败。

查看资源限制
kubectl get pod  -n  -o jsonpath='{.spec.containers[].resources}'

典型的问题配置:

resources:

requests: memory: "128Mi" cpu: "100m" limits: memory: "128Mi" # 刚好够用,一有波动就OOM cpu: "100m"

内存request设置得太紧,一有点内存波动就触发OOMKilled。解决:适当放宽limits,或者检查应用是否有内存泄漏。

检查探针配置
livenessProbe:

httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 # 连续3次失败才重启 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5

问题场景:

  • initialDelaySeconds设置太短,容器还没启动完就检测,导致连续失败→重启
  • /healthz接口响应慢,超时失败
  • 依赖的数据库不可用时,/healthz返回失败,触发重启

排查第四步:检查依赖和调度

如果前三步都没问题,那问题可能在Pod依赖上。

查看Pod依赖是否Ready
kubectl get pods -n  -o wide | grep 
检查网络连通性
# 进入Pod内部测试网络

kubectl exec -it -n -- sh

然后

nc -zv 8080 ping

查看Node资源情况
kubectl describe node 

重点看Allocatable和Allocated resources部分,如果内存或CPU已经分配了90%以上,说明Node资源紧张,Pod可能被驱逐。

真实案例:Java应用OOM导致无限重启

一个Spring Boot应用部署到K8s后,Pod一直在重启。describe看到Back-off日志,logs看到OOMKilled。

排查过程

1. `kubectl logs --previous` 没有输出(OOM时应用直接被kill) 2. 查看JVM内存参数:-Xmx512m,而Pod的memory limit也是512m 3. 问题在于:JVM堆内存512m + Metaspace + 线程栈 + 容器开销 > 512m limit,一超过就被OOM Kill

解决方案

  • 将memory limit调大到768m
  • 或者调整JVM参数:-XX:MaxRAMPercentage=70.0,让JVM自动按容器限制调整堆大小

预防Pod重启的最佳实践

1. 合理设置资源限制:requests不能太小,limits要比requests大50%-100% 2. 正确配置探针:initialDelaySeconds要大于应用启动时间,failureThreshold别太低 3. 添加优雅停止:处理SIGTERM信号,给业务留出收尾时间 4. 开启Pod Disruption Budget:保证滚动更新时最小可用实例数 5. 监控告警:记录Pod重启次数,设置阈值告警

# 优雅停止示例

lifecycle: preStop: exec: command: - /bin/sh - -c - "sleep 10"

结语

Pod反复重启排查的核心就四步:看事件→看日志→查资源→查依赖。80%的问题在第一步describe就能发现线索,别一上来就删Pod重建,那只会掩盖问题而不是解决问题。下次遇到Pod重启,照着这个流程走一遍,保证你不再是那个只会重启的运维。


看完还有什么疑问吗?

如果文章没有覆盖到你的情况,欢迎联系我们咨询——免费解答,说清楚再决定要不要服务。

📞 服务热线:13708730161 💬 微信:eyc1689 📧 邮箱:service@eycit.com 🌐 https://www.eycit.com

易云城IT服务,您身边的IT专家。

上一篇
查看所有网卡状态和统计信息...
下一篇
查看当前会话限制...