Kubernetes故障排查实战手册:从CrashLoopBackOff到etcd应急的全链路诊断

Kubernetes集群故障排查的通用方法论

Kubernetes容器编排的生产环境里,故障排查是SRE稳定性工程的核心能力。Pod CrashLoopBackOff、Service访问不通、节点NotReady、资源抢占导致OOMKilled——这些问题每天都有可能碰到。DevOps实践的关键不是记住所有故障场景,而是掌握一套系统化的排查路径:从控制面到数据面,从组件状态到日志分析,逐步缩小问题范围。

下面按故障类别逐一拆解,每个场景给出诊断命令和修复操作。

Pod状态异常:CrashLoopBackOff排障全流程

CrashLoopBackOff是生产环境最常见的Pod故障。表现是Pod反复启动然后崩溃,kubelet不断重试。排查的第一步永远是看事件和日志:

# 查看Pod事件
kubectl describe pod <pod-name> -n <namespace>

# 关键信息在底部Events段,关注:
# - Warning  BackOff    ... Container <name> failed
# - Warning  Failed     ... Error: exit code 137 (OOMKilled)
# - Warning  Unhealthy  ... Liveness probe failed

# 查看容器日志(当前崩溃的实例)
kubectl logs <pod-name> -n <namespace> --previous

# 如果previous也看不到日志,看当前实例
kubectl logs <pod-name> -n <namespace>

常见的CrashLoopBackOff原因和修复方法:

  • exit code 137 (OOMKilled):调整resources.limits.memory,或者在应用层面优化内存使用
  • exit code 1/2:应用配置错误,检查环境变量和ConfigMap挂载是否正确
  • Liveness probe failed:探针超时阈值太短或应用启动慢,调整initialDelaySeconds和timeoutSeconds
  • ImagePullBackOff:镜像拉取失败,检查镜像地址和网络策略

Service与Ingress访问不通的诊断

Service访问不通的排查分四层:Service配置→Endpoints→网络策略→kube-proxy。

# 第1步:检查Service配置和Endpoints
kubectl get svc <svc-name> -n <namespace> -o wide
kubectl get endpoints <svc-name> -n <namespace>

# Endpoints为空说明selector没匹配到Pod
# 检查selector标签是否和Pod标签一致
kubectl get pods -n <namespace> --show-labels

# 第2步:集群内测试Service连通性
kubectl run tmp-shell --rm -i --tty --image busybox -- sh
# 在临时Pod内:
wget -qO- http://<svc-name>.<namespace>.svc.cluster.local:<port>

# 第3步:检查NetworkPolicy是否阻断流量
kubectl get networkpolicy -n <namespace>

# 第4步:检查kube-proxy运行状态
kubectl get pods -n kube-system -l k8s-app=kube-proxy
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=50

Ingress访问不通时,先确认Ingress Controller是否正常运行,再检查Ingress资源配置:

# 检查Ingress Controller状态
kubectl get pods -n ingress-nginx

# 检查Ingress资源配置
kubectl describe ingress <ingress-name> -n <namespace>

# 常见问题:
# 1. TLS证书过期或secret不存在
# 2. pathType配置错误(Exact vs Prefix)
# 3. 后端Service端口名不匹配

节点NotReady的根因分析与修复

节点NotReady意味着kubelet与API Server通信中断,或节点条件不满足。排查路径:

# 查看节点条件和事件
kubectl describe node <node-name>

# 关键字段: Conditions段
# - Ready = Unknown → kubelet失联
# - MemoryPressure = True → 内存压力
# - DiskPressure = True → 磁盘压力
# - PIDPressure = True → 进程数过多

# SSH到节点上检查kubelet日志
journalctl -u kubelet --since "10 minutes ago" --no-pager

# 常见原因:
# 1. 磁盘满: docker/containers目录占满磁盘
#    → 清理未使用的镜像和停止的容器
docker system prune -af --volumes

# 2. kubelet证书过期: 
#    → 重新生成kubelet客户端证书
# 3. CPU负载过高: 
#    → 检查是否有异常进程占用CPU
top -c

修复后如果节点状态恢复为Ready但Pod没有自动调度回来,需要手动删除处于Terminating状态的Pod:

# 强制删除卡在Terminating的Pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0

# 如果节点要永久下线,先cordon和drain
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

资源竞争与QoS等级调优

Pod被OOMKilled不一定是内存泄漏,也可能是QoS等级太低被系统优先驱逐。Kubernetes把Pod分成三个QoS等级:Guaranteed(requests=limits)、Burstable(requests<limits)、BestEffort(无requests/limits)。内存紧张时,系统按BestEffort→Burstable→Guaranteed的顺序驱逐。

# 查看Pod的QoS等级
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.qosClass}'

# 生产环境关键业务Pod必须设置Guaranteed QoS
resources:
  requests:
    cpu: "4"
    memory: "16Gi"
  limits:
    cpu: "4"
    memory: "16Gi"  # requests和limits完全一致

# Burstable适用于可容忍偶尔被驱逐的中间层服务
resources:
  requests:
    cpu: "2"
    memory: "8Gi"
  limits:
    cpu: "4"
    memory: "16Gi"

etcd集群故障应急响应

etcd是Kubernetes控制面的存储后端,etcd不可用等于整个集群不可用。关键监控指标:

# etcd健康检查
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health

# 关键告警指标:
# - etcd_disk_wal_fsync_duration_seconds > 10ms → 磁盘IO慢
# - etcd_mvcc_db_total_size_in_bytes > 8GB → 数据库过大
# - etcd_server_has_leader = 0 → 无Leader,集群无法写入

# etcd数据库压缩(解决db过大问题)
ETCDCTL_API=3 etcdctl --endpoints=<endpoint> compact $(etcdctl endpoint status --write-out=json | python3 -c "import sys,json;print(json.load(sys.stdin)[0]['Status']['header']['revision'])")
ETCDCTL_API=3 etcdctl --endpoints=<endpoint> defrag

etcd故障的黄金法则:不要在etcd异常时重启API Server,那只会让情况更糟。先修复etcd,再恢复其他组件。

CI/CD流水线与混沌工程集成

故障排查能力需要持续验证。在CI/CD流水线中加入混沌工程测试,自动注入故障验证系统自愈能力:

# 使用Chaos Mesh注入Pod故障
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: web-pod-failure
  namespace: chaos-testing
spec:
  action: pod-failure
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: web-service
  duration: "30s"
  scheduler:
    cron: "@every 5m"

混沌工程的核心不是制造混乱,而是用可控的故障注入来验证系统的故障应急响应机制是否生效。每次发布前跑一轮混沌测试,比人工巡检可靠得多。

监控告警体系的关键指标

Kubernetes故障排查的效率取决于监控告警体系是否完善。必须覆盖的核心指标:

  • API Server延迟:apiserver_request_duration_seconds > 1s 持续5分钟
  • Pod重启次数:increase(kube_pod_container_status_restarts_total[1h]) > 3
  • 节点NotReady:kube_node_status_condition{condition=”Ready”,status=”true”} == 0
  • etcd写延迟:etcd_disk_wal_fsync_duration_seconds > 0.01
  • PVC使用率:kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes > 0.85

告警不在于多,在于精准可操作。每条告警必须有明确的处理SOP,否则就是噪音。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-gu-zhang-pai-cha-shi-zhan-shou-ce-cong/

(0)
小编小编
上一篇 15小时前
下一篇 15小时前

相关推荐