K8s 学习:常用命令 100 条(二)- 生产环境故障排查

K8s 学习:常用命令 100 条(二)- 生产环境故障排查

故障排查

系列文章: K8s 命令实战指南
适用人群: 运维工程师、SRE 工程师、DevOps 工程师
阅读时间: 20 分钟


前言

在生产环境中,快速定位和解决问题是运维的核心能力。本文整理了最常见的 K8s 故障场景及排查命令,帮助你快速恢复服务。


一、Pod 故障排查

1.1 Pod 状态异常

# 查看所有异常 Pod
kubectl get pods --all-namespaces --field-selector=status.phase!=Running

# 查看特定状态的 Pod
kubectl get pods --field-selector=status.phase=Pending
kubectl get pods --field-selector=status.phase=Failed
kubectl get pods --field-selector=status.phase=Unknown

# 查看 Pod 状态详情
kubectl get pods -o custom-columns='NAME:metadata.name,STATUS:status.phase,RESTARTS:status.containerStatuses[0].restartCount,NODE:spec.nodeName'

# 查看 Pod 所有容器的状态
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].state}'

使用场景:

  • Pod 一直处于 Pending 状态
  • Pod 启动后立即退出
  • 批量检查异常 Pod
  • 监控 Pod 健康状态

1.2 CrashLoopBackOff

# 查看 Pod 事件
kubectl describe pod <pod-name> | grep -A 20 Events

# 查看容器日志
kubectl logs <pod-name> --previous

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

# 查看容器终止原因
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'

# 查看容器重启次数
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].restartCount}'

# 查看 Pod 的资源使用
kubectl top pod <pod-name>

使用场景:

  • 应用启动失败
  • 配置文件错误
  • 资源不足(OOM)
  • 健康检查失败

常见退出码:

  • 0:正常退出
  • 1:应用错误
  • 137:OOMKilled(内存不足)
  • 139:Segmentation Fault
  • 143:被 SIGTERM 终止

1.3 ImagePullBackOff / ErrImagePull

# 查看镜像拉取错误
kubectl describe pod <pod-name> | grep -A 10 "Events:"

# 查看 Pod 使用的镜像
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}'

# 查看镜像拉取策略
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].imagePullPolicy}'

# 查看 Secret(镜像拉取密钥)
kubectl get pod <pod-name> -o jsonpath='{.spec.imagePullSecrets}'

# 检查 Secret 是否存在
kubectl get secrets | grep <secret-name>

# 查看 Secret 内容
kubectl describe secret <secret-name>

# 测试镜像拉取(手动)
docker pull <image-name>
crictl pull <image-name>

使用场景:

  • 镜像不存在或标签错误
  • 镜像仓库认证失败
  • 网络不通或镜像仓库不可达
  • 镜像拉取超时

1.4 Pending 状态

# 查看 Pending 原因
kubectl describe pod <pod-name> | grep -A 20 Events

# 查看节点资源
kubectl describe nodes | grep -A 5 "Allocated resources"

# 查看节点可调度性
kubectl get nodes -o custom-columns='NAME:metadata.name,READY:status.conditions[?(@.type=="Ready")].status,SCHEDULABLE:spec.unschedulable'

# 查看资源请求
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].resources.requests}'

# 查看 PV/PVC 状态
kubectl get pvc | grep <pod-namespace>

# 查看节点标签(用于节点选择)
kubectl get nodes --show-labels

# 查看 Pod 的节点选择器
kubectl get pod <pod-name> -o jsonpath='{.spec.nodeSelector}'

# 查看 Pod 的亲和性规则
kubectl get pod <pod-name> -o jsonpath='{.spec.affinity}'

使用场景:

  • 资源不足(CPU/内存)
  • 节点不可调度
  • PVC 未绑定
  • 节点选择器不匹配
  • 污点和容忍度问题

二、节点故障排查

2.1 NotReady 状态

# 查看节点状态
kubectl get nodes

# 查看节点详情
kubectl describe node <node-name>

# 查看节点条件
kubectl get node <node-name> -o jsonpath='{.status.conditions}'

# 查看 kubelet 状态(SSH 到节点)
systemctl status kubelet

# 查看 kubelet 日志
journalctl -u kubelet -f

# 查看容器运行时状态
systemctl status docker
systemctl status containerd

# 查看容器运行时日志
journalctl -u docker -f
journalctl -u containerd -f

使用场景:

  • kubelet 服务异常
  • 容器运行时异常
  • 网络不通
  • 磁盘满

2.2 节点资源不足

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

# 查看节点资源分配
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

# 查看节点上的 Pod
kubectl get pods --all-namespaces --field-selector spec.nodeName=<node-name>

# 查看节点上的 Pod 资源使用
kubectl top pod --all-namespaces --field-selector spec.nodeName=<node-name>

# 查看磁盘使用(SSH 到节点)
df -h

# 查看内存使用
free -h

# 查看进程资源使用
top
htop

# 清理未使用的容器和镜像
docker system prune -a
crictl rmi --prune

使用场景:

  • CPU 使用率过高
  • 内存不足
  • 磁盘空间不足
  • inode 耗尽

2.3 节点磁盘满

# 查看磁盘使用(SSH 到节点)
df -h

# 查看大文件
du -sh /* | sort -h | tail -10

# 查看 Docker 目录大小
du -sh /var/lib/docker

# 查看容器日志大小
du -sh /var/lib/docker/containers/*/*-json.log

# 查看日志文件
ls -lh /var/log/

# 清理 Docker 资源
docker system prune -a --volumes

# 清理容器日志(谨慎!)
truncate -s 0 /var/lib/docker/containers/*/*-json.log

# 清理系统日志
journalctl --vacuum-time=3d

# 查看被删除但仍占用的文件
lsof | grep deleted

使用场景:

  • 磁盘使用率 > 90%
  • 容器日志过大
  • 镜像层过多
  • 临时文件未清理

三、网络故障排查

3.1 DNS 解析失败

# 测试 DNS 解析
kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup kubernetes

# 测试外部 DNS
kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup www.google.com

# 查看 CoreDNS Pod 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns

# 查看 CoreDNS ConfigMap
kubectl get configmap coredns -n kube-system -o yaml

# 查看 Pod 的 DNS 配置
kubectl exec <pod-name> -- cat /etc/resolv.conf

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

# 查看 Service ClusterIP
kubectl get svc <service-name> -o jsonpath='{.spec.clusterIP}'

使用场景:

  • Service 域名解析失败
  • 外部域名解析失败
  • CoreDNS 配置错误
  • 跨命名空间访问失败

3.2 Service 无法访问

# 查看 Service 详情
kubectl describe service <service-name>

# 查看 Endpoints
kubectl get endpoints <service-name>

# 查看 Service 选择器
kubectl get svc <service-name> -o jsonpath='{.spec.selector}'

# 查看匹配的 Pod
kubectl get pods -l <selector-key>=<selector-value>

# 查看 Pod 标签
kubectl get pods --show-labels

# 查看 Service ClusterIP
kubectl get svc <service-name> -o jsonpath='{.spec.clusterIP}'

# 查看 Service 端口
kubectl get svc <service-name> -o jsonpath='{.spec.ports}'

# 测试 Service 连通性
kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- wget -qO- <service-name>:<port>

# 端口转发测试
kubectl port-forward service/<service-name> <local-port>:<service-port>

使用场景:

  • Service 没有后端 Pod
  • Pod 标签不匹配
  • 端口配置错误
  • 网络策略阻止

3.3 Pod 之间网络不通

# 查看 Pod IP
kubectl get pod <pod-name> -o jsonpath='{.status.podIP}'

# 测试 Pod 之间连通性
kubectl exec <pod1-name> -- ping <pod2-ip>

# 查看 Pod 网络
kubectl exec <pod-name> -- ip addr

# 查看路由表
kubectl exec <pod-name> -- route -n

# 查看 iptables(SSH 到节点)
iptables -L -n -v

# 查看网络策略
kubectl get networkpolicy --all-namespaces

# 查看网络策略详情
kubectl describe networkpolicy <policy-name>

# 查看 CNI 配置(SSH 到节点)
ls /etc/cni/net.d/
cat /etc/cni/net.d/*.conf

# 查看 CNI 插件日志(SSH 到节点)
journalctl -u kubelet | grep cni

使用场景:

  • 跨节点 Pod 不通
  • 同节点 Pod 不通
  • 网络策略阻止
  • CNI 插件问题

四、存储故障排查

4.1 PVC Pending

# 查看 PVC 状态
kubectl get pvc

# 查看 PVC 详情
kubectl describe pvc <pvc-name>

# 查看 PV 状态
kubectl get pv

# 查看 StorageClass
kubectl get storageclass

# 查看 Provisioner 日志
kubectl logs -n kube-system <provisioner-pod>

# 查看 PVC 事件
kubectl describe pvc <pvc-name> | grep -A 10 Events

# 查看可用 PV
kubectl get pv | grep Available

# 查看 PV 容量
kubectl get pv -o custom-columns='NAME:metadata.name,CAPACITY:spec.capacity.storage,STATUS:status.phase'

使用场景:

  • 没有可用的 PV
  • StorageClass 不存在
  • Provisioner 异常
  • 存储配额限制

4.2 Pod 挂载失败

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

# 查看 Pod 挂载点
kubectl get pod <pod-name> -o jsonpath='{.spec.volumes}'

# 查看 PVC 绑定状态
kubectl get pvc <pvc-name> -o jsonpath='{.status.phase}'

# 进入 Pod 查看挂载
kubectl exec -it <pod-name> -- df -h

# 查看挂载点内容
kubectl exec <pod-name> -- ls -lh /<mount-path>

# 查看 PV 挂载信息(SSH 到节点)
mount | grep <pv-name>

# 查看磁盘挂载(SSH 到节点)
lsblk
df -h

使用场景:

  • PVC 未绑定
  • PV 挂载失败
  • 存储类型不支持
  • 权限问题

五、性能故障排查

5.1 CPU 使用率高

# 查看节点 CPU 使用
kubectl top node

# 查看 Pod CPU 使用
kubectl top pod --all-namespaces

# 按使用量排序
kubectl top pod --all-namespaces --sort-by=cpu

# 查看资源请求和限制
kubectl get pod <pod-name> -o custom-columns='NAME:metadata.name,CPU_REQ:spec.containers[*].resources.requests.cpu,CPU_LIM:spec.containers[*].resources.limits.cpu'

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

# 查看进程 CPU 使用
kubectl exec <pod-name> -- ps aux --sort=-pcpu | head

# 生成 CPU Profile(需要应用支持)
kubectl exec <pod-name> -- curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof

使用场景:

  • 应用 CPU 占用过高
  • 资源限制不合理
  • 代码性能问题
  • 死循环或阻塞

5.2 内存泄漏

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

# 查看内存使用趋势(持续监控)
watch kubectl top pod <pod-name>

# 查看内存请求和限制
kubectl get pod <pod-name> -o custom-columns='NAME:metadata.name,MEM_REQ:spec.containers[*].resources.requests.memory,MEM_LIM:spec.containers[*].resources.limits.memory'

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

# 查看进程内存使用
kubectl exec <pod-name> -- ps aux --sort=-pmem | head

# 查看容器内存限制
kubectl exec <pod-name> -- cat /sys/fs/cgroup/memory/memory.limit_in_bytes

# 生成 Heap Dump(需要应用支持)
kubectl exec <pod-name> -- curl http://localhost:6060/debug/pprof/heap > heap.prof

# 查看 OOM 事件
kubectl get events --field-selector reason=OOMKilled

使用场景:

  • 内存持续增长
  • 频繁 OOMKilled
  • 内存泄漏
  • 缓存过大

六、证书故障排查

6.1 证书过期

# 查看证书有效期(kubeadm)
kubeadm certs check-expiration

# 查看 API Server 证书
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A 2 Validity

# 查看 kubelet 证书
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text -noout | grep -A 2 Validity

# 查看证书过期时间
kubectl get csr

# 续期证书(kubeadm)
kubeadm certs renew all

# 重启服务使证书生效
kubectl rollout restart deployment -n kube-system
systemctl restart kubelet

使用场景:

  • API Server 证书过期
  • kubelet 证书过期
  • etcd 证书过期
  • 证书轮换失败

6.2 证书认证失败

# 查看 kubeconfig
kubectl config view

# 查看 client 证书
openssl x509 -in ~/.kube/client-certificate -text -noout

# 测试 API 连接
kubectl cluster-info

# 查看认证日志(API Server)
journalctl -u kube-apiserver -f | grep auth

# 查看证书链
openssl s_client -connect <api-server-ip>:6443 -showcerts

# 验证证书和私钥匹配
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5

使用场景:

  • kubeconfig 配置错误
  • 证书路径错误
  • 证书和私钥不匹配
  • CA 证书错误

七、应用故障排查

7.1 健康检查失败

# 查看 Pod 事件
kubectl describe pod <pod-name> | grep -A 10 Events

# 查看健康检查配置
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].livenessProbe}'

# 查看就绪检查配置
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].readinessProbe}'

# 手动测试健康检查端点
kubectl exec <pod-name> -- curl -v http://localhost:<port>/health

# 查看容器日志
kubectl logs <pod-name> --tail=100

# 查看容器重启原因
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState}'

使用场景:

  • Liveness Probe 失败
  • Readiness Probe 失败
  • 健康检查端点错误
  • 超时时间太短

7.2 配置错误

# 查看 ConfigMap
kubectl get configmap <configmap-name> -o yaml

# 查看 Secret
kubectl get secret <secret-name> -o yaml

# 查看 Pod 挂载的配置
kubectl exec <pod-name> -- ls -lh /etc/config/

# 查看环境变量
kubectl exec <pod-name> -- env | grep <config-key>

# 查看 Pod 的环境变量配置
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].env}'

# 解码 Secret
kubectl get secret <secret-name> -o jsonpath='{.data.<key>}' | base64 --decode

# 更新 ConfigMap
kubectl create configmap <configmap-name> --from-file=<file> --dry-run=client -o yaml | kubectl apply -f -

使用场景:

  • ConfigMap 不存在
  • Secret 解码错误
  • 环境变量未注入
  • 配置文件路径错误

八、日志故障排查

8.1 日志收集问题

# 查看 Pod 日志
kubectl logs <pod-name> --tail=100

# 查看多个容器的日志
kubectl logs <pod-name> --all-containers

# 查看指定容器的日志
kubectl logs <pod-name> -c <container-name>

# 查看前一个容器的日志
kubectl logs <pod-name> --previous

# 实时查看日志
kubectl logs -f <pod-name>

# 查看日志大小限制
kubectl describe pod <pod-name> | grep -i log

# 查看 kubelet 日志配置(SSH 到节点)
cat /var/lib/kubelet/config.yaml | grep -A 5 containerLog

# 查看容器日志文件(SSH 到节点)
ls -lh /var/lib/docker/containers/*/*-json.log

使用场景:

  • 日志输出过多
  • 日志文件过大
  • 日志格式错误
  • 日志采集失败

九、总结

9.1 故障排查流程

1. 查看状态
   ↓
2. 查看事件
   ↓
3. 查看日志
   ↓
4. 定位问题
   ↓
5. 解决问题

9.2 常用排查命令速查

场景 命令
Pod 异常 kubectl describe pod <pod-name>
容器日志 kubectl logs <pod-name> --previous
节点异常 kubectl describe node <node-name>
DNS 问题 nslookup kubernetes
网络问题 kubectl exec <pod> -- ping <ip>
资源不足 kubectl top node/pod
证书问题 kubeadm certs check-expiration
存储问题 kubectl describe pvc <pvc-name>

9.3 预防措施

  1. 监控告警

    • 设置资源使用告警
    • 设置 Pod 重启告警
    • 设置节点状态告警
  2. 日志收集

    • 统一日志格式
    • 集中日志存储
    • 日志分析和搜索
  3. 定期检查

    • 证书有效期
    • 资源使用率
    • 磁盘空间
  4. 文档记录

    • 记录常见问题
    • 记录解决方案
    • 记录配置变更

参考资料


作者: PaPaBot
发布时间: 2026-03-07
标签: #Kubernetes #K8s #DevOps #运维 #故障排查


本文属于《K8s 命令实战指南》系列文章第二篇

Views: 0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Index