Kubernetes容器编排故障排查手册:从Pod异常到集群级诊断

Kubernetes容器编排环境中,故障排查是SRE稳定性工程的核心技能。与单机运维不同,K8s的故障点分散在Pod、Node、Control Plane等多个层级,问题定位需要系统化的诊断路径。本文整理了一套从Pod级别到集群级别的完整排查流程,覆盖Docker自动化部署场景下最常见的故障模式。

Pod状态异常的分级诊断方法

Pod是K8s最小调度单元,几乎所有业务故障的入口都从这里开始。不同状态对应不同的排查方向:

Pending状态:调度失败,资源不足或约束冲突。

kubectl describe pod <pod-name> -n <namespace>
# 查看Events部分,常见原因:
# - Insufficient cpu/memory
# - node(s) didn't match Pod's node affinity/selector
# - persistentvolumeclaim not found

CrashLoopBackOff状态:容器启动后反复崩溃。

kubectl logs <pod-name> -n <namespace> --previous
# 查看上一次崩溃的日志,常见原因:
# - 应用配置错误(连接数据库失败、环境变量缺失)
# - 健康检查配置不当(livenessProbe探针过于严格)
# - 资源限制过小(OOMKilled)

ImagePullBackOff状态:镜像拉取失败。

kubectl describe pod <pod-name> -n <namespace>
# 常见原因:
# - 镜像名或标签错误
# - 私有仓库认证失败(需配置imagePullSecrets)
# - 网络策略阻止外网访问

Service与Ingress流量不通的诊断路径

Service和Ingress故障占K8s运维问题的30%以上。排查路径遵循从内到外的原则:

第一步:验证Pod本身是否正常接收请求:

# 直接访问Pod IP
kubectl get pod -n <namespace> -o wide
curl http://<pod-ip>:<container-port>/healthz

第二步:验证Service ClusterIP是否可达:

# 从集群内任意Pod访问Service
kubectl run tmp-shell --rm -i --tty --image=busybox -- sh
wget -qO- http://<service-name>.<namespace>.svc.cluster.local:<port>/healthz

第三步:验证Endpoints是否正确关联:

kubectl get endpoints <service-name> -n <namespace>
# 如果Endpoints为空,检查selector标签是否匹配Pod标签
kubectl describe svc <service-name> -n <namespace>

第四步:Ingress配置检查:

kubectl describe ingress <ingress-name> -n <namespace>
# 检查Backends字段是否显示healthy
# 检查TLS证书是否正确配置

Node节点故障与资源压力排查

Node级别问题通常表现为Pod调度异常或性能劣化。核心诊断命令:

# 节点资源使用情况
kubectl top nodes

# 节点详细状态
kubectl describe node <node-name>
# 关注Conditions部分:
# - MemoryPressure: true → 节点内存压力
# - DiskPressure: true → 磁盘空间不足
# - PIDPressure: true → 进程数过多
# - Ready: Unknown → 节点与API Server失联

节点NotReady处理流程:

1. SSH登录节点检查kubelet状态:systemctl status kubelet

2. 检查kubelet日志:journalctl -u kubelet -n 100 --no-pager

3. 常见原因:磁盘满(清理/var/lib/docker和日志)、证书过期、网络插件异常

4. 恢复后节点重新Ready,原调度到该节点的Pod可能已被驱逐,需检查kubectl get pods -A -o wide | grep <node>

Control Plane组件异常诊断

Control Plane故障影响面最大,需优先排查:

# 检查组件状态
kubectl get componentstatuses

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

# API Server日志
kubectl logs -n kube-system kube-apiserver-<master-node>

# Scheduler和Controller Manager日志
kubectl logs -n kube-system kube-scheduler-<master-node>
kubectl logs -n kube-system kube-controller-manager-<master-node>

etcd是最关键的组件,etcd不可用意味着整个集群不可用。定期检查etcd磁盘延迟(etcdctl endpoint status --write-out=table),超过100ms即需关注。etcd数据备份是最后的保障,建议每日自动执行:

ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/peer.crt \
  --key=/etc/kubernetes/pki/etcd/peer.key

CI/CD流水线中的K8s部署故障定位

CI/CD流水线中的K8s部署失败通常与权限和配置版本有关。排查清单:

1. RBAC权限不足:ServiceAccount未绑定正确的ClusterRole,检查kubectl auth can-i验证权限。

2. Helm值覆盖错误helm diff upgrade对比变更,确认values文件合并逻辑。

3. 滚动更新卡住:Readiness探针未通过,新版本Pod无法就绪。检查kubectl rollout statuskubectl get events

4. 回滚操作kubectl rollout undo deployment/<name>回退到上一个版本,kubectl rollout history查看历史。

日志分析与监控告警体系设计

集群级故障排查离不开日志聚合和监控体系。推荐工具组合:

日志:Fluent Bit → Elasticsearch → Kibana。Fluent Bit以DaemonSet部署在每个节点,采集/var/log/containers/下的容器日志。

监控:Prometheus + Grafana。关键告警规则包括:节点CPU/内存超过85%、Pod重启次数5分钟内超3次、etcd磁盘延迟超100ms、API Server请求延迟超500ms。

故障应急响应的黄金原则:先恢复再排查。通过kubectl rollout undo快速回滚,待服务恢复后再通过日志和事件定位根因。

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

(0)
小编小编
上一篇 2026年8月3日
下一篇 2026年8月3日

相关推荐

Kubernetes容器编排故障排查手册:从Pod CrashLoop到网络策略的实战诊断

Kubernetes故障排查为什么需要结构化方法论

K8s集群的故障表现往往与根因不在同一层级——Pod报CrashLoopBackOff可能是应用代码问题,也可能是资源配置错误或Secret挂载失败。无头排查容易在错误方向浪费时间。结构化排查的顺序是:集群级→节点级→Pod级→容器级→应用级,逐层缩小范围。

Pod CrashLoopBackOff的五种常见根因与诊断命令

CrashLoopBackOff是最常见也最令人困惑的Pod状态,本质是容器反复启动后退出。逐条排查:

1. 应用启动失败(退出码非0)

# 查看容器退出码和上次日志
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
kubectl logs <pod-name> --previous

# 退出码1:应用错误,看日志定位具体异常
# 退出码137:OOMKilled,内存不足被杀
# 退出码139:Segfault,通常是C库或JNI问题

2. 存活探针配置过于激进

# 检查探针配置
kubectl get pod <pod-name> -o yaml | grep -A10 livenessProbe

# 常见问题:initialDelaySeconds太短,应用还没初始化完就被探测
# 修复:把initialDelaySeconds设为应用实际启动耗时的1.5倍
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30   # 根据实际启动时间调整
  periodSeconds: 10
  failureThreshold: 3

3. ConfigMap或Secret挂载失败

# 查看Events中的挂载错误
kubectl describe pod <pod-name> | grep -A5 Warning

# 典型错误:"secret <name> not found"——Secret在另一个namespace
# 修复:确保Secret与Pod在同一个namespace,或使用cross-namespace引用

4. 资源Limit设置不合理

# 查看实际资源使用vs限制
kubectl top pod <pod-name> --containers
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resources}'

# CPU Throttle误判:limits.cpu设太低,应用看起来慢但不报错
# 区分OOM和CPU throttle:OOM会重建容器,throttle只是变慢

5. Init容器执行失败

# 查看Init容器状态
kubectl get pod <pod-name> -o jsonpath='{.status.initContainerStatuses}'
kubectl logs <pod-name> -c <init-container-name>

Service与网络策略的连通性诊断

服务不可达是第二大类故障。排查链路:Service→Endpoint→NetworkPolicy→DNS。

# 1. 检查Service是否有后端Endpoint
kubectl get endpoints <svc-name>
# 如果ENDPOINTS是<none>,说明selector匹配不到Pod

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

# 3. 检查NetworkPolicy是否阻断流量
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>

NetworkPolicy的坑在于默认行为——如果namespace中存在任何允许入站的Policy,未匹配的流量会被拒绝而不是允许。排查时用kubectl describe逐条检查规则是否遗漏了必要的端口或来源。

节点NotReady的排查路径

节点NotReady通常由kubelet问题引起,排查顺序:

# 1. SSH到故障节点,检查kubelet状态
systemctl status kubelet
journalctl -u kubelet --since "1 hour ago" | tail -50

# 2. 检查节点资源压力(磁盘/内存/PID)
df -h /var/lib/kubelet    # 磁盘使用率超过85%会触发驱逐
free -h
ps -e --no-headers | wc -l  # PID数量

# 3. 检查节点条件
kubectl describe node <node-name> | grep -A5 Conditions

# 4. 常见修复
# 磁盘满:清理旧容器镜像
crictl rmi --prune
# PID耗尽:调整kubelet的pidLimit
# kubelet证书过期:重新签发证书

集群级故障的应急响应流程

etcd不可用是集群级故障中最严重的场景——所有写操作都会失败。应急步骤:

# 检查etcd集群健康
ETCDCTL_API=3 etcdctl endpoint health \
  --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

# 如果多数节点不可用,集群已丧失写入能力
# 不要尝试重启所有etcd节点——会造成数据丢失
# 正确做法:保留一个数据最完整的节点,移除故障节点后逐一恢复
ETCDCTL_API=3 etcdctl member remove <failed-member-id>

故障排查的关键不是记住所有命令,而是掌握分层诊断的方法论。从集群到应用逐层缩小范围,每一层用对应的诊断工具确认状态,避免盲目猜测。

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

(0)
小编小编
上一篇 2026年7月30日
下一篇 2026年7月30日

相关推荐

Kubernetes容器编排故障排查手册:从Pod CrashLoopBackOff到节点NotReady的诊断链路

K8s故障排查的核心思路:从事件到根因的递进式诊断

Kubernetes容器编排环境的故障排查和传统单机运维完全不同。一个服务不可用,可能涉及Pod、Deployment、Service、Ingress、节点等多个层级。DevOps实践中最有效的诊断路径是自底向上:先看Pod状态,再看节点状态,最后排查网络和存储。这条诊断链路覆盖了90%以上的K8s生产故障场景。SRE稳定性工程的核心就是把这条链路标准化、工具化,把平均故障恢复时间(MTTR)压到最低。

Pod CrashLoopBackOff:最常见也最容易误判的故障

Pod反复崩溃重启,kubectl get pods显示CrashLoopBackOff状态。排查步骤:

# 第一步:查看Pod事件
kubectl describe pod <pod-name> -n <namespace>

# 第二步:查看容器日志(前一次崩溃的日志)
kubectl logs <pod-name> -n <namespace> --previous

# 第三步:查看当前日志
kubectl logs <pod-name> -n <namespace>

# 第四步:检查容器退出码
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'

常见退出码含义:

  • Exit Code 0:进程正常退出(检查是否缺少前台阻塞进程导致容器立即退出)
  • Exit Code 137:OOMKilled,内存超限被杀,需要调大resources.limits.memory
  • Exit Code 139:Segfault,应用本身内存越界,需要检查代码或依赖库版本
  • Exit Code 1:应用启动失败,通常是配置文件错误或依赖服务不可达
# 快速定位OOM问题
kubectl describe pod <pod-name> -n <namespace> | grep -A5 "Last State"

# 临时调大内存限制验证
kubectl set resources deployment <deploy-name> -n <namespace> \
  --containers=<container-name> \
  --limits=memory=1Gi \
  --requests=memory=512Mi

ImagePullBackOff:镜像拉取失败的系统性排查

镜像拉取失败在生产环境中往往不是镜像本身的问题,而是网络、认证或存储驱动层面的故障。

# 查看详细错误信息
kubectl describe pod <pod-name> -n <namespace> | grep -A10 Events

# 在节点上直接测试镜像拉取
crictl pull <registry>/<image>:<tag>

# 检查节点上的容器运行时配置
cat /etc/containerd/config.toml | grep -A5 registry

根因分类:

  1. 认证失败:私有Registry未配置imagePullSecrets,或Secret过期
  2. 网络不通:节点无法访问Registry,检查DNS解析和防火墙策略
  3. 镜像不存在:Tag拼写错误或镜像已被删除
  4. 存储驱动:节点磁盘满或overlayfs异常
# 创建Registry认证Secret
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=robot\$pull \
  --docker-password=<token> \
  --docker-email=admin@example.com \
  -n <namespace>

# 在Deployment中引用
kubectl patch serviceaccount default -n <namespace> \
  -p '{"imagePullSecrets": [{"name": "regcred"}]}'

节点NotReady:从kubelet到基础设施的逐层排查

节点变为NotReady状态,意味着kubelet无法正常向API Server上报节点状态。Docker自动化部署和容器管理的底层依赖出问题,上层所有Pod都会受影响。

# 查看节点状态和条件
kubectl describe node <node-name> | grep -A15 "Conditions"

# SSH到节点检查kubelet
systemctl status kubelet
journalctl -u kubelet --since "10 minutes ago"

# 检查节点资源使用
df -h        # 磁盘
free -h      # 内存
top          # CPU

# 检查容器运行时
systemctl status containerd
crictl ps

NotReady的常见根因:

  • 磁盘满:kubelet无法写入日志和数据,Docker image目录占满磁盘
  • PLEG超时:容器运行时响应慢,通常是docker/containerd的日志文件过大
  • 网络插件异常:CNI Pod崩溃导致节点网络配置丢失
  • 内核问题:内核死锁或cgroup内存泄漏
# 清理节点磁盘空间(紧急处理)
crictl rmi --prune  # 清理无用镜像
journalctl --vacuum-size=200M  # 清理系统日志
find /var/log/containers -name "*.log" -size +100M -delete

# 重启kubelet恢复节点
systemctl restart kubelet

Service与Ingress连通性问题

Pod正常但Service不可达,排查链路:

# 1. 检查Endpoints是否正常
kubectl get endpoints <svc-name> -n <namespace>

# 2. 在集群内测试Service连通性
kubectl run test --image=busybox -it --rm -- wget -qO- <svc-name>:<port>

# 3. 检查kube-proxy
kubectl logs -n kube-system -l k8s-app=kube-proxy
iptables -t nat -L KUBE-SERVICES | grep <svc-cluster-ip>

# 4. Ingress Controller日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

Service没有Endpoints通常是selector标签不匹配。Ingress 404/502则需要检查后端Pod的readinessProbe配置。

监控告警体系:故障预警与自动化诊断

故障排查不能全靠人工巡检。完善的监控告警体系应该覆盖:

  1. Pod级别:RestartCount > 3 触发告警,CrashLoopBackOff 立即告警
  2. 节点级别:DiskPressure、MemoryPressure、NotReady 状态变更
  3. 集群级别:API Server延迟P99 > 500ms,etcd磁盘延迟 > 100ms
  4. 业务级别:Service错误率 > 1%,P99延迟 > 2s
# Prometheus规则示例:Pod重启告警
- alert: PodCrashLoopBackOff
  expr: rate(kube_pod_container_status_restarts_total[15m]) * 60 * 5 > 0
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} is crash looping"
    runbook: "https://ops.internal/runbook/pod-crashloop"

K8s故障排查的效率取决于两个因素:对架构分层的理解深度,以及诊断工具链的完备度。把describe、logs、events这三板斧用熟练,配合监控告警体系做自动化预警,大部分故障都能在5分钟内定位到根因。

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

(0)
小编小编
上一篇 2026年7月30日
下一篇 2026年7月30日

相关推荐