摘要
整理 K8s 生产环境十类高频故障:Pending、CrashLoopBackOff、ImagePullBackOff、OOMKilled、Service 不通、Ingress 报错、节点 NotReady、磁盘压力驱逐、滚动发布抖动、DNS 解析失败。每类给出排查命令、常见根因与处理方式,附 kubectl 速查表。
排查前的三个基本功
kubectl get pod-owide# 看状态与所在节点kubectl describe pod<pod># 看 Events(80% 的答案在这)kubectl logs<pod>[-p][-c 容器名]# 看当前/上次日志记住一个原则:先看 describe 的 Events,再看日志——调度失败、拉镜像失败、探针失败都写在 Events 里。
1. Pod 一直 Pending
排查
kubectl describe pod<pod>|grep-A10Events常见根因
| Events 关键字 | 含义 |
|---|---|
Insufficient cpu/memory | 节点资源不足 → 看 requests 是否过大 |
node(s) had taint | 节点有污点,Pod 没配 tolerations |
didn't match node selector/affinity | 亲和性/选择器写错 |
volume node affinity conflict | PV 与 Pod 不在同可用区 |
no nodes available | 节点 NotReady 或全部被占满 |
2. CrashLoopBackOff(反复重启)
排查顺序
kubectl logs<pod>-p# 1. 上次容器日志(关键)kubectl describe pod<pod># 2. 看退出码与 OOMKilled退出码速查
| 退出码 | 含义 |
|---|---|
| 1 | 应用自身报错(配置、依赖、端口占用) |
| 137 | 被 SIGKILL:OOM 或 liveness 探针超时被杀 |
| 143 | 收到 SIGTERM 正常退出(常是优雅停机逻辑有问题) |
容易忽略的点:livenessProbe配置不当(初始延迟太短、路径写错)会导致应用还没起来就被反复杀死——这类问题日志里看不出报错,只能从 Events 的Killing container发现。
3. ImagePullBackOff / ErrImagePull
kubectl describe pod<pod>|grep-A5Events常见原因:
- 镜像名/标签写错(最常见)
- 私有仓库没配
imagePullSecrets - 仓库凭证过期
- 节点到仓库网络不通(内网 registry、镜像加速器失效)
4. Pod 被 OOMKilled
kubectl describe pod<pod>|grep-ioom kubectltoppod<pod># 看实际内存判断是"泄漏"还是"峰值超限":
- 持续增长→ 应用内存泄漏(Java 看堆 + 堆外 DirectByteBuffer)
- 平时正常、高峰被杀→
limits太小或流量突增
处理:先临时调大limits止血,再定位根因;requests也要设合理,否则调度会超卖。
5. Service 访问不通
三步定位
# 1. Endpoints 是否为空(最常见的坑)kubectl get endpoints<svc># 2. 从 Pod 内部测试kubectlexec-it<pod>--curl<svc-name>:<port># 3. 看 Service 与 Pod 的标签是否匹配kubectl get svc<svc>-oyaml|grepselector kubectl get pod --show-labelsEndpoints 为空= selector 与 Pod 标签不匹配,或 Pod 未 Ready(readiness 没过也不会进 Endpoints)。
6. Ingress 返回 404 / 502
| 现象 | 排查方向 |
|---|---|
| 404 | host / path 规则不匹配;IngressClass 选错 |
| 502 | 后端 Service/Endpoints 有问题(回到第 5 条) |
| 503 | 后端无可用 Pod |
kubectl get ingress kubectl describe ingress<name># 看规则与后端kubectl logs-ningress-nginx<ingress-pod># 看网关侧错误7. 节点 NotReady
kubectl describenode<node>|grep-A10Conditions常见原因:
- kubelet 挂了 →
systemctl status kubelet - 容器运行时异常(containerd/docker)
- 磁盘压力 / 内存压力 → 节点进入 DiskPressure
- 网络插件异常(Calico/Flannel Pod 挂了)
注意:节点 NotReady 超过pod-eviction-timeout后,上面的 Pod 会被驱逐,可能引发雪崩。
8. 磁盘压力导致 Pod 被驱逐
kubectl describenode<node>|grep-ipressuredf-h/var/lib/kubelet /var/lib/containerdK8s 默认驱逐阈值:节点可用磁盘低于 10~15% 就开始驱逐。
元凶通常是:容器日志(/var/log/pods)、镜像层堆积、core dump。
处理:
- 清理:
crictl rmi --prune清理无用镜像 - 根治:限制容器日志大小(
log-opts max-size)、日志采集后轮转 - 把 kubelet 与镜像目录单独挂盘
9. 滚动发布期间流量抖动
四个关键配置
spec:strategy:rollingUpdate:maxUnavailable:0# 先起新的再停旧的maxSurge:1template:spec:terminationGracePeriodSeconds:30containers:-name:appreadinessProbe:# 真正就绪才接流量httpGet:{path:/healthz,port:8080}initialDelaySeconds:5lifecycle:preStop:exec:{command:["sh","-c","sleep 5"]}# 先摘流量再退出再加PDB保护最小可用副本数:
apiVersion:policy/v1kind:PodDisruptionBudgetspec:minAvailable:2selector:matchLabels:{app:myapp}10. Pod 内 DNS 解析失败
kubectlexec-it<pod>--cat/etc/resolv.conf kubectlexec-it<pod>--nslookupkubernetes.default kubectl get pod-nkube-system|grepcoredns kubectl logs-nkube-system<coredns-pod>常见原因:
- CoreDNS Pod 异常或副本不足
ndots:5导致大量无效查询(短域名拼接)- 节点 conntrack 表满(高并发下 DNS 丢包)
- 网络插件策略拦截
kubectl 速查表
# 状态与事件kubectl get pod-owide kubectl describe pod<pod>kubectl get events --sort-by=.lastTimestamp|tail-20# 日志kubectl logs<pod>-p--tail=200kubectl logs<pod>-c<container>-f# 资源kubectltoppod / kubectltopnode# 网络kubectl get svc,ep,ingress kubectlexec-it<pod>--sh# 节点kubectl describenode<node>kubectl getnode-owide# 排障临时容器(1.23+)kubectl debug-it<pod>--image=busybox--target=<container>排查心法
- 先看 Events 再看日志——调度/镜像/探针问题日志里没有
- 对比"变更前后"——刚发过版?先回滚再说
- 保留现场——重启前先
describe、logs -p、必要时kubectl debug - 别只修一台——集群问题往往成片出现,先看是不是节点级/网络级
这些排查链路我整理成了一个小程序
上面这些场景的题目(以及更多)我整理成了一个小程序「系统运维面试题学习随手记刷」,295 道题,按 8 个模块分类:
中间件 · DevOps · SRE · 云原生 · Linux · AIOps · Shell · 综合开放题
- 题库全部免费,不用登录,每题都有参考答案,就是本文这种"排查步骤 + 回答结构"的形式
- 把简历和 JD 粘进去,会出 20 道针对你经历的押题,并给一份适配度分析
- 还有录像练习:摄像头答题 → 回放 → 按要点自评,练表达(本地处理,不上传)
微信搜索小程序「系统运维面试题学习随手记刷」
你遇到过最离谱的线上故障是什么?评论区聊聊。