kube-apiserver 频繁 OOM:一次控制面内存治理记录

举报
yd_275379215 发表于 2026/10/31 08:15:04 2026/10/31
【摘要】 K8s用了两年多,控制面一直相安无事,直到某天凌晨apiserver容器重启了三次。告警里OOMKilled字样很扎眼,3.4G的内存上限被吃穿了。先看指标。Grafana里apiserver的内存曲线是一条缓慢上涨的斜线,重启后回落,几小时后再爬上去,典型的缓存膨胀问题。用metrics接口排查各资源对象数量:kubectlget--raw/metrics|grepapiserver_st...

K8s 用了两年多,控制面一直相安无事,直到某天凌晨 apiserver 容器重启了三次。告警里 OOMKilled 字样很扎眼,3.4G 的内存上限被吃穿了。

先看指标。Grafana 里 apiserver 的内存曲线是一条缓慢上涨的斜线,重启后回落,几小时后再爬上去,典型的缓存膨胀问题。用 metrics 接口排查各资源对象数量:

kubectl get --raw /metrics | grep apiserver_storage_objects | sort -t' ' -k2 -rn | head

发现某业务团队把 CronJob 当定时任务仓库用,建了 8000 多个,加上历史遗留的 EndpointSlice,存储对象总数超过 3 万。apiserver 对每种资源的 watch 缓存都吃内存,对象一多就顶不住了。

处理方式比较克制:先删掉废弃的 CronJob,etcd 做历史压缩;再给 apiserver 调整参数:

# static pod manifest 里调整
--max-requests-inflight=800      # 请求并发上限,默认 400
--max-mutating-requests-inflight=400
--watch-cache-size=200           # watch 缓存,资源多时适当放大

改完内存稳定在 1.8G 左右,再没重启过。

事后补了两件事:一是给 apiserver 加了内存使用率 75% 的预警,不再等 OOM 才知道;二是写了个每周统计脚本,按 namespace 汇总对象数量,异常增长直接通知负责人。第二周就抓到一个团队用脚本批量建 Secret 没清理,一周堆了 4000 个。

控制面的问题往往不是高可用没做好,而是没人盯着它慢慢变坏。资源对象的规模和集群内存水位,值得在大盘上单独留两个面板。

工单系统里给控制面也建了专属看板:apiserver 内存、请求延迟分位数、watch 数、etcd 提交延迟四个曲线并排,一眼扫完。后来 etcd 的磁盘延迟也加了进来,因为它才是很多控制面慢的源头,存储抖动时 etcd 提交变慢,apiserver 跟着堆积,这条传导链看多了就熟了。

事后我们把控制面容量做成了容量规划的一部分。经验公式很简单:每五万个 API 对象,apiserver 预留 1G 内存,再按 watch 数量加一成缓冲;etcd 的数据库默认配额 2G,超过七成就该压缩和整理碎片了。另一个容易被忽略的点是 apiserver 的请求延迟指标,P99 超过一秒往往不是机器不行,而是某个客户端在全量 list 大对象,审计日志里按客户端聚合就能揪出来。控制面不像业务节点出了事立刻报警,它更像慢性病,定期体检比抢救有效,建议至少每月看一次对象规模和内存趋势。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。