Kubernetes 故障排查指南

🔍 故障排查流程

通用排查步骤

1. 确定问题现象 → 2. 收集基础信息 → 3. 分析日志和事件 → 4. 定位根本原因 → 5. 解决问题 → 6. 验证修复

基础信息收集命令

# 集群基础信息
kubectl cluster-info
kubectl get nodes -o wide
kubectl get pods --all-namespaces

# 查看异常资源
kubectl get pods --all-namespaces | grep -v Running
kubectl get events --sort-by=.metadata.creationTimestamp

🔴 Pod故障排查

Pod状态异常

Pending状态

现象:Pod一直处于Pending状态,无法调度

排查步骤

# 1. 查看Pod详情和事件
kubectl describe pod <pod-name>

# 2. 检查节点资源
kubectl top nodes
kubectl describe nodes

# 3. 检查调度约束
kubectl get pod <pod-name> -o yaml | grep -A 10 "nodeSelector\|affinity\|tolerations"

常见原因和解决方案

  • 资源不足:节点CPU/内存不够

    # 解决:调整资源请求或增加节点
    kubectl edit deployment <deployment-name>
    
  • 节点选择器限制:nodeSelector找不到匹配节点

    # 检查并修改nodeSelector
    nodeSelector:
      disktype: ssd  # 确保有节点有这个标签
    
  • 污点和容忍:节点有污点但Pod没有相应容忍

    # 查看节点污点
    kubectl describe node <node-name> | grep Taints
    
    # 添加容忍
    tolerations:
    - key: "node.kubernetes.io/unreachable"
      operator: "Exists"
      effect: "NoExecute"
    
CrashLoopBackOff状态

现象:Pod不断重启

排查步骤

# 1. 查看Pod日志
kubectl logs <pod-name> --previous

# 2. 查看容器退出码
kubectl describe pod <pod-name>

# 3. 检查存活探针配置
kubectl get pod <pod-name> -o yaml | grep -A 10 livenessProbe

常见原因和解决方案

  • 应用启动失败:检查应用配置和依赖

    # 进入容器调试
    kubectl exec -it <pod-name> -- /bin/bash
    
  • 存活探针过于激进:调整探针参数

    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 60  # 增加初始延迟
      periodSeconds: 30        # 增加检查间隔
      failureThreshold: 5      # 增加失败阈值
    
  • 资源限制过小:调整资源限制

    resources:
      limits:
        memory: "512Mi"  # 增加内存限制
        cpu: "500m"
    
ImagePullBackOff状态

现象:无法拉取镜像

排查步骤

# 1. 查看详细错误信息
kubectl describe pod <pod-name>

# 2. 检查镜像名称和标签
kubectl get pod <pod-name> -o yaml | grep image:

# 3. 检查镜像拉取密钥
kubectl get secrets

解决方案

  • 镜像不存在:检查镜像名称和标签
  • 认证失败:配置镜像拉取密钥
    # 创建Docker密钥
    kubectl create secret docker-registry regcred \
      --docker-server=<registry-server> \
      --docker-username=<username> \
      --docker-password=<password>
    
    # 在Pod中使用
    imagePullSecrets:
    - name: regcred
    

Pod性能问题

内存泄漏

现象:Pod内存使用不断增长

排查命令

# 查看内存使用
kubectl top pod <pod-name>

# 进入容器查看进程
kubectl exec -it <pod-name> -- top
kubectl exec -it <pod-name> -- free -h

解决方案

# 设置合理的资源限制
resources:
  limits:
    memory: "1Gi"
  requests:
    memory: "512Mi"
CPU使用率高

现象:Pod CPU使用率持续很高

排查命令

# 查看CPU使用
kubectl top pod <pod-name>

# 查看进程状态
kubectl exec -it <pod-name> -- ps aux --sort=-%cpu

🌐 网络故障排查

Service访问问题

Service无法访问

排查步骤

# 1. 检查Service配置
kubectl get svc <service-name> -o yaml

# 2. 检查端点
kubectl get endpoints <service-name>

# 3. 检查Pod标签匹配
kubectl get pods -l <selector-labels> --show-labels

常见问题

  • 标签选择器不匹配

    # Service选择器
    selector:
      app: myapp
      version: v1
    
    # Pod标签必须匹配
    labels:
      app: myapp
      version: v1
    
  • 端口配置错误

    ports:
    - port: 80          # Service端口
      targetPort: 8080   # Pod端口,必须匹配容器端口
    
DNS解析问题

排查命令

# 测试DNS解析
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default

# 测试Service DNS
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <service-name>.<namespace>.svc.cluster.local

# 检查CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns

网络连通性问题

Pod间无法通信

排查步骤

# 1. 检查网络策略
kubectl get networkpolicy

# 2. 测试网络连通性
kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -- ping <target-pod-ip>

# 3. 检查CNI插件状态
kubectl get pods -n kube-system | grep -E 'flannel|calico|weave'
Ingress访问问题

排查步骤

# 1. 检查Ingress配置
kubectl get ingress <ingress-name> -o yaml

# 2. 检查Ingress Controller
kubectl get pods -n ingress-nginx

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

💾 存储故障排查

PVC绑定问题

PVC一直Pending

排查步骤

# 1. 查看PVC状态
kubectl describe pvc <pvc-name>

# 2. 检查PV可用性
kubectl get pv

# 3. 检查StorageClass
kubectl get storageclass
kubectl describe sc <storageclass-name>

常见原因

  • 没有匹配的PV:创建或配置合适的PV
  • StorageClass问题:检查动态供应配置
  • 访问模式不匹配:确保PV和PVC的访问模式兼容

挂载问题

卷挂载失败

排查命令

# 查看Pod挂载信息
kubectl describe pod <pod-name> | grep -A 5 Mounts

# 检查节点上的挂载
kubectl get pods -o wide  # 找到节点
ssh <node> "df -h | grep <volume-path>"

🔐 安全和权限问题

RBAC权限问题

403 Forbidden错误

排查步骤

# 1. 检查当前用户权限
kubectl auth can-i <verb> <resource>
kubectl auth can-i create pods

# 2. 检查ServiceAccount
kubectl get serviceaccount
kubectl describe sa <sa-name>

# 3. 检查角色绑定
kubectl get rolebindings,clusterrolebindings
kubectl describe rolebinding <binding-name>

解决方案

# 创建适当的角色和绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

镜像拉取权限问题

排查步骤

# 检查镜像拉取密钥
kubectl get secrets
kubectl describe secret <docker-registry-secret>

# 测试镜像拉取
docker pull <image-name>

📊 性能问题排查

资源使用异常

节点资源耗尽

排查命令

# 查看节点资源使用
kubectl top nodes

# 查看Pod资源使用
kubectl top pods --all-namespaces

# 查看资源请求和限制
kubectl describe nodes | grep -A 5 "Allocated resources"
集群性能问题

排查步骤

# 1. 检查API Server响应时间
time kubectl get pods

# 2. 检查etcd状态
kubectl get pods -n kube-system | grep etcd
kubectl logs -n kube-system <etcd-pod>

# 3. 检查控制器状态
kubectl get pods -n kube-system | grep controller

🛠️ 常用故障排查工具

创建调试Pod

# 网络调试Pod
kubectl run -it --rm netshoot --image=nicolaka/netshoot --restart=Never -- /bin/bash

# 基础调试Pod
kubectl run -it --rm busybox --image=busybox --restart=Never -- /bin/sh

# Ubuntu调试Pod
kubectl run -it --rm ubuntu --image=ubuntu --restart=Never -- /bin/bash

端口转发调试

# 转发到Pod
kubectl port-forward pod/<pod-name> 8080:80

# 转发到Service
kubectl port-forward svc/<service-name> 8080:80

# 转发到Deployment
kubectl port-forward deployment/<deployment-name> 8080:80

复制文件调试

# 从Pod复制文件到本地
kubectl cp <pod-name>:/path/to/file ./local-file

# 从本地复制文件到Pod
kubectl cp ./local-file <pod-name>:/path/to/file

📋 故障排查检查清单

Pod问题检查清单

  • Pod状态 (kubectl get pods)
  • Pod事件 (kubectl describe pod)
  • Pod日志 (kubectl logs)
  • 资源限制和请求
  • 镜像拉取配置
  • 健康检查配置
  • 安全上下文配置

网络问题检查清单

  • Service配置和端点
  • DNS解析测试
  • 网络策略规则
  • Ingress配置
  • CNI插件状态
  • 防火墙规则

存储问题检查清单

  • PVC状态和配置
  • PV可用性和匹配
  • StorageClass配置
  • 节点存储空间
  • 挂载权限

权限问题检查清单

  • ServiceAccount配置
  • RBAC角色和绑定
  • 镜像拉取密钥
  • Pod安全策略
  • 网络策略权限

🚨 紧急故障处理

集群节点宕机

# 1. 查看节点状态
kubectl get nodes

# 2. 驱逐节点上的Pod
kubectl drain <node-name> --ignore-daemonsets

# 3. 标记节点为不可调度
kubectl cordon <node-name>

# 4. 节点恢复后解除限制
kubectl uncordon <node-name>

Pod大量异常重启

# 1. 快速查看异常Pod
kubectl get pods --all-namespaces | grep -v Running

# 2. 批量查看Pod日志
for pod in $(kubectl get pods | grep -v Running | awk '{print $1}'); do
  echo "=== $pod ==="
  kubectl logs $pod --tail=10
done

# 3. 临时扩容正常Pod
kubectl scale deployment <deployment-name> --replicas=10

资源耗尽处理

# 1. 立即清理完成的Job
kubectl delete jobs --field-selector=status.successful=1

# 2. 清理失败的Pod
kubectl delete pods --field-selector=status.phase=Failed

# 3. 重启消耗资源高的Pod
kubectl delete pod <high-resource-pod>

📚 日志分析技巧

查看聚合日志

# 查看Deployment所有Pod日志
kubectl logs -l app=<app-name> --tail=100

# 实时跟踪多个Pod日志
kubectl logs -l app=<app-name> -f

# 查看前一次重启的日志
kubectl logs <pod-name> --previous

日志过滤和分析

# 过滤错误日志
kubectl logs <pod-name> | grep -i error

# 统计错误数量
kubectl logs <pod-name> | grep -i error | wc -l

# 查找特定时间段的日志
kubectl logs <pod-name> --since=1h
kubectl logs <pod-name> --since-time=2023-01-01T00:00:00Z

🔧 自动化故障检测脚本

健康检查脚本

#!/bin/bash
# k8s-health-check.sh

echo "=== Cluster Health Check ==="

# 检查节点状态
echo "1. Node Status:"
kubectl get nodes | grep -v Ready | grep -v NAME || echo "All nodes are Ready"

# 检查异常Pod
echo "2. Problem Pods:"
kubectl get pods --all-namespaces | grep -v Running | grep -v Completed || echo "All pods are healthy"

# 检查系统Pod
echo "3. System Pods:"
kubectl get pods -n kube-system | grep -v Running || echo "All system pods are healthy"

# 检查资源使用
echo "4. Resource Usage:"
kubectl top nodes 2>/dev/null || echo "Metrics server not available"

echo "=== Health Check Complete ==="

快速诊断脚本

#!/bin/bash
# k8s-quick-diagnosis.sh

POD_NAME=$1
NAMESPACE=${2:-default}

if [ -z "$POD_NAME" ]; then
    echo "Usage: $0 <pod-name> [namespace]"
    exit 1
fi

echo "=== Quick Diagnosis for Pod: $POD_NAME ==="

echo "1. Pod Status:"
kubectl get pod $POD_NAME -n $NAMESPACE -o wide

echo "2. Pod Events:"
kubectl describe pod $POD_NAME -n $NAMESPACE | grep Events -A 20

echo "3. Pod Logs (last 50 lines):"
kubectl logs $POD_NAME -n $NAMESPACE --tail=50

echo "4. Resource Usage:"
kubectl top pod $POD_NAME -n $NAMESPACE 2>/dev/null || echo "Metrics not available"

echo "=== Diagnosis Complete ==="

记住,故障排查是一个系统性的过程,保持冷静,按步骤进行,大多数问题都能快速定位和解决!🎯

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐