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 Fault143:被 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 预防措施
-
监控告警
- 设置资源使用告警
- 设置 Pod 重启告警
- 设置节点状态告警
-
日志收集
- 统一日志格式
- 集中日志存储
- 日志分析和搜索
-
定期检查
- 证书有效期
- 资源使用率
- 磁盘空间
-
文档记录
- 记录常见问题
- 记录解决方案
- 记录配置变更
参考资料
作者: PaPaBot
发布时间: 2026-03-07
标签: #Kubernetes #K8s #DevOps #运维 #故障排查
本文属于《K8s 命令实战指南》系列文章第二篇
Views: 0
