
有些故障表面看只是一个 Pod 起不来,背后却可能牵涉到调度器、容器运行时、网络、存储、DNS,甚至控制面本身。
如果没有一套稳定的排查思路,遇到问题时就很容易陷入“到处看日志、四处改配置、越改越乱”的状态。
其实,大多数 Kubernetes 问题都有比较固定的定位路径:
先看状态,再看 Events;先缩小范围,再查日志;最后再回到配置本身。
本文结合生产环境中的典型案例,整理出 10 个最常见的 Kubernetes 高频故障场景,覆盖:
Pod Pending CrashLoopBackOff Service 无法访问 镜像拉取失败 Node NotReady 存储卷挂载异常 资源限制与驱逐 etcd 故障 DNS 解析异常 权限与安全上下文问题
如果你平时负责 Kubernetes 集群运维,这篇文章建议直接收藏,关键时刻真能省不少时间。
一、先记住一条通用排障思路
很多人排查 Kubernetes 故障时,上来就改 YAML,或者只盯着 Pod 状态不放。
实际上,更高效的顺序应该是:
1)先看对象状态
先搞清楚出问题的是谁:
Pod 异常 Node 异常 PVC 异常 Service 不通 CoreDNS 异常 控制面异常
常用命令:
kubectl get pods -A
kubectl get nodes
kubectl get svc -A
kubectl get pvc -A
2)再看 describe 和 Events
绝大多数常见问题,都会在事件里留下线索。
尤其是调度失败、挂载失败、探针失败、镜像拉取失败,先看 Events 往往比先翻日志更高效。
kubectl describe pod -n <namespace> <pod-name>
kubectl describe node <node-name>
kubectl describe pvc -n <namespace> <pvc-name>
3)再看相关组件日志
如果事件只能告诉你“失败了”,但原因仍然不够清楚,就继续下钻到组件:
kubelet containerd kube-proxy CoreDNS CSI etcd
4)最后回到配置本身
等故障范围缩小以后,再去核对:
资源配置 标签和选择器 镜像地址 探针 安全上下文 存储配置 网络策略
这套方法很朴素,但真正在生产环境里非常有效。
二、问题 1:Pod 一直处于 Pending 状态
问题现象
Pod 创建后长时间停留在 Pending,始终没有进入 Running。
常见场景
新部署的应用起不来 扩容后副本仍调度失败 集群资源紧张时无法重新调度
排查思路
Pending 往往表示 Pod 还没有进入正常运行阶段。
最常见的原因主要有三类:
调度器找不到可用节点 Pod 被污点、亲和性或资源约束挡住了 PVC 未成功绑定,导致 Pod 无法继续推进
排查步骤
先看 Pod 详情
kubectl get pod -n <namespace> <pod-name> -o wide
kubectl describe pod -n <namespace> <pod-name>
重点看 Events。例如:
Warning FailedScheduling default-scheduler 0/5 nodes are available: 1 Insufficient cpu, 3 node(s) had taints that the pod didn't tolerate.
再看节点资源
kubectl top nodes
kubectl describe node <node-name>
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.allocatable.cpu}{" CPU\t"}{.status.allocatable.memory}{"\t"}{.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}'
重点关注 Allocatable,不要只看机器总资源。
检查污点
kubectl get node -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
检查 PVC 状态
kubectl get pvc -n <namespace>
kubectl describe pvc -n <namespace> <pvc-name>
常见根因与修复
1)资源不足
常见报错:
Insufficient cpu Insufficient memory
处理方式:
扩容节点 降低 Pod 的 requests 优化资源占用 清理低优先级工作负载
resources:
requests:
memory:"128Mi"
cpu:"100m"
limits:
memory:"256Mi"
cpu:"200m"
2)节点污点限制
临时处理可以移除污点:
kubectl taint node <node-name> key=value:NoSchedule-
更稳妥的方式是在 Pod 里增加容忍:
tolerations:
-key:"key"
operator:"Exists"
effect:"NoSchedule"
3)PVC 绑定失败
重点检查:
StorageClass 是否存在 PV / PVC 是否匹配 CSI 驱动是否正常 存储后端是否可达
验证方法
kubectl get pod -n <namespace> <pod-name> -w
风险提示
移除节点污点会改变整个节点的调度行为,操作前先确认该节点是否承担专用角色。
三、问题 2:Pod 一直处于 CrashLoopBackOff 状态
问题现象
Pod 能调度到节点,但容器启动后很快退出,并反复重启。
常见场景
新版本上线后立即崩溃 依赖服务未就绪导致应用退出 健康检查过严,容器还没启动完就被杀掉
排查思路
CrashLoopBackOff 的核心不是“起不来”,而是:
容器启动了,但启动后很快崩了。
重点看这 5 个方向:
退出码 崩溃前日志 启动命令 外部依赖 健康检查
排查步骤
看退出信息
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.status.containerStatuses[*]}{"\n"}'
kubectl describe pod -n <namespace> <pod-name> | grep -A 20 "Last State"
看上一次崩溃日志
kubectl logs -n <namespace> <pod-name> --previous
看启动命令和环境变量
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.containers[*].command}'
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.containers[*].args}'
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.containers[*].env}'
看探针配置
kubectl describe pod -n <namespace> <pod-name> | grep -A 5 "Liveness"
kubectl describe pod -n <namespace> <pod-name> | grep -A 5 "Readiness"
kubectl describe pod -n <namespace> <pod-name> | grep -A 5 "Startup"
测试依赖连通性
kubectl exec -it -n <namespace> <pod-name> -- nc -zv <service-name> 3306
kubectl exec -it -n <namespace> <pod-name> -- nslookup <service-name>
常见根因与修复
1)启动命令错误
command: ["/bin/sh", "-c"]
args: ["node app.js && sleep infinity"]
2)依赖服务不可达
数据库、Redis、MQ 等依赖异常时,应用常常直接退出。
3)ConfigMap / Secret 缺失
kubectl get configmap -n <namespace> <configmap-name>
kubectl get secret -n <namespace> <secret-name>
4)目录权限不足
kubectl exec -it -n <namespace> <pod-name> -- ls -la /data
kubectl exec -it -n <namespace> <pod-name> -- id
5)探针过早失败
更合理的做法是给启动较慢的应用配置 startupProbe:
startupProbe:
httpGet:
path:/healthz
port:8080
failureThreshold:30
periodSeconds:10
验证方法
kubectl get pod -n <namespace> <pod-name> -w
kubectl exec -it -n <namespace> <pod-name> -- ps aux
回滚方案
kubectl rollout undo deployment <deployment-name> -n <namespace>
kubectl rollout status deployment <deployment-name> -n <namespace>
四、问题 3:Pod 无法通过 Service 访问
问题现象
Pod 之间通过 Service 名称访问失败,curl 超时,或者 Ingress 流量无法转发到后端。
排查思路
Service 通信链路通常可以拆成三层:
DNS 解析 Service 到后端的转发 后端 Pod 端口监听
排查步骤
确认对象存在
kubectl get pod -n <namespace> -o wide
kubectl get svc -n <namespace> <svc-name>
从其他 Pod 发起访问测试
kubectl exec -it -n <namespace> <source-pod> -- curl -v http://<svc-name>:<port>/
检查 Endpoints 和 EndpointSlice
kubectl get endpoints -n <namespace> <svc-name>
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<svc-name>
kubectl describe svc -n <namespace> <svc-name>
如果 Endpoints 为空,说明 Service 没匹配到后端。
检查 kube-proxy
kubectl get pod -n kube-system -l k8s-app=kube-proxy -o wide
kubectl logs -n kube-system <kube-proxy-pod> --tail=100
测试 ClusterIP
kubectl exec -it -n <namespace> <source-pod> -- curl -v http://<cluster-ip>:<port>/
必要时到节点侧看规则
登录节点执行:
iptables -t nat -L -n | grep <cluster-ip>
ipvsadm -Ln
常见根因与修复
1)selector 不匹配
kubectl get pod -n <namespace> --show-labels
2)Pod 没 Ready
Service 默认不会把未 Ready 的 Pod 加进后端。
3)kube-proxy 异常
kubectl delete pod -n kube-system -l k8s-app=kube-proxy
4)DNS 异常
kubectl exec -it -n <namespace> <pod-name> -- nslookup <svc-name>
kubectl exec -it -n <namespace> <pod-name> -- cat /etc/resolv.conf
5)NetworkPolicy 阻断
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy -n <namespace> <policy-name>
风险提示
重启 kube-proxy 和修改 NetworkPolicy 都可能影响业务流量,生产环境必须分批观察。
五、问题 4:镜像拉取失败
问题现象
Pod 调度成功,但镜像下载失败,状态显示 ImagePullBackOff 或 ErrImagePull。
排查思路
这类问题通常集中在 4 个方向:
镜像地址写错 tag 不存在 认证失败 节点到仓库网络或 TLS 异常
排查步骤
看事件
kubectl describe pod -n <namespace> <pod-name> | grep -A 15 "Events"
节点侧手动拉取测试
crictl pull <registry>/<image>:<tag>
ctr -n k8s.io images pull <registry>/<image>:<tag>
检查镜像仓库认证
kubectl get secret -n <namespace>
kubectl describe secret -n <namespace> <registry-secret-name>
检查仓库网络与证书
curl -I https://<registry>/v2/
常见根因与修复
1)镜像地址或 tag 错误
最常见,也最容易忽略。
2)认证凭据错误
kubectl create secret docker-registry <secret-name> \
--docker-server=<registry> \
--docker-username=<user> \
--docker-password=<password> \
--docker-email=<email> \
-n <namespace>
Pod 里引用:
spec:
imagePullSecrets:
-name:<secret-name>
3)TLS 证书不被信任
私有仓库常见问题是内部 CA 没有安装到节点信任链里。
4)节点网络不通
例如 DNS 不通、防火墙阻断、代理配置缺失。
验证方法
kubectl delete pod -n <namespace> <pod-name>
kubectl get events -n <namespace> --sort-by='.lastTimestamp' | tail -20
风险提示
删除 Pod 前先确认副本数是否足够,避免直接影响线上流量。
六、问题 5:Node 变成 NotReady
问题现象
节点状态显示 NotReady,新 Pod 无法继续调度到该节点。
排查思路
优先排查这 4 个方向:
kubelet 是否正常 containerd 是否正常 系统资源是否耗尽 节点与 API Server 是否连通
排查步骤
看节点状态
kubectl get nodes
kubectl describe node <node-name>
kubectl get node <node-name> -o jsonpath='{.status.conditions[*]}'
登录节点检查 kubelet
systemctl status kubelet
journalctl -u kubelet -n 100 --no-pager
检查系统资源
free -h
df -h
top -bn1 | head -20
检查 containerd
systemctl status containerd
检查与 API Server 连通性
ping <api-server-ip>
curl -k https://<api-server-ip>:6443/healthz
检查 kubelet 证书
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -noout -dates
常见根因与修复
1)kubelet 异常
systemctl restart kubelet
2)磁盘或内存耗尽
journalctl --vacuum-size=500M
crictl image prune
3)containerd 异常
systemctl restart containerd
systemctl restart kubelet
4)节点到控制面网络不通
重点查路由、防火墙、安全组和 LB 配置。
隔离与恢复
如果一时修不好,先隔离节点:
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
恢复后再:
kubectl uncordon <node-name>
七、问题 6:存储卷挂载异常
问题现象
PVC 长期 Pending Pod 启动后无法读写数据目录 有状态服务无法正常挂载卷
排查思路
重点检查四层链路:
StorageClass PVC PV CSI 驱动 / 存储后端
排查步骤
看 PVC
kubectl get pvc -n <namespace>
kubectl describe pvc -n <namespace> <pvc-name>
看 PV
kubectl get pv
kubectl describe pv <pv-name>
看 StorageClass
kubectl get storageclass
kubectl describe storageclass <sc-name>
看 CSI
kubectl get pod -n kube-system | grep csi
kubectl logs -n kube-system <csi-driver-pod> --tail=100
kubectl get csidrivers
到节点检查挂载
登录节点执行:
mount | grep <pv-name>
df -h | grep <mount-path>
常见根因与修复
1)StorageClass 不存在或 provisioner 错误
2)PVC 与 PV 不匹配
3)CSI 驱动异常
kubectl delete pod -n kube-system <csi-driver-pod>
4)节点无法访问存储后端
比如 NFS:
showmount -e <nfs-server>
5)目录权限不匹配
securityContext:
fsGroup:2000
runAsUser:1000
验证方法
kubectl exec -it -n <namespace> <pod-name> -- sh -c "echo test > /data/test.txt && cat /data/test.txt"
风险提示
删除 PVC 可能导致数据永久丢失,生产环境必须先确认备份。
八、问题 7:资源限制或节点压力导致 Pod 异常
问题现象
Pod 被杀掉、被驱逐,或者根本创建失败。
常见表现包括:
OOMKilled Evicted ResourceQuota 超限
排查思路
这类问题要分开看:
OOMKilled:通常是容器超过内存 limit Evicted:通常是节点压力触发驱逐 创建失败:通常是 quota / limitrange 限制
排查步骤
kubectl get pod -n <namespace>
kubectl describe pod -n <namespace> <pod-name>
kubectl get resourcequota -n <namespace>
kubectl describe resourcequota -n <namespace>
kubectl get limitrange -n <namespace>
kubectl describe limitrange -n <namespace>
kubectl top pod -n <namespace>
kubectl top nodes
kubectl get events -n <namespace> --sort-by='.lastTimestamp' | tail -30
常见根因与修复
1)内存 limit 太小
resources:
requests:
memory:"512Mi"
limits:
memory:"1Gi"
2)节点资源压力
如果是 Evicted,不要只盯 Pod,更要看节点层面的容量。
3)命名空间配额耗尽
可以适当调整:
apiVersion:v1
kind:ResourceQuota
metadata:
name:increase-quota
spec:
hard:
requests.cpu:"20"
requests.memory:40Gi
limits.cpu:"40"
limits.memory:80Gi
4)LimitRange 默认限制不合理
很多应用一上线就 OOM,问题根本不在代码,而在命名空间默认 limit 太小。
九、问题 8:etcd 集群故障
问题现象
kubectl 请求超时 API Server 不稳定 控制面整体异常
排查思路
etcd 出问题时,表面看起来常常像“整个集群都怪怪的”。
这时优先确认:
etcd 进程是否健康 endpoint 是否健康 member 是否完整 磁盘是否满了 证书是否过期
排查步骤
看 etcd 状态
如果是静态 Pod:
kubectl -n kube-system get pod -l component=etcd -o wide
kubectl -n kube-system logs <etcd-pod> --tail=100
如果是 systemd:
systemctl status etcd
journalctl -u etcd -n 100 --no-pager
看健康状态
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 --cluster
看成员状态
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 \
member list -w table
看磁盘和证书
df -h /var/lib/etcd
du -sh /var/lib/etcd/*
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates
kubeadm certs check-expiration
常见根因与修复
1)磁盘空间不足
可以先做 defrag:
ETCDCTL_API=3 etcdctl defrag --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
2)成员异常或网络分区
涉及 member remove 时一定要慎重。
3)证书过期
先用:
kubeadm certs check-expiration
确认是否真是证书问题。
风险提示
etcd 是集群最核心的组件之一。涉及成员变更、证书续期、快照恢复前,务必先做备份。
备份示例:
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%F-%H%M).db
十、问题 9:DNS 解析异常
问题现象
Pod 无法通过服务名访问目标服务,nslookup 超时或返回异常结果。
排查思路
DNS 问题优先看三件事:
CoreDNS 是否健康 Pod 的 resolv.conf 是否正确 53 端口流量是否被拦截
排查步骤
看 CoreDNS 状态
kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
kubectl logs -n kube-system <coredns-pod> --tail=100
起一个测试 Pod 做解析验证
kubectl run -it --rm debug --image=busybox -n default --restart=Never -- nslookup kubernetes.default
kubectl run -it --rm debug --image=busybox -n default --restart=Never -- nslookup <svc-name>.<namespace>.svc.cluster.local
看业务 Pod 的 resolv.conf
kubectl exec -it -n <namespace> <pod-name> -- cat /etc/resolv.conf
看 CoreDNS 配置
kubectl get configmap -n kube-system coredns -o yaml
看网络策略
kubectl get networkpolicy -A
常见根因与修复
1)CoreDNS Pod 异常
kubectl rollout restart deployment coredns -n kube-system
2)上游 DNS 配置错误
3)Headless Service 结果与预期不一致
clusterIP: None 返回的是 Pod IP 列表,不是单个 VIP。
4)NetworkPolicy 阻断 53 端口
这是生产环境里很常见的误伤点。
十一、问题 10:安全上下文导致权限不足
问题现象
应用报 Permission denied,常见表现包括:
无法写目录 无法绑定低位端口 某些系统调用被拒绝
排查思路
在 Kubernetes 1.28 中,重点关注:
securityContext Pod Security Admission SELinux / AppArmor / seccomp 宿主机目录权限
排查步骤
kubectl get pod -n <namespace> <pod-name> -o yaml | grep -A 30 securityContext
kubectl describe pod -n <namespace> <pod-name>
kubectl get ns <namespace> --show-labels
kubectl exec -it -n <namespace> <pod-name> -- id
kubectl exec -it -n <namespace> <pod-name> -- ls -la /data
节点侧检查:
getenforce
apparmor_status
seccomp 检查:
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.securityContext.seccompProfile}'
kubectl get pod -n <namespace> <pod-name> -o jsonpath='{.spec.containers[*].securityContext.seccompProfile}'
常见根因与修复
1)非 root 用户无法写目录
推荐修目录权限,而不是直接切 root:
securityContext:
runAsUser:1000
fsGroup:1000
initContainers:
-name:fix-permission
image:busybox
command: ["sh", "-c", "chown -R 1000:1000 /data"]
2)缺少能力绑定低位端口
securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
3)只读根文件系统与应用行为冲突
4)命名空间安全策略限制
风险提示
不要轻易把容器改成 privileged: true 或 runAsUser: 0,生产环境应尽量遵循最小权限原则。
十二、10 大高频问题排查矩阵
kubectl describe pod | ||
kubectl logs --previous | ||
kubectl get endpoints | ||
kubectl describe pod | ||
systemctl status kubelet | ||
kubectl describe pvc | ||
kubectl describe pod | ||
etcdctl endpoint health | ||
nslookup | ||
kubectl describe podsecurityContext |
十三、建议长期保留的一份巡检清单
# 节点健康
kubectl get nodes -o wide
kubectl top nodes
# 异常 Pod
kubectl get pods -A | egrep -v 'Running|Completed'
kubectl get pods -A | grep -i Evicted
# 资源配额
kubectl get resourcequota -A
kubectl get limitrange -A
# 存储状态
kubectl get pvc -A
kubectl get pv
# 核心组件
kubectl get pods -n kube-system
# 最近事件
kubectl get events -A --sort-by='.lastTimestamp' | tail -50
如果条件允许,建议同时对以下指标配置监控告警:
Node NotReady Pod 重启次数异常 Pending Pod 数量 PVC Pending 数量 CoreDNS 错误率 etcd 延迟与空间使用率 镜像拉取失败次数
十四、写在最后
Kubernetes 的问题之所以让人觉得“复杂”,很多时候并不是因为它真的无从下手,而是因为故障表象和真实根因之间隔了几层。
一个 Pod 起不来,可能是资源问题;
一个 Service 不通,可能是 DNS、selector、探针,甚至网络策略;
一次 API 超时,背后也可能不是 apiserver 本身,而是 etcd 已经开始出问题。
所以,排障最怕的不是问题复杂,而是没顺序。
只要记住这条主线:
先看状态,再看 Events;先缩小范围,再查日志;最后回到配置。
大部分生产环境里的常见故障,基本都能更快收敛。
如果你也在维护 Kubernetes 集群,建议把这篇文章先收藏起来。
很多问题平时看着不常见,但真到线上出故障的时候,能不能第一时间找到排查路径,差别会非常大。
你在生产环境里踩过最离谱的 Kubernetes 坑是什么?欢迎留言聊聊。
(版权归原作者所有,侵删)
免责声明:本文内容来源于网络,所载内容仅供参考。转载仅为学习和交流之目的,如无意中侵犯您的合法权益,请及时联系Docker中文社区!

温馨提示:文章内容系作者个人观点,不代表Docker中文对观点赞同或支持。
版权声明:本文为转载文章,来源于 互联网 ,版权归原作者所有,欢迎分享本文,转载请保留出处!

发表评论