华为云 CCE 实战:集群与节点池规划、资源 requests/limits、健康探针与弹性伸缩避坑指南
前言
把应用迁到 Kubernetes 之后,很多团队发现"能跑起来"和"跑得稳"之间差了很远:Pod 被 OOMKilled、发布时短暂 502、流量高峰扩容跟不上、节点资源明明很空却调度失败。华为云云容器引擎 CCE 把控制面托管了,但工作负载怎么配置仍然要自己负责。本文按照从集群规划到上线检查的顺序,整理一些实践中容易踩的坑,具体功能和参数以 CCE 官方文档和控制台为准。
一、集群与网络规划:先想清楚,后期很难改
- 容器网络模型:CCE 通常提供容器隧道网络、VPC 网络、云原生网络(CCE Turbo)等模型。它们在性能、Pod 能否直接被 VPC 内访问、规模上限方面各不相同,创建集群时选定后基本无法变更,要提前结合业务规模和是否需要 Pod 直通 ELB 来选。
- 网段不要重叠:VPC 网段、容器网段、Service 网段三者不能冲突,还要考虑将来与其他 VPC 对等连接、与 IDC 打通时的地址规划。容器网段要按"最大节点数 × 每节点 Pod 数"留足余量。
- 控制面高可用:生产集群建议选择多控制节点(高可用)规格,并让节点分布在多个可用区。
二、节点池:按负载特征分组
不要把所有业务都塞进一个节点池。比较常见的分法是:通用无状态业务一个池、有状态/IO 敏感业务一个池、需要 GPU 或大内存的业务单独一个池。每个池可以设置不同的规格、标签和污点,再通过 nodeSelector、nodeAffinity 和容忍度把 Pod 调度到合适的池里。
节点池的好处还体现在运维上:升级、扩缩容、修改内核参数都可以按池进行,影响范围可控。节点的系统参数(如 conntrack、文件句柄上限)建议通过节点池的初始化配置统一设置,而不是登录节点手工改,否则节点重建后配置就丢了。
三、requests 与 limits:最容易配错的两个字段
- requests 决定调度:调度器只看 requests 来判断节点能否放下这个 Pod。requests 设得太大,节点"看起来满了"但实际利用率很低;设得太小,节点被超卖,高峰期互相抢资源。
- limits 决定上限:内存超过 limits 会被 OOMKilled;CPU 超过 limits 会被限流(throttling),表现为接口时延突然变高,但进程不会被杀,很难察觉。
- 经验做法:先不加 CPU limits 或者设得宽松,观察一到两周的实际用量,把 requests 设在 P90~P95 左右;内存 limits 一定要设,并与 requests 接近,避免节点内存被挤爆导致驱逐。
- JVM 等运行时要感知容器限制:Java 应用建议使用 -XX:MaxRAMPercentage 而不是写死 -Xmx,并给堆外内存留出空间,否则容易出现"堆没满却被 OOMKilled"。
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
memory: "1Gi"
四、三种探针各司其职
- livenessProbe(存活):失败会重启容器。只应检查进程自身是否卡死,不要在里面检查数据库、下游服务,否则下游一抖,所有 Pod 一起重启,故障被放大。
- readinessProbe(就绪):失败会把 Pod 从 Service 的后端中摘除,但不重启。适合检查"现在能不能接流量",比如缓存是否预热完成。
- startupProbe(启动):针对启动慢的应用,在启动探针成功之前,存活探针不会生效,避免应用还没起来就被反复重启。
探针的超时和阈值要留余量:timeoutSeconds 默认只有 1 秒,GC 停顿或高负载时很容易误判。
五、弹性伸缩:HPA 与节点伸缩要配合
工作负载层面用 HPA 按 CPU、内存或自定义指标扩缩 Pod 数;集群层面用节点自动伸缩(CCE 的 autoscaler 插件)在 Pod 因资源不足 Pending 时扩节点。几个注意点:
- HPA 基于 requests 计算使用率,requests 没设或设得不合理,HPA 就会失真;
- 节点扩容需要分钟级时间,突发流量场景要预留一定冗余,或者结合定时伸缩策略在高峰前提前扩容;
- 配置缩容稳定窗口(behavior.scaleDown),避免指标抖动导致频繁扩缩;
- 为关键业务设置 PodDisruptionBudget,防止节点缩容时一次驱逐过多副本。
六、优雅下线与滚动发布
发布时出现短暂 502,多数是因为 Pod 已经开始退出,但 ELB 或 kube-proxy 还在往它转发流量。常见做法:
- 在容器里加 preStop 钩子 sleep 几秒,等端点摘除传播完成再停止进程;
- 应用正确处理 SIGTERM,停止接新请求、处理完存量请求后退出,terminationGracePeriodSeconds 要大于 preStop 加业务收尾的时间;
- 滚动更新设置 maxUnavailable: 0、maxSurge: 1 或按比例,保证发布过程中可用副本数不下降;
- 副本用 podAntiAffinity 或 topologySpreadConstraints 打散到不同节点和可用区,避免单节点故障带走全部副本。
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
terminationGracePeriodSeconds: 40
七、可观测性与镜像
- 开启容器日志采集和监控插件,至少关注节点 CPU/内存/磁盘、Pod 重启次数、OOMKilled 事件、Pending 时长;
- 镜像放在容器镜像服务 SWR 中,使用固定版本号的 tag 而不是 latest,便于回滚和审计;
- 定期清理节点上的无用镜像,防止磁盘写满触发驱逐。
八、上线前检查清单
- 网络模型、三个网段已规划,留有扩展余量;
- 节点池按负载分组,节点系统参数通过初始化配置统一设置;
- 每个容器都设置了 requests 和内存 limits,并基于实测数据调整过;
- 存活、就绪、启动探针职责清晰,存活探针不依赖下游;
- HPA、节点伸缩、PDB 已配置并做过压测验证;
- preStop 与优雅退出已验证,滚动发布过程中无报错;
- 副本跨节点、跨可用区打散,监控告警和日志采集已接入。
结语
CCE 托管了控制面和大量运维工作,但"稳定性"最终取决于工作负载本身的配置。把资源、探针、伸缩、下线这几个环节逐项对照检查,绝大多数线上问题可以在上线前被发现。欢迎在评论区交流你们在 CCE 使用中遇到的问题和经验。
- 点赞
- 收藏
- 关注作者
评论(0)