Skip to content

第14章 故障与交付案例集(实施场景版) ​

对应简历:贯穿全部项目——工作职责「负责平台上线割接、环境验收与客户方培训交付」「上线后驻场提供运维支持,与华为原厂协同处理巡检、告警与疑难故障」/ 项目一职责「负责上线割接与环境验收」/ 项目二职责「沉淀海外镜像拉取失败、RBAC 字段不可变等 9 项生产避坑清单」

用法:每个案例按"场景 → 排查(命令+讲解)→ 根因 → 解决 → 预防 → 面试讲法(完整 STAR)"六段背。来源标注:【真实项目】= 我在生产亲手处理/验证;【课程项目】= 课程实验 + 理解口径;【经典故障】= 话术库标准案例,讲时用"我处理过类似的"口径。实施版特别说明:本章前 5 个为实施场景专属案例(环境踩坑/割接回滚/现场网络/培训冷场/原厂协同)——实施岗面试官问"客户现场出问题你怎么办",弹药主要从这五条里拿;其后保留通用技术故障骨架。术语:Kubernetes(下文简写 K8s)。

14.0 故障回答万能框架(先止损 → 再定位 → 后复盘) ​

任何故障场景题,先套这个框架再展开细节——实施岗加一句升级版:现场故障的第一动作还包括"稳住客户"。

使用方法:

  • 面试官抛出任何故障题,回答的第一句话永远是框架第一句,然后进入具体案例六段;实施场景再补"同步通报客户与干系人";
  • 六段里面试讲法是完整口述版(60–120 秒),其余五段是被追问时的展开弹药;
  • 每个"排查"小节的第一条命令要形成条件反射。
  1. 先止损(最优先):恢复业务优先于找根因——有备切换备、能扩先扩、影响大先摘流量;同步通报干系人、安抚客户("问题我在跟,预计 X 分钟给下一步结论");客户现场宁可保守不可炫技。
  2. 再定位(体现技术):从入口往里、从网络到应用分层收敛;看监控曲线 + 看日志 + 看变更("最近改了什么"——六成故障和变更相关);实施场景特别一招"环境对照"——同样的包在能跑的环境和跑不起的环境做差异对比。
  3. 后复盘(体现素养):恢复后写故障报告(时间线/根因/动作/影响);根因改进(配置固化、监控补盲、预案演练);把个案沉淀成部署手册的检查项——我的 9 项避坑清单和"注意事项"章节就是这么来的。

案例速查总表(被问"遇到过什么故障/踩过什么坑"时扫一眼选 1–2 个展开):

#现象第一条命令根因一句话来源
1ARM 装机踩坑docker inspect | grep Arch二进制/镜像架构不匹配真实
2割接验证失败割接清单逐项核预案兑现:触发回退真实
3客户访问不通telnet IP 端口监听地址/防火墙/安全组真实
4培训冷场(软技能框架)讲法不对路,换实操真实
5原厂协同排障(转案四件套)转案质量决定闭环速度真实
6节点 NotReadykubectl get pods -n kube-flannelCNI 镜像拉取失败(90%)真实
7kubectl x509openssl x509 -text 查 SAN证书缺新入口地址真实
8数据库双主风险集群状态查询两节点同时重启(license 替换)真实
9CPU 打满top(按 P)应用死循环/挖矿/IO 传导经典
10进程被杀dmesg | grep -i oom内存泄漏,OOM killer经典
11No space leftdf -h / df -i日志堆积或 inode 耗尽经典
12502/504ss -lntp 看后端502 后端挂、504 后端超时经典
13认证时好时坏date / timedatectl 对比节点时间不同步真实
14VIP 时通时断两台分别 ip addrKeepalived 脑裂双 MASTER经典
15CrashLoopBackOffkubectl logs --previous应用启动报错(配置/依赖)课程+生产
16容器宿主机磁盘涨满docker system df镜像层堆积+日志无上限经典
17Secret 空值接口报错进 Pod 看 Secret 文件转义丢字符+异常吞错经典

第一部分 实施场景案例(实施版核心,前五个必背) ​

14.1 ARM 环境交付连环坑:镜像架构与依赖缺失 【真实项目】 ​

场景:银行项目统信 UOS(ARM)环境部署 BCS 与 K8s 组件,两类典型报错交替出现:容器启动报 exec format error;源码编译 Redis 时报依赖库缺失。

排查(命令 + 讲解):

bash
docker inspect <镜像> | grep Architecture      # 查本地镜像实际架构
docker manifest inspect <镜像>:<tag>           # 外网查该 tag 的架构支持列表
yum install -y gcc make                        # 编译缺依赖先补工具链
yum provides "*/lksctp-tools.so" || yum search <库名>   # 反查缺失库属于哪个包
cat /etc/yum.repos.d/*.repo | grep -i aarch64  # 确认用的是 aarch64 源

第一类问题(exec format error)的定位思路是"内核执行不了另一个指令集的二进制"——x86 的镜像在 ARM 节点上就是这个表现。我用 docker inspect | grep Architecture 查已导入镜像的实际架构,用 docker manifest inspect(在外网机器)查一个 tag 有没有 arm64 构建,两步就能把"镜像问题"和"环境问题"切开。第二类问题(编译缺依赖)的处理套路是 yum provides 反查:报错说缺某个 .so 文件,就用 yum provides 搜这个文件属于哪个包,装上对应的 devel 包再重编译——比网上搜报错快。还有一个前置检查容易被忽略:确认 yum 源本身是 aarch64 的——如果源配的是 x86 仓库,装出来的包全都是错的,后面所有报错都是连环假象。

根因:ARM 国产化环境的软件供给链和 x86 完全是两套——镜像要 arm64 构建、二进制要 aarch64 包、编译依赖要从 ARM 源补;任何一处混入 x86 资产就报架构错误。 解决:镜像层做"镜像架构清单"(镜像名/tag/architecture/来源四列表格)交付前逐项核对;二进制层统一走 aarch64 静态包或 aarch64 专用源;编译层先补齐 ARM 的 devel 依赖再 make。 预防:把"架构核对"写进部署手册环境准备一节的固定检查项;镜像导入后第一件事不是起容器而是查 Architecture 字段。

面试讲法(STAR 完整版,约 320 字): 这是我 ARM 国产化交付里最有代表性的一课。情境:银行内网统信 ARM 环境部署 BCS 组件,容器起不来报 exec format error,同时源码装 Redis 还报依赖库缺失,两类问题叠在一起。任务:把组件在 ARM 环境装通。行动:我先处理镜像问题——docker inspect 查这个镜像的 Architecture 字段,发现混进了一个 x86 镜像,内核执行不了另一个指令集的二进制就是这个报错;外网机器用 manifest inspect 核对该 tag 的架构支持列表后,换成已验证的 arm64 离线包重新导入。编译问题用 yum provides 反查缺失的 .so 属于哪个包,从 aarch64 源补上 devel 依赖重编译通过;顺手检查了 yum 源配置确认全是 aarch64 仓库,杜绝后续连环错。结果:组件全部装通;更重要的是沉淀——我做了"镜像架构清单"这个交付前检查项(四列表格逐项核对),并把"架构核对"写进部署手册环境准备一节。后来同类项目零复发。这个案例我常拿来讲实施岗的核心习惯:内网国产化环境里,"先核对架构再动手"应该像"先备份再变更"一样成为肌肉记忆——偶发事故变成清单检查项,就是踩坑的完整回报。

14.2 割接回滚决策:窗口内验证失败怎么办 【真实项目】 ​

场景:上线割接窗口内,业务验证阶段发现某核心功能异常,窗口时间已过半,客户和原厂接口人都在线上等结论——继续修还是回退?

排查/决策(动作 + 讲解):

text
① 触发决策框架(割接方案里预定义):
   验证清单分"关键项/非关键项"——核心业务功能属关键项,失败即进入回退评估
② 回退评估只回答一个问题:能否在剩余窗口内定位并修复?
   → 能且影响可控:修复继续;不能:立即执行回退
③ 回退执行(预案命令级):恢复网络配置 → 回滚应用版本 → 恢复数据指向 → 复测验证清单
④ 全程记录时间线:T0 发现异常 → T1 决策 → T2 回退完成 → T3 验证通过

这个场景的"排查"不是敲命令,是按预案走决策流程——这正是割接准备的价值兑现时刻。关键项失败后我先组织快速定位(10 分钟内):从验证报错入手分层收敛——是数据问题、配置问题还是代码问题;结论是"剩余窗口内修复风险不可控",触发回退。回退动作是预案里写好的命令级步骤,逐条执行、每步即验,全程向客户同步:"发现问题——判断无法在窗口内稳妥修复——按预案执行回退,预计 X 分钟完成"。回退完成后按验证清单复测通过,宣布本次割接未成功但系统已恢复到割接前状态,业务无损。

根因:割接内容里一处变更在测试环境验证不充分——测试环境与生产的数据规模差异放大了问题(这类差异正是割接风险清单应该覆盖的项)。 解决:按预案回退,业务无损;问题定位后单独修复、补齐测试,安排下一个窗口重新割接,二次成功。 预防:割接方案必须包含"回退触发条件 + 命令级回退步骤 + 回退验证清单"三件套;测试环境尽量对齐生产数据规模;关键变更在割接前于类生产环境预演。

面试讲法(STAR 完整版,约 300 字): 这是我对"变更管理"理解最深的一次实战。情境:银行平台上线割接,窗口过半时核心功能验证失败,客户、华为原厂都在线上等结论。任务:在不伤业务的前提下给出决策。行动:我没有陷进"现场修"的执念——按割接方案里预定义的决策框架走:该功能属验证清单关键项,失败即进入回退评估;评估只回答一个问题"能否在剩余窗口内定位并修复"——快速分层定位后结论是风险不可控,于是按预案执行回退:命令级步骤逐条执行每步即验,全程向客户同步进展和预计完成时间。结果:回退完成业务无损,问题事后定位修复、补齐测试,第二个窗口一次割接成功。复盘沉淀两条:一是"回退不是失败,是预案的组成部分——敢不敢割接取决于能不能退回来";二是测试环境与生产的数据规模差异进了割接风险清单。这个案例我讲的时候重点不是技术,是决策纪律:窗口内的沉没成本不该影响决策,现场最贵的动作是"没有决策"——这套思路我在第 15 章的割接方法论里把它标准化了。

14.3 客户现场"服务访问不通"排查(联调期最高频) 【真实项目】 ​

场景:平台部署完成,客户从他们的办公网访问管理页面打不开;我方人员在本机自测一切正常——"我们这边好好的"和"我们这边就是打不开"各执一词。

排查(命令 + 讲解):

bash
# 我方服务器侧:
ss -lntp | grep -E ':443|:8080'      # 1 服务监听 + 监听地址(0.0.0.0 还是 127.0.0.1)
# 客户侧(请客户配合或远程指导):
ping <服务器业务IP>                   # 2 三层通不通
telnet <服务器业务IP> 443             # 3 四层端口通不通
nslookup <平台域名>                   # 4 解析对不对(域名场景)
traceroute <服务器业务IP>              # 5 路径断在哪(跨网段场景)
# 网络设备侧(需要网络团队配合):
display port vlan / display vlan      # 6 VLAN 放行核对(华为 CE)

这类"各执一词"的问题,解法是把模糊的争议变成分层的测量。第一步先自证:ss 看服务监听且地址是 0.0.0.0——服务只听 127.0.0.1 是第一大坑,本机自测正常、外部全不通;第二步请客户配合跑 ping 和 telnet:ping 通 telnet 不通,方向收敛到端口层(防火墙/VLAN/安全组);ping 不通收敛到路由和 VLAN;第三步域名场景加 nslookup 排解析;第四步跨网段加 traceroute 看断点。这次的真实根因落在第六步:交换机上新增的端口没有放行业务 VLAN——规划表里写了,施工时漏配了。定位到之后一条 port trunk allow-pass 补上,客户访问恢复。

根因:网络配置与规划表不一致——交换机端口 VLAN 放行漏配;叠加服务监听地址类问题的高发性,这类"部署侧自测正常、客户端访问不通"九成是网络路径或监听地址问题。 解决:补齐 VLAN 放行后恢复;同时把"连通性基线验证"固化成部署完成后的固定动作——部署侧、客户侧各跑一组命令留档。 预防:网络施工按规划表逐项勾选完成;部署手册增加"客户视角验证"一节(不能只自测);把 ping/telnet 的验证步骤写进客户交接文档,客户自己也能初判。

面试讲法(STAR 完整版,约 300 字): 这是客户现场最高频的一类问题,我处理过很多次,讲一次最典型的。情境:平台部署完成,客户从办公网访问打不开,我方自测一切正常,双方各执一词。任务:把"谁的问题"变成"断在哪一层"。行动:我先自证服务侧——ss -lntp 确认监听地址是 0.0.0.0 而不是 127.0.0.1(这是第一大坑);然后请客户配合做两个测量:ping 业务 IP、telnet 443——结果 ping 通 telnet 不通,问题收敛到端口层;再核对防火墙放行没问题,最后拉网络团队查交换机——发现新增端口的业务 VLAN 漏配了,按规划表补上 trunk 放行,客户访问恢复。结果之外我做了两件沉淀:把"连通性基线验证"(部署侧加客户侧各一组命令)固化为部署完成后的必做动作;部署手册加了"客户视角验证"一节——部署完不能只自己测,要用客户的网络位置测。这个案例我总结成一句话给团队:现场网络问题的解法是把"各执一词"变成"分层测量"——每一层都有命令能给出客观答案,争议就自然消失。这也是第 9 章排查命令链在现场的典型应用。

14.4 培训冷场应对:客户听不下去怎么办 【真实项目】(软技能场景) ​

场景:给客户运维做平台部署培训,讲到组件架构部分,台下没人提问、有人看手机、有人面露难色——培训效果眼看要砸,而培训是验收交付的一部分,砸了直接影响客户对整个交付的评价。

应对框架(动作 + 讲解):

text
① 识别冷场原因(30 秒内判断):
   听不懂(术语过密)?不相关(讲的内容和他的日常脱节)?形式疲劳(单向灌输太久)?
② 立即切换(三选一):
   → 降维:术语换人话("etcd 多数派"→"三台管理节点坏一台还能决策")
   → 换场景:从讲原理切到"你每天上班要用的三个页面"
   → 换形式:从 PPT 切现场演示——现场制造一个告警、当场处置给客户看
③ 提问激活:点名式开放式提问("你们现在碰到告警第一件事做什么?")
④ 收口重设计:下半场改为"客户操作 + 我看"——实操永远比听讲有效

那次的真实处理:我讲到一半发现冷场,判断是"不相关"——客户运维关心的是每天巡检点什么、告警来了干什么,不关心架构图。我当场砍掉架构章节,直接切到现场演示:手动停掉一个采集组件制造真实告警,带着客户从告警出现、看大盘定位、按手册处置到恢复走了一遍全程——台下立刻活了,问题一个接一个。下半场全部改成客户上手操作,我在旁边只纠偏。培训反馈那次反而是最好的——客户对接人原话说"比讲 PPT 的培训有用多了"。

根因:培训设计错位——按"我想讲的"组织而不是按"听众要用的"组织;单向灌输超过 20 分钟必然疲劳。 解决:现场砍章节换演示加实操;事后把培训材料重构为"三段式":价值结论(管理层)→ 日常操作(运维层)→ 实操演练(所有人),实操占一半时间。 预防:培训前先调研听众(谁是使用者、他们日常要做什么);准备"演示预案"(可现场制造的可控故障);培训成功的验收标准定为"客户能独立完成一轮操作",不是"讲完了"。

面试讲法(STAR 完整版,约 280 字): 这个案例我用来答"培训怎么做""客户沟通"类的行为题。情境:客户部署培训讲到一半冷场,没人提问、有人看手机,而培训是验收的一部分。任务:把培训救回来。行动:我先判断冷场原因——不是听不懂,是不相关:客户运维要的是"每天巡检点什么、告警来了怎么办",我却在讲架构。当场决策:砍掉架构章节,切换成现场演示——我手动停掉一个采集组件制造真实告警,带着客户从告警出现、大盘定位、按手册处置到恢复走完全程,现场立刻活了;下半场全部改成客户上手操作,我在旁边只看只纠偏。结果:那场培训反馈反而是最好的,客户对接人说"比讲 PPT 的有用多了";培训材料从此重构为三段式——管理层讲结论、运维层讲日常操作、所有人实操演练,实操占一半时间。沉淀的标准也变了:培训成功的标志不是"我讲完了",是"客户能独立完成一轮操作"。这个案例背后的认知:培训和交付一样,对象是使用者不是技术——内容跟着听众的日常走,形式上"演示和实操永远赢过 PPT"。

14.5 与华为原厂协同排障:转案四件套与闭环 【真实项目】 ​

场景:平台运行期出现一个疑难问题——BCS 相关组件行为异常,一线排查超出我的权限和工具范围(需要原厂内部日志工具或补丁),必须转华为原厂二线。

协同流程(动作 + 讲解):

text
① 一线先穷尽(转案前的责任):
   现象记录(截图/录屏)+ 时间线整理 + 影响面评估 + 已做的排查和结果
② 转案四件套(转案材料的标准结构):
   1 现象描述:什么组件、什么报错、什么时间开始、能否复现
   2 环境信息:版本配套(FC 8.3.0/BCS 1.2.6/K8s 1.17.3)、拓扑、近期变更
   3 证据包:日志片段、告警截图、我已执行的排查命令和输出
   4 我的判断:已排除什么、怀疑什么——给原厂一个起点而不是一堆原材料
③ 过程跟踪:约定响应节点,主动补材料,不当甩手掌柜
④ 闭环验收:原厂给方案后由我验证执行、复测确认,结果记入故障记录

这套流程的核心是"转案质量决定闭环速度":原厂二线拿到的是我整理好的结构化材料,直接从"验证我的怀疑"开始查,而不是从"要日志、问版本"开始。那次案例里,我按四件套转案时附上了"已排除网络和证书因素"的排查记录,原厂直接聚焦到组件配置项,一个工作日给出处置方案,我验证执行后复测恢复。反过来我也见过反面案例:转案只发一句"系统报错了帮忙看看",来回要信息耗掉两三天——对比之下,转案四件套的价值一目了然。

根因:一线与二线的分工边界是"工具与权限",不是"责任心"——一线的职责是把问题收敛到"需要原厂工具/补丁"的精度再转。 解决:按四件套转案,原厂快速定位;我执行方案并复测闭环。 预防:把转案四件套做成模板存在运维手册里;每次协同的结论回填到内部知识库——同类问题下次一线就能处理,逐步减少对二线的依赖。

面试讲法(STAR 完整版,约 280 字): 这题我拿来说明"协同能力"——实施岗在多方团队里的工作方式。情境:银行平台运行期一个 BCS 组件行为异常,超出一线权限,必须转华为原厂。任务:让这次转案最快闭环。行动:我先在一线穷尽排查——现象、时间线、影响面、已做的尝试全部整理;然后按我的"转案四件套"组织材料:现象描述(组件、报错、时间、复现方式)、环境信息(完整版本配套和拓扑、近期变更)、证据包(日志片段、告警截图、排查命令输出)、我的判断(已排除什么、怀疑什么)——最后这条最重要,我给原厂的是起点不是一堆原材料。原厂一个工作日给出方案,我验证执行、复测确认,结果记入故障记录闭环。结果:那次问题的解决周期明显短于同类转案的平均水平,原厂接口人后来主动说"你们的转案材料是他们收到过最完整的"。沉淀:四件套做成模板进了运维手册,每次协同结论回填知识库——同类问题逐步变成一线可处理。我的心得:接口人的价值不是传话,是让链条上每个人都拿到他需要的东西——客户要"有人管到底",原厂要"信息完整",两头都喂饱,我就是闭环本身。


第二部分 通用技术故障案例(保留骨架,实施视角微调) ​

14.6 K8s 节点 NotReady(真实:镜像拉取) 【真实项目】 ​

场景:移动云项目,三台 worker join 之后 kubectl get nodes 一直显示 NotReady。

排查(命令 + 讲解):

bash
kubectl get nodes                                  # 确认 NotReady 范围(全部 or 个别)
kubectl get pods -n kube-flannel -o wide           # Flannel Pod 状态 → ImagePullBackOff
kubectl describe pod <flannel-pod> -n kube-flannel | grep -A5 Events   # 拉取失败详情
kubectl edit daemonset kube-flannel-ds -n kube-flannel   # 镜像地址替换为内网仓库

kubectl get nodes 先确认范围——三台全 NotReady 是共性问题不是单机故障。然后直接看 CNI Pod:get pods -n kube-flannel 的输出里 ImagePullBackOff 一目了然——Flannel 起不来、节点网络插件没就绪、kubelet 自然置 NotReady。describe 看 Events 拿到具体报错:海外镜像源在内网不可达。"九成 NotReady 是镜像拉取问题"这个经验判断就来自这类现场——kubelet 的 Ready 条件依赖 CNI 就绪,CNI 的镜像拉不下来是一切的开端。

根因:内网环境海外镜像不可达 → CNI 起不来 → 节点网络未配置 → NotReady。 解决:kubectl edit daemonset 把 init 容器和主容器镜像全部替换成内网私有仓库地址,DaemonSet 滚动更新后 Pod Running,节点几分钟内全 Ready。 预防:部署顺序强制"先 CNI 后 worker";镜像清单提前入内网仓库——写进建设方案避坑清单第 1 条。

面试讲法(STAR 完整版,约 280 字): 移动云项目真实踩的坑。情境:集群部署到 worker 加入阶段,三台 worker 全部 NotReady,部署卡住。任务:让节点就绪。行动:先 get nodes 确认三台全中——共性问题;直接看 kube-flannel 的 Pod,状态 ImagePullBackOff——九成的 NotReady 到这一步就见分晓;describe 看 Events 确认是海外镜像内网拉不下来,Flannel 起不来节点网络没配置。解决用 kubectl edit 改 Flannel 的 DaemonSet,把 init 和主容器镜像全部替换成内网私有仓库地址,滚动更新后三台节点几分钟内全部 Ready。结果之外更重要的是沉淀:"先部署 CNI 再加 worker"固化成部署顺序,镜像清单预导入写成标准动作,两条都进了 9 项避坑清单。经验句我主动给:遇到 NotReady 先查 CNI Pod 的镜像状态,九成问题在那里终结。

14.7 证书 SAN 缺失(真实:多 master 改造) 【真实项目】 ​

场景:银行项目单 master 升级三 master 后,用 VIP 连 apiserver 报证书错误,kubectl 不可用。

排查(命令 + 讲解): 两条命令完成关键分叉:curl -k https://VIP:16443/version 正常返回——网络、负载均衡、apiserver 全好,问题切割到证书校验层;kubectl 连同一地址报 x509——不跳过校验的客户端报错即指向证书内容。第三条 openssl x509 -in apiserver.crt -text -noout 翻到 SAN 字段——里面只有原单 master 时期的地址,没有新 VIP 和 master02/03。根因落定:kubeadm 的 apiserver 证书只包含初始化时 certSANs 里声明的名字,后来加的入口不在里面。

根因:证书的有效范围在签发那刻画定,新增 VIP 和节点不在 SAN 里,TLS 校验必失败。 解决:三步——kubeadm 配置补全 certSANs(新 VIP 加三台 master 主机名 IP);移走旧证书(mv /etc/kubernetes/pki/apiserver.{crt,key},不移 kubeadm 不重建)后 kubeadm init phase certs apiserver 重签;杀 apiserver 容器让 kubelet 拉起新证书实例,openssl 复核 SAN,最后把 certSANs 回写 kubeadm-config 防续期再丢。 预防:改集群入口地址必须先想证书;初始化时把 VIP、全部 master、LB 地址一次性写进 certSANs——移动云项目这么做了,此坑零复发。

面试讲法(STAR 完整版,约 300 字): 我印象最深的真实故障,因为"两句话定位"的价值在这里体现得最充分。情境:银行项目单 master 升三 master 加了 Nginx+Keepalived VIP 后,用 VIP 连 apiserver 报 x509,集群操作不可用。任务:恢复管理入口。行动:curl -k 跳过校验访问 VIP 的 16443——正常返回,两秒证明网络、LB、apiserver 全好;openssl x509 -text 看 SAN 字段——只有旧地址,新 VIP 和新 master 都不在。解决三步:补 certSANs、移走旧证书重签(不移不会重建)、杀容器让 kubelet 拉起新证书实例,kubectl 恢复;SAN 回写配置防续期丢失。结果:入口恢复,流程沉淀成标准六步。规则级教训:证书的有效范围在签发那刻画定——后来移动云初始化就把 CLB VIP 写进 certSANs,再没出现。把踩过的坑变成团队的前置设计,是故障复盘最大的价值。

14.8 数据库双主风险:license 替换的重启时序 【真实项目】 ​

场景:平台上线后 Vastbase 三个月免费 license 到期,替换正式 license 需重启 HAS 高可用服务;我第一次操作时两节点同时重启,集群短暂出现双主风险预警。

排查/处置(命令 + 讲解):

bash
# 集群状态查询(Vastbase/openGauss 系):
vb_guc / 集群状态命令查看主备角色与复制状态    # 确认主备拓扑
systemctl status has dcs                        # HAS/DCS 服务状态

出险瞬间第一动作是稳住集群:停止第二个节点的重启动作、观察主备角色是否收敛正确、确认复制链路恢复——所幸时间窗极短未造成数据问题。事后复盘根因在操作序列:HAS 高可用组件在两节点同时重启期间会短暂失去互视,可能各自认定自己为主——正确做法是分批:先重启一个节点,等它完全就绪、主备角色确认正确后,再重启另一个。

根因:集群类服务的重启时序问题——同时重启破坏了高可用组件的互视机制,带来双主风险。 解决:现场稳住集群;操作规范改为"先重启一个节点→确认就绪与角色正确→再重启另一个"的分批模式,写进部署指南注意事项。 预防:凡涉及集群状态的操作(重启、切换、升级)先设计"分批加观察"的步骤再动手;这条后来推广到所有重启类变更,也是我讲行为题"最大的挫折"的主案例。

面试讲法(STAR 完整版,约 280 字): 这是我职业生涯里后怕最真的一次,也是行为题"最大挫折"的主答案例。情境:银行平台上线后 Vastbase license 到期,替换需重启 HAS 高可用服务。任务:完成替换且不影响业务连续性。挫折点:我第一次操作按惯性把两个节点同时重启,集群短暂出现双主风险预警——金融生产环境里这就是可能出大事的操作,虽然及时稳住没有造成数据问题,但那一刻的后怕我记到现在。行动:先稳住集群停止后续动作、确认主备收敛;然后复盘操作序列,把"两节点同时重启"改造成"先重启一个、确认就绪和角色正确、再重启另一个"的分批规范,写进部署指南。结果:后续两次 license 操作零风险完成,分批规范成为公司标准文档的一部分。教训一句话:凡涉及集群状态的操作,先设计"分批加观察"再动手——这条后来被我推广到所有重启类变更。

14.9 CPU 负载高定位 【经典故障】 ​

场景:告警 CPU 持续 90%+,业务响应变慢。

排查(命令 + 讲解):

bash
uptime                       # 负载对比核数(8 核 load>8 才算真满载)
top                          # P 按 CPU 排序 → 拿 PID;看 us/sy/wa/si 分布
top -Hp <PID>                # 下钻线程级(单线程打满=死循环特征)
pidstat -u 1 5               # 连续采样分持续型/抖动型

先 uptime 把"告警阈值触发"和"真资源耗尽"分开;top 按 P 拿到吃资源的进程,重点看四项分布:us 高是应用烧 CPU、sy 高是内核态忙、wa 高其实是磁盘慢 CPU 在干等、si 高是网络软中断——分布决定下一步查应用、内核还是 IO。top -Hp 下钻到线程,单线程打满大概率死循环或锁自旋。

根因:常见四类——应用死循环/GC 风暴、异常进程(挖矿)、IO 瓶颈传导(wa 高)、突发流量。 解决:异常进程 kill 并排查入侵入口;应用问题先重启或扩容止损,dump 线程栈交开发定位。 预防:CPU 分级告警(70/85/95)、进程资源限制、可疑计划任务纳入巡检。

面试讲法(STAR 完整版,约 250 字): "我处理过类似的"口径。值班收 CPU 持续 90% 告警,业务变慢。我按先止损再定位:确认有冗余节点,业务影响可控后开始定位。uptime 看负载已超核数,确认真耗尽;top 按 P 锁定一个 Java 进程 us 接近满载——方向从系统层收敛到应用;top -Hp 下钻发现单线程把一核打满,典型死循环特征。止损是重启该服务,业务恢复;事后线程栈 dump 交开发,定位到低效正则回溯爆炸。复盘两件事:该服务加分级告警、推动上线前热点代码 review。沉淀:us/sy/wa 四项分布比 CPU 总数本身信息量大得多——这是我讲 CPU 类故障的第一句。

14.10 内存不足与 OOM 【经典故障】 ​

场景:进程莫名被杀,日志出现 "Out of memory: Killed process"。

排查(命令 + 讲解):

bash
free -h                                  # 看 available 列(含可回收缓存,才是真可用)
dmesg -T | grep -i "out of memory"       # OOM killer 记录——谁被杀、何时
ps aux --sort=-%mem | head -10           # 内存 TOP10
vmstat 1 5                               # si/so 持续非 0 = 疯狂换页

dmesg 是 OOM 类故障的第一证据来源:内核杀进程一定留记录,加 -T 转可读时间对时间线;free 看 available 而非 free——buff/cache 可回收;ps 按内存排序找大户;vmstat 的 si/so 持续非零说明内存压力已传导到换页层。

根因:应用内存泄漏(RSS 缓慢爬升)、并发突增、JVM 堆配置过大挤压系统内存。 解决:重启泄漏进程止损;容器场景统一配 memory limit(超限被 OOMKill 是预期行为,limit 按实际用量加余量)。 预防:内存 80% 告警;看 RSS 趋势提前发现泄漏——缓慢爬升的曲线是泄漏典型形状,等 OOM 才发现就晚了。

面试讲法(STAR 完整版,约 250 字): "我处理过类似的"口径。业务进程周期性被杀,开发查了几轮代码没结果。我介入先找证据:dmesg 加 grep "out of memory"——内核日志明确有 OOM killer 记录,被杀的就是那个进程——问题定性成系统内存耗尽、内核主动杀人,不是应用自己崩。free -h 看 available 见底;ps 按内存排序锁定一个 Python 服务 RSS 异常;回看监控历史,内存三天从几百兆爬到 4G——缓慢爬升,典型泄漏形状。止损加定时重启的临时措施;根因交开发确认是缓存没设上限。修复后我把内存趋势告警加进监控——这类问题的正确发现方式是看曲线斜率,不是等 OOM。dmesg 是 OOM 故障的第一证据来源,这句话我每次培训都讲。

14.11 磁盘满(含 inode 满) 【经典故障】 ​

场景:服务报 "No space left on device",但 df -h 看不出哪个分区满。

排查(命令 + 讲解):

bash
df -h && df -i                      # 先分清容量满还是 inode 满
du -sh /* 2>/dev/null | sort -h     # 逐层下钻大目录
lsof | grep deleted                 # 已删但仍占空间的句柄
> /var/log/nginx/access.log         # truncate 释放(别 rm 大文件)

第一动作同时敲 df -h 和 df -i——海量小文件场景经常 inode 先耗尽,容量看着还有余,只看 df -h 会误判。容量满用 du 逐层下钻加 sort -h;经典陷阱单独查 lsof | grep deleted——进程握着已删文件句柄空间不释放,这就是"rm 了日志 df 却没降"的原因,解法是重启进程或 truncate(原地清空立即生效,对在线服务更安全)。

根因:日志无切割堆积、容器镜像层堆积、binlog 堆积、删除但句柄未释放。 解决:truncate 释放;句柄类重启进程;容器环境 prune 清理无用镜像层。 预防:logrotate 加保留天数、磁盘 80% 告警、清理脚本进 crontab。

面试讲法(STAR 完整版,约 250 字): "我处理过类似的"口径。收磁盘 100% 告警,第一步同时跑 df -h 和 df -i——这是习惯动作,磁盘满有两种,只看容量会误判。这次是容量满;du 逐层下钻锁定日志目录下一个几十 G 的 access.log——日志切割配置没生效。释放动作用重定向 truncate 而不是 rm——rm 大文件的坑是进程持句柄空间不回,truncate 原地清空立即生效,对在线服务更安全。复盘三件事:logrotate 按天切割保留 7 天、磁盘 80% 提前告警、"清理大文件先 truncate 后确认释放"写进 SOP。这个案例我常拿来讲"工具的行为差异也是运维知识"——rm 和 truncate 看似都是删,工程效果完全不同。

14.12 服务 502/504 【经典故障】 ​

场景:Nginx 反代后面,用户请求大量 502/504。

排查(命令 + 讲解):

bash
tail -100 /var/log/nginx/error.log    # connect() failed=502;upstream timed out=504
ss -lntp | grep 8080                   # 后端监听在不在、是否 0.0.0.0
ss -ant | grep 8080 | awk '{print $1}' | sort | uniq -c   # 连接状态分布
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' http://127.0.0.1:8080/   # 本机直连后端

先分清两码:502 后端连不上(挂了/重启中/监听地址不对),504 连上了但超时(后端慢,慢在数据库或下游)。tail error.log 措辞直接分诊;ss -lntp 看后端监听——只听 127.0.0.1 是经典坑;连接状态分布看 SYN_SENT(连不上)/CLOSE_WAIT(应用不关连接);curl 本机直连绕开 Nginx 验证后端本身。

根因:502 常见后端挂/监听 127.0.0.1/backlog 满/被 OOM;504 常见慢 SQL、下游依赖慢、超时参数过短。 解决:502 拉起后端、修正监听地址;504 定位慢在哪层,临时放大 proxy_read_timeout 只是缓解必须治慢源。 预防:后端多副本加健康检查摘除、超时参数标准化。

面试讲法(STAR 完整版,约 280 字): 结合我在数币平台真实处理过的口径。现象:平台上线后用户反馈登录后接口报错。我按"从入口往里"走:curl 入口通——Nginx 活着;telnet 后端 8080 通——链路没问题,"后端连不上"的方向排除;登后端 jps 确认 Java 进程在、监听正常;疑点收敛到应用内部,翻后端日志看到数据库连接报错——顺着查,定位到 Vastbase 主备切换后应用连接串指向没更新。修正配置重启恢复。两条总结:502/504 第一判断永远是分清"连不上"还是"连上了但慢";从入口一层层往里收敛,每步排除一层——比跳着猜快得多。

14.13 时间不同步导致认证失败(真实) 【真实项目】 ​

场景:集群节点间认证频繁失败、日志时间戳乱跳、部分请求间歇性被拒。

排查(命令 + 讲解):

bash
timedatectl                    # 各节点逐一对比时间与时区
chronyc sources -v             # 同步源是否可达、已选择
chronyc tracking               # 偏差量(毫秒级正常)

"时好时坏"是关键词——间歇性故障先找"变化的变量"。逐台 timedatectl 对比,发现个别节点偏差到秒级——不一致的位置找到了;原理:TLS 证书校验对时间敏感(证书有 NotBefore/NotAfter 窗口),偏差大校验间歇性落窗外;chronyc sources -v 确认问题节点没配源或 chrony 没起。

根因:节点未统一时间同步,TLS 时间窗校验间歇性失败。 解决:全节点 chrony 统一指向内网 NTP,重启后 tracking 偏差毫秒级,认证问题消失。 预防:"时间同步检查"写进初始化基线和巡检项——最不像坑的坑伤害最大。

面试讲法(STAR 完整版,约 250 字): 移动云项目真实踩过。情境:集群节点间认证时好时坏,日志时间戳乱跳。任务:定位这个"变化的变量"。行动:直觉先押时间——证书类认证对时间敏感;逐台 timedatectl 对比,果然个别节点偏差到秒级,时好时坏的行为和偏差漂移完全吻合;chronyc sources -v 查出问题节点没配 NTP 源。解决:全节点 chrony 指向内网 NTP,偏差毫秒级,问题再未复现。沉淀:"时间同步校验"进初始化基线和 9 项避坑清单。总结句:间歇性故障的排查入口是找"不一致",多节点横向对比是最快的找法;先对时间,再谈认证。

14.14 Keepalived 脑裂 【经典故障】(结合项目一真实防范) ​

场景:主备两台负载均衡,网络抖动后两边都认为自己是 MASTER,VIP 冲突,流量时通时断。

排查(命令 + 讲解): 确认脑裂一条命令:两台分别 ip addr 看 VIP 绑在谁身上——两边都绑着就是实锤(正常状态 VIP 只在 MASTER 一方)。然后查 Keepalived 日志和 VRRP 通告链路:主备间组播(或单播)报文有没有被交换机/防火墙拦截——脑裂的直接诱因几乎都是"备节点收不到主的通告"。

根因:VRRP 报文不可达(网络分区、组播被禁、防火墙拦截),备节点超时自我升级 MASTER 而主还活着。 解决:临时确定一方降级(停一端 keepalived 或摘 VIP)恢复流量唯一性;根治打通 VRRP 通告链路(放行协议 112 或改 unicast 指定对端)。 预防(我在项目一的真实四招):vrrp_script 检测真实服务端口(ss -antp | grep 16443)而非 keepalived 进程本身;priority 100/90 拉开加 advert_int 1 秒;VRRP 走管理平面交换机;上线前主节点关机实测漂移。

面试讲法(STAR 完整版,约 280 字): 原理加防范实践分开讲。原理:Keepalived 主备关系靠 VRRP 通告维持,主周期发通告、备超时收不到就自我升级——通告链路被打断(网络分区或组播限制)就出现双 MASTER 双 VIP,流量时通时断;确认一条命令:两台分别 ip addr 都绑 VIP 即实锤。防范我在银行项目配 Nginx+Keepalived 前置层时做了四招:检测脚本盯 16443 端口真实监听而不是 keepalived 进程——keepalived 活着不代表后端服务活着;priority 100 比 90 拉开避免抢占抖动;通告走管理平面交换机保链路质量;最关键是上线前演练——主节点直接关机,实测 VIP 秒级漂移、curl version 接口正常。这套"设计加实测"的完整闭环我在现场做过,讲的时候有底气。

14.15 Pod 起不来 / CrashLoopBackOff 通用排查 【经典故障】(课程项目 + 生产接触) ​

场景:部署的 Pod 一直不 Ready,CrashLoopBackOff 反复重启。

排查(命令 + 讲解): 第一句 kubectl get pods -o wide 看状态和重启次数——RESTARTS 持续增长即崩溃循环;kubectl describe pod 看 Events(调度失败/镜像/探针/退出码);kubectl logs --previous 是关键命令——看上一次崩溃前的日志,不加的话容器刚重启可能什么都看不到;Last State 的 exitCode 分方向:137 转内存 limit(OOMKilled),0/1 转应用代码。

根因:高频四类——启动报错(配置/依赖)、镜像问题、探针太苛刻、资源 limit 不足。 解决:按日志对症:配置错修配置;探针调 initialDelaySeconds;OOM 调大 limit 同时查泄漏;依赖连不上按网络链路查。 预防:就绪探针模板化、requests/limits 按实测配、启动类日志格式统一。

面试讲法(STAR 完整版,约 250 字): 集群部署和业务发布中反复处理的一类。现象:业务 Pod 部署后 CrashLoopBackOff。三步:describe 看 Events——排除调度层和镜像层,容器起了又退说明应用自身崩溃;logs --previous 看上次崩溃日志——这个参数是细节所在,不加看到的是刚重启的空日志;这次日志里是数据库连接失败——配置里 Service 名写错了。修正配置重新部署恢复。如果日志看不出,看 Last State 退出码:137 转 OOM 方向,0/1 转代码方向。口诀:describe 看事件、logs 看 --previous、退出码分方向——三步以内必有答案,发布环节处理多了就是条件反射。

14.16 容器环境磁盘涨满与误删应急(两案合一) 【经典故障】 ​

场景一:容器宿主机磁盘告警,业务数据和系统日志都不大——查两个"只涨不缩"的目录:docker system df(或 crictl 对应统计)看镜像、容器、卷各占多少——反复构建的环境悬空镜像能堆几十 G;du -sh /var/log/containers/ 看容器 json 日志——没配上限时一个狂刷日志的容器能写满磁盘。解决:prune 清理悬空镜像与退出容器;daemon.json 配 log-opts max-size/max-file 根治。预防:日志上限作为运行时标准配置部署时就配好;镜像清理进巡检。 场景二:误删文件应急(rm -rf 类):动作有顺序——第一分钟先停服务停止写入(删除后数据块被覆盖前可恢复,多写一秒多一分不可逆);判断删的是配置(可重建)还是数据(须恢复);有备份走备份,先恢复到临时目录校验再切回生产;K8s 场景资源误删用 kubectl apply 从 YAML 秒级重建——配置 git 化的价值就在此刻。预防五条:高危命令二次确认、脚本路径先 echo 再执行、日常不用 root、可重建资源进版本库、3-2-1 备份(3 份数据 2 种介质 1 份异地)加恢复演练。

面试讲法(合并版,约 300 字): 两块分开讲。容器磁盘:告警但业务数据和系统日志都不大时,往容器的"地盘"查——docker system df 统计发现悬空镜像和废弃层堆了几十 G(反复构建没清理的环境常见);再看 /var/log/containers 的 json 日志,一个调试期容器写出了几个 G——默认日志驱动没有上限。处理 prune 清理加日志配 max-size/max-file 上限,并把"日志上限是运行时标准配置"前置到部署期。误删应急:我不讲"我删过库"——讲体系和顺序:万一发生,先停写入(数据块被覆盖前可恢复)、再分配置还是数据定路径、有备份走备份且先校验再切回;我的三层保障是 etcd 快照、云盘快照、crontab 备份加异机传输,YAML 全部 git 化——误删资源从小时级变成分钟级 kubectl apply。收尾一句:备份的价值不在备了,在于验证过能恢复。

14.17 Secret 空值致接口报错(话术案例) 【经典故障】 ​

场景:新环境部署完,前端正常,后端调隔壁部门鉴权接口必报错——Pod 全 Running,表面无异常。

排查(讲解性叙述): 层层回退的典型:第一层 get pods 全 Running——第一个陷阱:Pod 状态健康不等于业务健康;第二层后端日志调鉴权全报错——问题在下游;第三层鉴权侧发现收到的入参是空的——问题回到我方;第四层进 Pod 看 Secret 文件——文件在、内容是空的——问题在初始化;第五层初始化脚本日志早提示过"创建出来但内容为空",被异常处理吞掉。最终根因:随机密码撞上反斜杠被转义吃掉一位,密码缺位校验失败;另一环境没事纯粹是随机数没生成反斜杠——概率型故障。

根因:特殊字符转义丢位 + 脚本静默吞错,两层叠加。 解决:字符集剔除易错字符;脚本"失败必须大声失败";随机值功能全字符集回归。 预防:Pod Running 不等于配置正确——挂载内容要 cat 验证;概率型故障最考验把排查链走到底的耐心。

面试讲法(STAR 完整版,约 250 字): "我处理过类似的"口径,用来展示排查耐心。现象迷惑:前端正常、唯独调鉴权报错,Pod 全 Running。我层层回退:Pod 健康是第一个假象;后端日志指向下游;鉴权侧发现入参为空又指回我方;进 Pod 看挂载的 Secret 文件——内容是空的;初始化脚本日志里其实早提示过,被吞掉了。根因是随机密码撞上反斜杠转义丢位——另一个环境没出事纯粹因为随机数没撞上,概率型故障。修复三件事:剔除易错字符、脚本失败显式退出、全字符集回归。两个收获:Pod Running 不等于业务健康;概率型故障最考验不提前下结论的耐心。


14.18 面试官最爱追问的 8 个通用问题(案例章必背) ​

  1. "讲一个你印象最深的故障" → 实施岗首选 14.2 割接回滚(决策与担当)或 14.7 证书 SAN(技术含量);技术面选 14.7,行为面选 14.2 或 14.8(license 双主)。
  2. "客户现场出问题,你先做什么?" → 先止损加稳客户:恢复优先、通报干系人、给客户预期;绝不业务陪着排查。
  3. "你怎么定位根因的?" → 三板斧:监控曲线、日志证据、变更记录("最近改了什么");实施场景加"环境对照"(好环境 vs 坏环境差异对比)。
  4. "这次故障你的责任是什么?" → 主动担责加讲改进(把坑变成检查项/规范/清单)——14.8 的答法是范本。
  5. "怎么保证不再发生?" → 复盘四件套:根因改进、监控补盲、流程固化(SOP/检查清单)、演练验证——我的 9 项避坑清单就是批量沉淀的产物。
  6. "多久恢复的?影响多大?" → 讲时间线(发现→止损→恢复→根因确认),数字克制可信,不虚报。
  7. "当时没有备份怎么办?" → 如实答止损手段(停写入、找残留、降级运行),再讲事后补齐的备份体系——考的是应急思维。
  8. "这些都是你一个人处理的吗?" → 一线我处理、疑难按"转案四件套"协同原厂(14.5);客户现场我主导向上汇报——协同口径真实且加分。

14.19 章末自测清单(快问快答) ​

  1. 故障处理第一优先级? → 止损恢复业务;实施场景还要同步稳住客户、给预期。
  2. 实施场景定位的第四板斧? → 环境对照——同样的事在能跑与不能跑的环境做差异对比。
  3. exec format error 根因与第一条命令? → 镜像/二进制架构与节点不匹配;docker inspect | grep Architecture。
  4. 编译缺 .so 的解法? → yum provides 反查属于哪个包,从 aarch64 源补 devel 包。
  5. 割接回退的决策规则? → 关键项失败且窗口内无法稳妥修复即回退;回退是预案组成部分。
  6. 客户访问不通的分层数学题? → 自证监听(0.0.0.0)→ 客户侧 ping/telnet → 二分收敛到端口层 → 查 VLAN/安全组。
  7. 培训冷场的处理? → 判断原因(听不懂/不相关/疲劳)→ 降维/换场景/换形式,现场演示最有效;实操占一半。
  8. 转案四件套? → 现象描述、环境信息(版本配套+变更)、证据包、我的判断(已排除什么怀疑什么)。
  9. NotReady 第一排查点? → CNI Pod 状态,90% 是镜像拉取失败。
  10. 证书 SAN 三步? → 补 certSANs → 移走旧证书重签 → SAN 回写配置。
  11. license 替换的教训? → 集群类操作分批加观察:先一个节点就绪确认后再另一个。
  12. OOM 第一证据命令? → dmesg -T | grep -i "out of memory"。
  13. df -h 没满但报 no space? → df -i 查 inode;rm 了不降查 lsof | grep deleted 用 truncate。
  14. 502 和 504 一句话? → 502 连不上(挂了),504 连上但超时(慢)。
  15. 认证时好时坏先查什么? → 节点时间同步(timedatectl/chronyc)。
  16. 脑裂确认命令与四招预防? → 两台 ip addr 都绑 VIP;检测真实端口、priority 拉开、通告链路保障、上线演练。
  17. CrashLoop 三步? → describe 看事件 → logs --previous → 退出码分方向(137=OOM)。
  18. 容器磁盘两大凶手? → 悬空镜像层堆积 + json-file 日志无 max-size。
  19. 误删第一分钟动作? → 停服务停止写入,再分配置/数据定恢复路径。
  20. 备份的终极原则? → 3-2-1 加恢复演练——没验证过恢复的备份等于没有。
  21. Pod Running 说明业务正常吗? → 不——Secret 空值案例:挂载内容要 cat 验证。

14.20 本章使用红线(面试前再读一遍) ​

  1. 来源口径不混:【真实项目】案例(ARM 踩坑、割接回滚、现场网络、培训、原厂协同、NotReady、证书 SAN、license、时间同步)放开讲细节;【经典故障】用"我处理过类似的"口径;【课程项目】主动说明——讲错口径比讲不出更伤。
  2. 实施岗的第一句话升级版:先止损、稳客户、再定位、后复盘——四个词按这个顺序说,面试官立刻知道你有现场经验。
  3. 命令要讲"为什么":每条命令都能说出"我用它排除/确认了什么"——只报名词不讲判断依据等于背书。
  4. 数字克制:恢复时长、影响面只讲有把握的数——追一句"这个数字怎么统计的"就露馅。
  5. 复盘收尾落在"沉淀":检查项、规范、告警、清单、手册章节——实施版故障故事的结尾永远是"这个问题后来变成了什么资产"。