Kubernetes生产运维00:会部署K8s,不等于会运维K8s
Kubernetes生产运维00:会部署K8s,不等于会运维K8s

写在前面
我是一名做了8年运维的DevOps工程师,目前管理AWS、腾讯云和阿里云上的6个Kubernetes集群,涉及百台节点和数百个Pod。
刚开始接触Kubernetes时,我也会把重点放在怎么创建Deployment、怎么暴露Service、怎么写Ingress。等真正面对生产故障后才发现:把服务部署进去只是开始,出现问题时能不能快速缩小范围,才是生产运维真正拉开差距的地方。
生产告警通常不会直接告诉你根因。
它只会告诉你:接口超时了、Pod重启了、节点不正常了,或者用户访问失败了。
同一个超时,可能来自应用线程池、Service没有Endpoint、CoreDNS异常、NetworkPolicy拦截、节点连接耗尽,也可能只是上游依赖变慢。命令记得再多,如果没有缩小范围的方法,仍然只能靠猜。
这也是我开启这个专栏的原因。
这套内容不从安装Kubernetes讲起,而是从生产环境最常见的问题出发,讨论如何判断影响、采集证据、验证假设、恢复服务,并在故障后补上监控和治理措施。

会部署和会运维,区别在哪里
会部署Kubernetes,通常意味着你能够:
- 创建Deployment、Service和Ingress
- 使用ConfigMap和Secret注入配置
- 使用Helm发布应用
- 查看Pod状态和日志
- 完成扩缩容与滚动更新
这些能力很重要,但它们处理的是相对确定的问题:目标明确、步骤固定、结果可以预期。
生产故障恰好相反。
| 维度 | 部署任务 | 生产故障 |
|---|---|---|
| 起点 | 已知目标配置 | 只有模糊现象 |
| 路径 | 按步骤执行 | 根据证据动态选择 |
| 影响 | 通常可以提前评估 | 可能持续扩大 |
| 操作 | 关注是否成功 | 还要考虑是否扩大故障 |
| 结果 | 资源创建完成 | 业务恢复且根因被验证 |
生产排障不是把所有命令都执行一遍,而是每拿到一条证据,就排除一批不可能的方向。
例如,只有一个Pod异常和同一节点上的多个服务同时异常,排查起点完全不同:
- 只有一个Pod异常,优先看应用、配置、镜像和依赖
- 同一Deployment的所有Pod异常,优先看发布、公共配置和上游依赖
- 同一节点上的多个不同服务异常,优先看节点、运行时和网络
- 多个集群同时异常,优先看公共入口、外部依赖或统一变更
真正的经验,不是看到一个状态就背出十种原因,而是知道下一条最有区分度的证据在哪里。
第一原则:根据影响决定先止损还是先定位
你选择的实战习惯是:根据故障严重程度决定处理顺序。这个判断比固定地先查日志或先重启更符合生产环境。

可以把事件粗略分为四级。不同公司的等级名称和响应时间会不同,下面是用于理解方法的参考框架。
| 等级 | 典型影响 | 第一动作 | 后续动作 |
|---|---|---|---|
| 严重 | 核心业务大面积不可用 | 回滚、切流、降级或隔离 | 恢复后保留数据并调查 |
| 较高 | 关键功能受损且影响扩大 | 一边控制影响,一边取证 | 建立时间线并组织协同 |
| 一般 | 少量实例异常,有冗余承接 | 先保留现场和采集证据 | 验证根因后修复 |
| 较低 | 无用户影响或潜在风险 | 按计划分析 | 纳入治理任务 |
这里有两个容易混淆的点。
止损不等于盲目重启
如果重启能够快速恢复业务,可以执行,但要尽量先保存容易丢失的信息:
# 保存Pod完整状态
kubectl get pod <pod-name> -n <namespace> -o yaml > pod-before-restart.yaml
# 保存相关事件
kubectl events -n <namespace> --for pod/<pod-name> > pod-events.txt
# 保存当前和上一次容器日志
kubectl logs <pod-name> -n <namespace> --all-containers > pod-current.log
kubectl logs <pod-name> -n <namespace> --all-containers --previous > pod-previous.log
# 保存工作负载版本和发布历史
kubectl rollout history deployment/<deployment-name> -n <namespace>
Events可能过期,崩溃容器的previous日志也可能随着多次重建消失。先花几十秒保存现场,往往能避免业务恢复后再也找不到根因。
取证也不能拖延恢复
如果核心交易已经中断,不能为了追求完美根因让用户一直等待。
更合理的做法是并行分工:一组人执行已验证的回滚或切流方案,另一组人记录时间线、保存现场并观察指标。没有多人协同时,也应先执行风险最低、回退路径最明确的恢复动作。
生产排障的五步框架

这套专栏会反复使用下面五个步骤。
第一步:判断影响
先回答业务问题,而不是先回答技术问题。
从什么时候开始
影响哪些用户、区域和接口
全部失败还是部分失败
错误率、延迟和流量发生了什么变化
冗余实例是否还能承接
影响是否仍在扩大
只有明确影响范围,才能决定事件等级、参与人员和第一动作。
一个Pod处于CrashLoopBackOff,不一定代表业务故障。如果Deployment还有多个健康副本,Service也只把流量转给Ready Pod,用户可能完全无感。相反,所有Pod看起来都在Running,也不代表业务正常,Readiness、应用错误率或上游依赖仍可能出问题。
第二步:建立时间线
生产故障经常与变更有关,但最近有发布不等于发布一定是根因。
应该把时间对齐:
14:00 新版本发布
14:03 错误率开始上升
14:04 部分Pod Readiness失败
14:06 用户反馈超时
14:08 回滚开始
14:11 错误率恢复
时间线能够形成强线索,但还需要配置差异、日志、指标或回滚结果来验证。
重点核对:
- 应用发布和镜像变更
- ConfigMap、Secret和环境变量变更
- Helm values和副本数变化
- 节点升级、扩缩容与驱逐
- 网络策略、Ingress和证书变更
- 云负载均衡、存储或外部依赖变更
第三步:分层采集证据
Kubernetes故障不是只有Pod一层。可以从上到下分成:
用户与业务
↓
入口与负载均衡
↓
Ingress或Gateway
↓
Service与EndpointSlice
↓
Pod与容器
↓
Node、kubelet与容器运行时
↓
网络、存储和云基础设施
每一层都要回答两个问题:
- 请求或资源是否到达这一层
- 这一层是否有证据证明自己正常
常用的第一轮信息采集如下:
# 工作负载与Pod分布
kubectl get deployment,pod -n <namespace> -o wide
# Pod状态、容器状态和Events
kubectl describe pod <pod-name> -n <namespace>
# 当前及崩溃前日志
kubectl logs <pod-name> -n <namespace> -c <container-name>
kubectl logs <pod-name> -n <namespace> -c <container-name> --previous
# Service与后端端点
kubectl get service,endpointslice -n <namespace>
# 节点状态和资源压力
kubectl get nodes
kubectl describe node <node-name>
# 按时间查看事件
kubectl events -A --types=Warning
这些命令不是固定套餐。Pod还没有调度时,容器日志并不存在,应该优先看FailedScheduling事件;多个不同服务集中在同一节点异常时,则应尽快转向Node、kubelet、运行时和主机指标。
第四步:提出假设并做最小验证
证据不是越多越好,关键是能够区分不同原因。
例如服务超时,当前有两个假设:
- 假设A:Redis服务端负载过高
- 假设B:只有特定节点上的客户端连接异常
有区分度的验证包括:
- Redis服务端指标是否异常
- 异常是否集中在特定Pod或Node
- 同一服务迁移到其他Node后是否恢复
- 异常Node与正常Node的TCP、连接跟踪和丢包指标是否不同
每次验证尽量只改变一个变量,并提前准备回退方式。不要同时重启Pod、修改资源、切换节点和调整网络,否则即使恢复,也不知道哪个动作真正有效。
第五步:形成闭环
故障恢复不是事件结束。
完整闭环至少包括:
临时恢复
→ 根因验证
→ 永久修复
→ 监控告警
→ Runbook或自动化
→ 复盘行动项
如果问题只能依赖某位老员工凭经验发现,下次仍然会重复消耗时间。应该把关键证据转化为指标、告警、发布检查、配置策略或自动诊断规则。
一个真实案例:Redis超时如何缩小到节点连接泄漏

下面是一个A级脱敏案例,只保留通用排查逻辑。
故障现象
部分微服务偶发Redis连接超时,但Redis服务本身看起来正常。从Pod内手工测试,基础网络也能连通。
如果只盯着Redis日志,很容易在服务端反复寻找并不存在的问题。
范围收敛
排查过程不是一次猜中,而是逐步排除:
Redis连接超时
→ Redis服务端资源和连接正常
→ Pod到Redis的基础网络可达
→ 不是所有Pod同时发生
→ 异常集中在部分Node
→ 异常Node的TCP分配连接数持续增长
→ 正常Node的同一指标保持稳定
→ 多个服务共用同一Redis客户端依赖
→ 开发定位依赖中的连接释放问题
关键证据是异常节点上的node_sockstat_TCP_alloc持续增长,并且与正常节点形成明显对照。
这条指标本身不能直接证明代码有Bug,但它把范围从Redis服务和整个网络,缩小到了特定节点上的TCP连接行为。再结合多个服务共用同一个客户端依赖,开发最终定位到底层网络调用没有正确释放连接。
修复与预防
- 临时层面:将受影响工作负载迁离异常节点,恢复连接能力
- 永久层面:升级公共Redis客户端依赖,修复连接释放问题
- 监控层面:增加节点TCP分配连接数及增长率告警
- 复盘层面:把节点级连接指标纳入类似超时问题的排查清单
这个案例说明,真正的排障能力不是会执行更多命令,而是能够根据对照证据不断改变观察层级。
应用层没有发现问题时,继续盯着同一批日志不会自动产生答案。要敢于从应用转向Pod,从Pod转向节点,再从节点指标回到公共代码依赖。
三类证据,避免把经验写成故事
这个专栏会明确标记案例证据等级。
| 等级 | 来源 | 使用方式 |
|---|---|---|
| A | 真实生产处理记录 | 脱敏后呈现现象、证据和处理决策 |
| B | 本地或临时集群实验 | 给出配置、步骤和实际结果 |
| C | 官方机制和设计分析 | 明确标注原理说明或待验证方案 |
这样做有两个目的:
第一,不把网上看来的方案包装成亲自做过。
第二,避免把一次偶然恢复写成确定根因。重启后恢复只能证明重启改变了状态,不能单独证明内存泄漏、网络故障或应用Bug。
生产排障最常见的五个误区
误区一:看到异常就重启
重启有时是正确的止损动作,但它可能清除现场。执行前应判断影响等级,并保存关键状态、Events和日志。
误区二:只看Pod状态
Running只是Pod阶段,不代表应用接口、依赖和业务指标正常。还要看Ready状态、EndpointSlice、错误率和延迟。
误区三:列出十种原因却不排序
排障清单有用,但更重要的是根据当前证据排序。最近变更、异常分布和对照组通常比泛泛的可能性更有价值。
误区四:一次修改多个变量
同时改资源、重启、换节点和回滚,会破坏因果判断。除非正在处理严重故障,否则优先做最小验证。
误区五:业务恢复后不再追查
没有永久修复、监控和Runbook,意味着同类故障还会回来。恢复是应急目标,闭环才是运维目标。
这个专栏会讲什么
整个系列包括导读和15篇正文,分为三个阶段。
第一阶段:Pod与基础排障
- 生产故障排查方法论
- kubectl排障工具箱
- Pod Pending
- CrashLoopBackOff
- OOMKilled与内存治理
目标是建立排查顺序,理解Pod状态背后的调度、容器和资源机制。
第二阶段:网络、存储与节点
- Service访问异常
- CoreDNS解析故障
- Ingress 404与502
- PVC Pending与挂载失败
- Node NotReady
目标是从单个Pod扩展到完整请求链路和基础设施层。
第三阶段:稳定性与治理
- 三类探针设计
- Requests、Limits与QoS
- RBAC最小权限
- Kubernetes集群无中断升级
- 监控、告警与故障复盘
目标是把一次次救火转化为配置标准、升级Runbook和稳定性闭环。
与面试和K8sChat项目的关系
这套专栏不只是为了发文章。
每篇内容都会同步转化为三类资产:
| 文章内容 | 面试资产 | K8sChat资产 |
|---|---|---|
| 排查路径 | 结构化场景题答案 | Agent分析步骤 |
| kubectl命令 | 实操追问答案 | 查询工具定义 |
| 故障案例 | STAR故事素材 | 测试与评估案例 |
| 停止条件 | 风险控制话术 | Agent退出机制 |
| 预防措施 | 架构治理能力 | 自动检查建议 |
例如CrashLoopBackOff文章中的Events、previous日志、退出码和OOM判断,未来可以直接转成K8sChat的工具调用顺序和评估数据。
面试怎么说
60秒回答
我认为Kubernetes生产运维的核心不是记住多少kubectl命令,而是能否根据影响和证据快速缩小故障范围。我的处理顺序是先判断业务影响,严重故障优先通过回滚、切流或隔离止损,影响可控时先保留现场。然后建立时间线,从应用、Pod、Service、Node到基础设施分层采证,每次用最小验证排除一个假设。恢复后还要验证根因,补监控、告警和Runbook,形成闭环。
3分钟项目版
可以结合Redis连接超时案例展开:
- Redis服务端和Pod基础连通性正常
- 通过异常分布发现问题集中在部分节点
- 对比节点指标发现TCP分配连接数持续增长
- 将范围缩小到公共Redis客户端依赖
- 开发修复连接释放问题
- 运维增加节点TCP增长率告警
重点不是宣称一开始就猜到Bug,而是说明每条证据如何推动范围收敛。
延伸问答
| 问题 | 回答要点 |
|---|---|
| 严重故障还需要保留现场吗 | 需要,但不能阻塞止损。优先保存几十秒内可获得的状态、事件和日志,并行执行恢复 |
| 回滚后恢复能证明发布是根因吗 | 只能形成强关联,还要对比版本、配置、日志或复现实验,确认具体变化 |
| Pod Running为什么服务仍然不可用 | Running不等于Ready,应用可能未就绪,Service也可能没有匹配到健康端点 |
| Events和日志哪个先看 | 取决于阶段。Pending优先Events,容器崩溃优先状态、Events和previous日志组合 |
| 怎么判断该转向Node层 | 多个不同工作负载集中在同一节点异常,或Pod层证据正常但问题随节点迁移而变化 |
| 什么才算根因 | 能解释现象和范围,有证据支持,并能通过修复或复现验证,而不是只与故障同时出现 |
小结
- 会部署Kubernetes解决的是确定性任务,生产运维面对的是模糊现象和持续变化的风险。
- 排障第一步不是执行命令,而是判断业务影响和故障范围。
- 严重故障优先止损,影响可控时优先保留现场,二者可以并行。
- 时间线、异常分布和正常对照组,是缩小范围的重要工具。
- 每次验证尽量只改变一个变量,避免恢复后仍不知道原因。
- 业务恢复不是结束,还要完成根因验证、永久修复、监控和复盘。
- 生产经验的价值不在于一次猜中,而在于建立可重复的证据链。
下一篇预告
下一篇进入这套系列的核心:Kubernetes生产故障排查方法论。
我们会把影响评估、时间线、变更检查、分层排查、假设验证和故障记录整理成一份可以直接使用的生产排障清单。
参考资料
- Kubernetes官方文档:Troubleshooting Applications
- Kubernetes官方文档:Debug Running Pods
- Kubernetes官方文档:Troubleshooting Clusters
- Kubernetes官方文档:kubectl events
- Kubernetes官方文档:Logging Architecture
本文对官方资料进行了归纳和重新表述,生产案例已脱敏。
更多推荐
所有评论(0)