知序
返回
保存草稿
发布
H1
H2
H3
1
2
3
Excalidraw 图
AI 写作
AI 优化
目录
输入内容后显示目录
Markdown
# 05 - 排障速查:状态、命令、异常对照 > 本篇目标:把前四篇用到的排障动作系统化。建议把它当手册用 —— 出问题时直接跳到对应小节,不用从头读。 > 前置:01~04 篇(熟悉 Deployment / Service / Ingress 的对象关系)。 --- ## 1. 先记住这一条链路 90% 的问题能靠这条链路定位,**顺序不要跳**:  *图:K8s 排障决策树:从内到外逐层排除* ```text kubectl get pods → 看状态是不是 Running │ 不是 Running v kubectl describe pod → 看 Events 里的原因 │ 是 Running 但访问不通 v kubectl get endpoints → 看 Service 后面到底有没有 Pod │ 空 → selector 写错了 / 探针没过 v kubectl port-forward → 集群内能不能通 │ 能通 → 问题在 Ingress / LB v kubectl describe ingress → 看路由和后端是否正确 ``` **为什么是这个顺序**:从内到外逐层排除。先确认"容器活着",再确认"能被 Service 找到",最后才怀疑"入口配置"。反过来查会浪费大量时间 —— 很多人在 Ingress 上折腾半天,其实是 Pod 的 selector 写错了。 --- ## 2. kubectl 常用命令速查 ```bash # ── 查看 ────────────────────────────────────────────── kubectl get pods -o wide # 带 IP 和节点 kubectl get all # 一次看大部分资源 kubectl get deploy,rs,pods # 三层关系一起看 kubectl get pods --watch # 实时观察变化 kubectl get pod <pod> -o yaml # 导出完整定义(含默认填充的字段) kubectl get events --sort-by=.metadata.creationTimestamp | tail -20 kubectl get pods --field-selector status.phase!=Running # 快速筛出异常 Pod # ── 排障三件套 ──────────────────────────────────────── kubectl describe pod <pod> # 看 Events!第一个该看的 kubectl logs -f <pod> # 跟进日志 kubectl logs <pod> --previous # 看上次崩溃前的日志(CrashLoop 必备) kubectl logs <pod> -c <container> # 多容器 Pod 要指定容器 kubectl exec -it <pod> -- sh # 进容器 kubectl debug pod/<pod> -it --image=busybox # 容器里没 shell 时用临时容器 # ── 变更 ────────────────────────────────────────────── kubectl apply -f xxx.yaml # 声明式,推荐 kubectl delete -f xxx.yaml kubectl scale deploy/<name> --replicas=5 kubectl set image deploy/<name> <container>=<image> kubectl rollout status deploy/<name> kubectl rollout undo deploy/<name> kubectl rollout restart deploy/<name> # 不换镜像,只重启(比如让 ConfigMap 生效) # ── 临时调试 ────────────────────────────────────────── kubectl port-forward svc/<svc> 8080:80 kubectl run tmp --rm -it --image=busybox -- sh # 起个临时 Pod 测网络 kubectl explain deployment.spec.strategy # 官方字段文档直接查 ``` ### 2.1 几个高频小技巧 ```bash # 看 Pod 为什么没起来:直接抓 Events kubectl describe pod <pod> | sed -n '/Events/,$p' # 对比"我提交的"和"集群实际存的"(很多默认值会被补上) kubectl get deploy <name> -o yaml > actual.yaml # 不记得字段名? kubectl explain pod.spec.containers.resources --recursive # 在 Pod 里测 Service 通不通(用临时 Pod,别在业务容器里装工具) kubectl run tmp --rm -it --image=busybox -- wget -qO- http://blog-system:80/actuator/health ``` --- ## 3. 常见异常对照表 ### 3.1 Pod 状态类 | Pod 状态 | 真实含义 | 第一步查什么 | |---|---|---| | `Pending` | 还没被调度到节点上 | `describe pod` 看 Events:资源不够 / 节点选择器不匹配 / PVC 没绑定 | | `ContainerCreating` | 正在拉镜像、挂卷 | 镜像大就慢;一直卡着看 Events | | `ImagePullBackOff` | 拉不到镜像 | 镜像名/tag 写错 / 私有仓库没配 `imagePullSecrets` / 仓库网络不通 | | `CrashLoopBackOff` | 容器起来就挂,被反复重启 | `kubectl logs --previous` 看崩溃日志 | | `Running` 但没有 `Ready` | 探针没通过 | `describe pod` 看 probe 失败信息;路径/端口/`initialDelaySeconds` 写错 | | `OOMKilled` | 超过 memory limits 被内核杀掉 | 调大 limits 或修内存泄漏 | | `Evicted` | 节点资源不足被驱逐 | 节点压力大;看 `requests` 是否设得合理 | | `Terminating` 卡住 | 删不掉 | 有 finalizer 或卷卸载卡住:`describe pod` | | `Error` / `Completed` | 容器退出(异常 / 正常结束) | 是不是把一次性任务当成常驻服务跑了 | ### 3.2 访问不通类 | 现象 | 最可能的原因 | 验证命令 | |---|---|---| | Service 访问不通 | `selector` 和 Pod 的 `labels` 对不上 | `kubectl get endpoints <svc>` 为空 | | Endpoints 是空的 | 同上,或就绪探针一直没过 | 同上 + `describe pod` 看探针 | | 集群内能通,外网不通 | Ingress 规则/`ingressClassName` 不对,或没有 Controller | `kubectl describe ingress` + 看 Controller 日志 | | 外网 404 | Ingress 的 `host`/`path` 不匹配 | `curl -H "Host: xxx" ...` 对比规则 | | 外网 502/503 | 后端没有可用 Pod | `kubectl get endpoints` | | 间歇性 5xx | 只跑了一个副本,或探针没配导致发布时短暂不可用 | 看副本数 + 探针配置 | | DNS 解析不了 | 服务名/命名空间写错 | `kubectl run tmp --rm -it --image=busybox -- nslookup <svc>` | ### 3.3 滚动更新类 | 现象 | 原因 | |---|---| | `rollout status` 一直不结束 | 新 Pod 起不来(看 `describe`),常见是探针配错、镜像拉不到 | | 更新卡住且旧 Pod 不减少 | `maxUnavailable: 0` + 新 Pod 一直没就绪 → 正常的"保护",先修新 Pod | | 更新后老代码还在跑 | 镜像 tag 用了 `latest`,节点上缓存了旧镜像 → 用明确版本号 | | 想撤销到某个历史版本 | `kubectl rollout history` 看编号,再 `rollout undo --to-revision=N` | --- ## 4. 生产前必须知道的几件事 入门跑通之后,往下走会碰到这些,先建立认知就不会踩: | 主题 | 一句话 | 什么时候需要 | |---|---|---| | **探针** | liveness 决定"重启不重启",readiness 决定"给不给流量" | 上线前必备 | | **resources** | 不设就是拿整个节点的稳定性赌博 | 上线前必备 | | **HPA** | 按 CPU/内存/自定义指标自动扩缩副本 | 流量波动明显时 | | **Namespace** | 逻辑隔离(不隔离内核资源),配合 ResourceQuota 管配额 | 多环境 / 多团队 | | **RBAC** | ServiceAccount + Role/ClusterRole,控制"谁能对什么资源做什么" | 有多个使用者时 | | **Helm** | K8s 的"包管理",把一堆 YAML 参数化、版本化 | YAML 超过 10 个文件后 | | **Operator** | 把"运维知识"写成控制器(比如自动做主从切换) | 有状态服务的深度运维 | | **可观测性** | Prometheus 指标 + 日志聚合 + 链路追踪 | 上线后 | | **网络策略** | NetworkPolicy,默认全通,按需收紧 | 多租户 / 安全要求高时 | | **成本** | 云上集群按节点/负载均衡/存储计费,空闲资源就是白花钱 | 一直要盯 | --- ## 5. 最后:几条踩过才知道的经验 ```text 1. K8s 的坑大多不在"怎么用",而在"以为它会自动做" └─ 它只保证你声明过的东西;备份、容量、成本、安全它一概不管 2. 探针设错比不设更危险 └─ liveness 依赖数据库 = 数据库抖动时全量重启,把小问题放大成雪崩 3. 别用 latest 标签 └─ 节点缓存 + 无法回滚到确定版本,是发布事故的常见起点 4. 从内到外排查,不要跳步 └─ 先 get pods,再 get endpoints,最后才是 Ingress 5. 每次上线前先想清楚"怎么回滚" └─ rollout undo 至少演练过一次,别等出事才现学 ``` --- ## 6. 课程回顾 ```text 00 总览 为什么需要 K8s、路线、环境 01 核心对象 观念(声明式/API/控制器循环)+ 架构 + Pod + Deployment 02 网络暴露 为什么不能用 Pod IP + Service 四种类型 + Ingress 03 配置数据 ConfigMap / Secret / Volume,配置与镜像分离 04 完整实战 Spring Boot + MySQL 从镜像到外网,含零停机验证 05 排障速查 链路 + 命令 + 异常对照 + 生产清单 ← 本篇 ``` **下一步可以学什么**(按这个顺序不会乱): ```text 先把无状态玩熟 ↓ Helm(把 YAML 管起来) ↓ 可观测性(Prometheus + 日志聚合,先有数据再谈优化) ↓ HPA(有指标之后自动扩缩才有意义) ↓ StatefulSet / Operator(真正开始碰有状态服务) ↓ Service Mesh(服务数量上来了再考虑) ```
预览
发布文章
添加摘要让读者更快了解文章内容
取消
确认发布
AI 写作助手
输入一个主题,AI 将为你生成一篇 Markdown 博客文章
AI 正在写作中...
取消
开始生成
AI 优化助手
描述你的修改需求,AI 将在原文基础上进行补充或微调
AI 正在优化中...
取消
开始优化
画布
从已有图里选
✕
图名
保存后生成 /images/excalidraw/<图名>.svg(只能用字母、数字、短横线、下划线、点)
取消
保存并插入