目录标题
- 📘 Linux CPU iowait 高 & K8s + overlayfs 排查笔记
- 1️⃣ 基础原理
- CPU iowait 本质
- load average 与 iowait关系
- 2️⃣ K8s + overlayfs 场景下 iowait 高典型链条
- 关键理解
- 3️⃣ 指标解读
- 4️⃣ 排查路径(实战版)
- 0️⃣ CPU 层
- 1️⃣ 进程层
- 2️⃣ block 层
- 3️⃣ 文件系统层(overlayfs + XFS / ext4)
- 4️⃣ device 层(最后一刀)
- 5️⃣ 实战口诀
- 6️⃣ 事故报告模板
- 7️⃣ 可视化图示
- 🚑 iowait 高 · 现场速查表
- 0️⃣ 一眼判断(先别敲命令)
- 1️⃣ CPU 层(只看 30 秒)
- 看什么
- 命令
- 结论
- 2️⃣ 进程层(铁证)
- 看什么
- 命令
- 结论
- 3️⃣ block 层(分水岭)
- 核心命令
- 只盯 3 个指标
- 经验阈值(重要)
- 4️⃣ fs 层(K8s 核心杀点)
- 关键角色
- 看什么
- 命令
- 一旦命中,直接下结论
- 5️⃣ device 层(最后才看)
- 什么时候看?
- 命令
- 关注点
- 6️⃣ K8s + overlayfs 专属「断案公式」
- 只要同时满足三点:
- 7️⃣ 一句话专家级总结(背下来)
- 8️⃣ 排查顺序(千万别反)
- 9️⃣ 最容易踩的 5 个坑
- 🧨 K8s I/O 排雷设计清单(工程版)
- 一句话设计总原则(先记住)
- 1️⃣ 应用 / 数据层设计(最重要)
- ❌ 禁止场景(高危)
- ✅ 正确做法(必须)
- 数据目录直挂 volume(绕开 overlayfs)
- 2️⃣ 容器文件系统设计
- overlayfs 该干什么?
- 日志设计(非常关键)
- ❌ 高危
- ✅ 正确
- 3️⃣ K8s 存储选型排雷
- local vs 网络盘
- emptyDir 的坑
- 4️⃣ Node 级别文件系统设计
- XFS 推荐参数(生产)
- mount 参数建议
- 5️⃣ block 层设计(容易被忽略)
- 队列深度要配得上写入模型
- 6️⃣ 数据库容器化专项排雷
- 必须满足的 5 条铁律
- 7️⃣ 监控 & 预警设计(提前拦截)
- 必须监控的 3 个指标
- 8️⃣ 一句话设计总结(终极版)
- 9️⃣ 你现在已经具备的能力
📘 Linux CPU iowait 高 & K8s + overlayfs 排查笔记
1️⃣ 基础原理
CPU iowait 本质
定义:CPU 空闲状态下,存在未完成 I/O 请求的等待时间。
关键点:
- CPU并未在忙计算,只是在 idle 状态等待 I/O 返回。
- 高 iowait≠ CPU 繁忙。
- iowait 高往往伴随进程大量 D 状态。
load average 与 iowait关系
- load = R 状态(可运行) + D 状态(不可中断睡眠)
- D 状态堆积 → load 升高 → iowait 升高
- ⚠️ 误区:load 高 ≠ CPU 算力不足
2️⃣ K8s + overlayfs 场景下 iowait 高典型链条
上游写请求 (应用 / 数据库) ↓ overlayfs copy-up ↓ 文件系统元数据 / 日志写 (XFS: xfsaild, ext4: jbd2) ↓ block 层队列堆积 (aqu-sz 高) ↓ CPU iowait ↑ ↓ 进程 D 状态增加 ↓ kubelet 超时 ↓ Pod 容器阻塞 / 服务不可用关键理解
xfsaild / jbd2:负责 fs 日志与元数据提交,是“写路径后台线程”。
- 高 iowait + D 状态时,它们通常在阻塞,导致整个文件系统写路径阻塞。
aqu-sz:block 层 I/O 队列深度。
- 高 aqu-sz = 上游写入模型压垮设备队列,而不一定是磁盘慢。
3️⃣ 指标解读
| 指标 | 来源 | 含义 | 正常值 | 危险值 | |
|---|---|---|---|---|---|
| iowait | /proc/stat/ node_exporternode_cpu_seconds_total{mode="iowait"} | CPU 等待 I/O 的百分比 | < 5% | > 20% 持续时间长 | |
| load average | uptime/top | 运行队列 + D 状态队列平均 | < CPU 核心数 | > CPU 核心数 2x | |
| D 状态进程数 | `ps -eo pid,stat,comm | grep ’ D’` | 不可中断睡眠 | 0-少量 | > 10-20 或关键应用阻塞 |
| await | iostat -x | 每次 I/O 平均等待时间 | < 10ms | > 50ms 持续 | |
| aqu-sz | iostat -x或/sys/block/*/queue/ | I/O 队列深度 | < 1 | > 8-16 持续 | |
| %util | iostat -x | 设备繁忙度 | < 50% | > 80% |
4️⃣ 排查路径(实战版)
0️⃣ CPU 层
- 确认 CPU 是否真忙:
topmpstat -P ALL1- 判断依据:iowait 高,user/system 不高 → CPU 无罪
1️⃣ 进程层
- 确认 D 状态进程:
ps-eo pid,stat,comm|grep' D'- 结论:大量 D 状态 → I/O 阻塞已经发生
2️⃣ block 层
- 查看设备 I/O 延迟和队列:
iostat -x1cat/sys/block/dm-*/queue/nr_requests关注字段:
await:单次 I/O 平均等待时间aqu-sz:队列深度%util:设备利用率
3️⃣ 文件系统层(overlayfs + XFS / ext4)
- 识别元数据 / 日志写压力:
ps-eo pid,stat,comm|egrep'xfsaild|jbd2'特征:
- 队列阻塞
- 小文件写入放大
- overlayfs copy-up
- fs metadata/journal 写延迟
4️⃣ device 层(最后一刀)
- 检查存储设备健康及异常:
dmesg|egrep-i'error|timeout|reset'smartctl -a /dev/sdX multipath -ll判断依据:
- 设备是否出现物理问题
- RAID / SAN / NVMe 异常
5️⃣ 实战口诀
iowait 高 + D 多 + user/system 不高
→ 跳过 CPU / 应用,直接沿 block → fs → device 查
6️⃣ 事故报告模板
本次 CPU iowait 升高并非 CPU 算力瓶颈,而是由于容器环境下 overlayfs 叠加 XFS 文件系统,在高写入场景中触发元数据与日志写放大,导致 block I/O 阻塞。进程大量进入 D 状态,进一步推高 iowait 与 load average,最终引发 kubelet 超时与 Pod 不可用。
7️⃣ 可视化图示
- 图示文件:
/mnt/data/A_digital_diagram_illustrates_the_impact_of_overla.png - 描述:展示应用写请求 → overlayfs → XFS/jbd2 → block queue → CPU iowait → D 状态 → Pod 阻塞
- 功能:帮助快速理解 K8s + overlayfs 场景下 I/O 写放大链路
这份笔记已经涵盖了:
- 原理理解
- 指标解释
- 排查步骤(CPU → 进程 → block → fs → device)
- 命令实践
- 经验值参考
- 可直接用在事故分析的模板
- 图示辅助理解
好,那我给你一份「一页纸 · 现场速查表」。
目标只有一个:事故现场 3 分钟内定性,不走弯路。
你可以直接存成笔记 / Wiki / 事故手册。
🚑 iowait 高 · 现场速查表
(K8s + 容器 + overlayfs 专用)
0️⃣ 一眼判断(先别敲命令)
看到监控如果是:
- ✅
iowait ↑ - ✅
load ↑ - ❌
user + system 不高
👉结论先下:CPU 无罪,直接查 I/O
1️⃣ CPU 层(只看 30 秒)
看什么
- iowait 是否明显高
- us / sy 是否不高
命令
topmpstat -P ALL1结论
- iowait 高 + us/sy 低
→不要再看 CPU
🚫 常见误区
- 调 CPU limit / request
- 扩容 CPU
👉完全无效
2️⃣ 进程层(铁证)
看什么
大量进程
STAT = D是否包含:
- 数据库
- runc / containerd
- kubelet
- curl / bash
命令
ps-eo pid,stat,comm|grep' D'结论
- D 状态多
→I/O 已经 block,是“因”,不是果
3️⃣ block 层(分水岭)
核心命令
iostat -x1只盯 3 个指标
| 指标 | 看什么 |
|---|---|
| await | 单次 I/O 等多久 |
| aqu-sz | I/O 排队长度 |
| %util | 设备是否被打满 |
经验阈值(重要)
| aqu-sz | 判断 |
|---|---|
| < 1 | 正常 |
| 1 ~ 4 | 可接受 |
| 4 ~ 8 | 开始拥堵 |
| 8 ~ 16 | 明显异常 ⚠️ |
| > 16 | I/O 雪崩前夜 ❌ |
👉aqu-sz 高 = 上游写入模型压垮 block queue
🚫 常见误区
- 看到 await 高就说“磁盘慢”
👉不一定
4️⃣ fs 层(K8s 核心杀点)
关键角色
- XFS→
xfsaild - ext4→
jbd2
看什么
- 是否处于 D 状态
命令
ps-eo pid,stat,comm|egrep'xfsaild|jbd2'一旦命中,直接下结论
overlayfs + fs 元数据 / 日志写被卡住
典型伴随:
- df 没满
- 系统却“写不动”
- 所有容器一起卡
🚫 常见误区
- 查 SQL
- 查应用 Bug
👉都不是第一现场
5️⃣ device 层(最后才看)
什么时候看?
- fs 层确认有问题
- block 层已经排队
- 才看 device
命令
dmesg|egrep-i'error|timeout|reset'multipath -ll smartctl -a /dev/sdX关注点
- timeout / reset
- SAN / 云盘 latency 抖动
- RAID 重构
6️⃣ K8s + overlayfs 专属「断案公式」
只要同时满足三点:
iowait ↑xfsaild / jbd2 Daqu-sz ↑
👉99% 不是盘坏,是写放大
7️⃣ 一句话专家级总结(背下来)
CPU iowait 升高并非 CPU 算力瓶颈,而是容器环境下 overlayfs 叠加文件系统元数据与日志写放大,导致 block 层队列堆积(aqu-sz 升高),I/O 请求无法及时完成,引发进程大量进入 D 状态并最终影响 kubelet 与 Pod 稳定性。
8️⃣ 排查顺序(千万别反)
CPU(确认无罪) ↓ 进程 D 状态 ↓ block queue(aqu-sz) ↓ fs(xfsaild / jbd2) ↓ device(最后)9️⃣ 最容易踩的 5 个坑
- ❌ iowait 高就扩 CPU
- ❌ load 高就说算力不足
- ❌ 先查应用、SQL
- ❌ 不看 aqu-sz
- ❌ 不理解 overlayfs 写放大
如果你愿意,下一步我可以再帮你做一件“更工程化”的事:
👉把这套速查表升级成「设计规避清单」
(哪些场景不该用 overlayfs、DB 如何落盘、node 级别怎么拆)
你要「排雷设计版」还是「事故复盘模板版」?
好,这一步已经是从“会排障”升级到“会设计”了。
下面这份是《K8s + 容器 + overlayfs 的 I/O 排雷设计版》——目标只有一个:
让 iowait 事故“设计上就不可能发生”
🧨 K8s I/O 排雷设计清单(工程版)
一句话设计总原则(先记住)
overlayfs 只适合“读多写少、无状态”
数据库 / 高写入 = 必须绕开它
1️⃣ 应用 / 数据层设计(最重要)
❌ 禁止场景(高危)
| 场景 | 原因 |
|---|---|
| DB 数据目录在容器可写层 | copy-up + metadata 放大 |
| 大量小文件频繁写 | inode / dentry 爆炸 |
| fsync 频繁(数据库) | journal 压力极大 |
| WAL / redo 在 overlayfs | log force 雪崩 |
👉这些场景 = 必出 iowait
✅ 正确做法(必须)
数据目录直挂 volume(绕开 overlayfs)
volumeMounts:-name:datamountPath:/var/lib/postgresql底层推荐:
- local SSD
- 独立云盘
- 直通 NVMe
✔️ 目标:数据写入不经过 overlayfs
2️⃣ 容器文件系统设计
overlayfs 该干什么?
✅ 适合:
- 程序二进制
- 配置文件
- 只读依赖
❌ 不适合:
- DB data
- 日志
- 临时文件高频写
日志设计(非常关键)
❌ 高危
- 容器内写
/var/log - 应用自己 rotate
✅ 正确
- stdout / stderr
- Sidecar / daemon 收集
👉 避免log 文件的小写风暴
3️⃣ K8s 存储选型排雷
local vs 网络盘
| 场景 | 建议 |
|---|---|
| DB / 高写 | local SSD / 本地 NVMe |
| 一般有状态 | 独立云盘 |
| 临时缓存 | emptyDir + medium: Memory |
emptyDir 的坑
emptyDir:medium:""- 默认 = 走 node fs(overlayfs 下)
- 高频写 → 仍可能压 fs
👉 高频临时写建议:
emptyDir:medium:Memory4️⃣ Node 级别文件系统设计
XFS 推荐参数(生产)
mkfs.xfs -mreflink=0-nftype=1ftype=1:overlayfs 必须reflink=0:减少 copy-on-write
mount 参数建议
noatime,nodiratime,logbufs=8,logbsize=256k目的:
- 减少 metadata 写
- 减轻 xfsaild 压力
5️⃣ block 层设计(容易被忽略)
队列深度要配得上写入模型
cat/sys/block/nvme0n1/queue/nr_requests经验值:
- NVMe:128 ~ 1024
- 云盘:按厂商建议
🚫 队列太小
→ aqu-sz 很快堆满
→ iowait 爆炸
6️⃣ 数据库容器化专项排雷
必须满足的 5 条铁律
- 数据目录必须 volume
- WAL / redo独立目录
- fsync 策略明确
- 容器 rootfs 只读
- 禁止 DB 写 overlayfs
7️⃣ 监控 & 预警设计(提前拦截)
必须监控的 3 个指标
| 指标 | 告警 |
|---|---|
| CPU iowait | > 20% |
| aqu-sz | > 8 |
| D 状态进程数 | 持续增长 |
👉aqu-sz 是“雪崩前指标”
8️⃣ 一句话设计总结(终极版)
任何需要稳定写入延迟的业务,都不应依赖 overlayfs 的可写层。
在 K8s 中,overlayfs 是“运行时层”,而不是“数据层”。
9️⃣ 你现在已经具备的能力
到这里你已经能做到:
- 看 iowait 不再看 CPU
- 看 aqu-sz 就能预判雪崩
- 一眼识别 overlayfs 写放大
- 从设计上规避事故
这已经是SRE / 内核级排障思维,不是普通运维了。
如果你愿意,最后我可以帮你做一件“压轴”的事:
👉 把这套内容整理成一份
《K8s I/O 事故标准化设计 & 排查手册(企业版)》目录大纲
你要不要?