华为云 CCE 集群节点池扩缩容实战:从一个被驱逐的 Pod 说起
华为云 CCE 集群节点池扩缩容实战:从一个被驱逐的 Pod 说起
上周我们的测试环境在午高峰做了一次节点池扩容,规格从通用型 4c8g 换成了 8c16g。控制台点完"确认变更",扩出来的机器十分钟后就绪了,我以为事情到此为止。第二天早上打开看板,业务批处理任务大面积超时,日志里铺满了 `pod was evicted` 和 `The node was low on resource: ephemeral-storage`。
后来复盘才明白,那次驱逐不是偶然:8c16g 的节点默认挂载的系统盘只有 40G,而我们这个镜像层拉下来就有 30G,加上容器日志没有配置轮转,单节点在三天内就把 ephemeral-storage 吃满了。CCE 的驱逐机制在资源不足时按优先级挑选牺牲者,这条链路本身工作正常,只是我在扩机器时只关注了"算力够不够",忽略了节点层面的隐性资源。
这次之后我们重新梳理了一遍节点池的生命周期管理,把踩过的坑整理出来。
一、扩缩容前必须先算清楚三类资源
很多人把节点池扩容理解成"买更大的机器",但真正容易被忽略的是那些不在规格表里的资源。
第一类是临时存储(ephemeral-storage)。它在云主机规格表里根本看不到,却是 K8s 节点调度的硬约束。镜像体积大、容器日志不轮转、或大量使用 emptyDir 的任务,都会吃掉它。我们的做法是在 workload 里显式声明 `resources.limits.ephemeral-storage`,并在日志配置里加上 `maxSize: 100Mi` 的轮转上限。
第二类是 Pod 数量密度。扩容后调度器把 Pod 铺到新节点,若单节点 Pod 上限配得太高,节点上的容器会互相抢 CPU,导致"机器很闲但业务很慢"的假象。我们把单节点最大 Pod 数从 110 调到 64 后,P99 延迟稳定下降。
第三类是镜像拉取带宽。一批新节点同时起来拉同一个大镜像,节点池会卡在 ContainerCreating 阶段。我们在节点池里配置了镜像预热策略,让调度器在节点可用前就把基础镜像拉好。
二、节点池变更的灰度节奏
直接在生产节点池上做变更的风险在于:一次操作同时影响所有节点,且不可回滚。
我们现在的做法是把节点池变更拆成"滚动替换"而不是"就地扩缩",并且严格控制每批的替换比例。配置上先设 20% 的单批比例,观察一轮业务指标再继续。这期间最关键的是监控要跟上——我们用 CCE 的集群事件和自定义监控指标同时盯着三个信号:节点池 Ready 节点数、驱逐事件计数、以及节点磁盘使用率。
有一次我们配置了 50% 的单批比例,替换进行到一半时磁盘告警集中爆发,因为新节点的可用区规格和旧节点不一致,导致部分有状态服务被重新调度到新节点并触发数据重平衡。从那之后单批比例再没超过过 20%。
三、驱逐事件的排查路径
驱逐事件是节点层问题的"果",真正要定位的是"因"。我们沉淀下来的排查顺序是:
先看事件来源,确认是 `Evicted` 事件而不是 `Killing` 或 `Preempted`——前者说明节点资源不足,后者往往涉及亲和性或调度约束。确认后去节点上看 `df -h` 和 `du -sh /var/lib/containerd`,如果磁盘水位高,那基本就是临时存储的问题。
如果磁盘水位正常,就要转去检查内存。节点内存不足时的表现和磁盘不一样,通常会伴随节点 NotReady 状态,而不是单纯的驱逐。
最后还有一类容易被忽略的驱逐原因:节点被云平台侧的运维动作回收,或者包年包月节点到期释放。这种情况在事件里会带上云厂商的回收标记,需要去云控制台核对。
四、把经验固化成准入检查
光靠人记这些显然不现实。我们做了一张节点池变更检查表,放在变更工单模板里,每次扩容前必须逐项确认:临时存储上限是否声明、日志是否配置轮转、单批替换比例是否超过 20%、监控告警是否覆盖磁盘水位。
检查表上线后,临时存储相关的问题基本清零。剩下的偶发驱逐大多是业务侧新增了新的临时文件写入点——这种情况检查表反而能第一时间暴露出来,因为它会要求重新评估存储水位。
写在最后,CCE 提供了不少开箱即用的能力——弹性伸缩、集群事件、拓扑视图——但它们解决的是"怎么把事情做完",而不是"怎么做对"。运维的门槛往往不在操作难度,而在对资源模型的认知深度上。把节点当成一台有四个维度资源的机器来理解,很多 puzzling 的问题就会变得理所当然。
- 点赞
- 收藏
- 关注作者
评论(0)