CentOS 7.9 迁移 Ubuntu 22.04 k8s cgroup v2问题 发表于 2025-06-25 | 分类于 k8s | 暂无评论 ### 一、案发现场:升级后的离奇“命案” 为了拥抱云原生未来,我们精心策划了这次大升级: • K8s版本: 升级到更高版本。 • 操作系统: 告别老将 CentOS 7.9,拥抱新锐 Ubuntu 22.04.4。 迁移过程本应丝滑,谁知部分 Java应用 刚踏上新集群的土地,就惨遭“毒手”!kubectl describe pod 揭示的死亡报告触目惊心: ```shell Last State: Terminated Reason: OOMKilled // 死于内存溢出! Exit Code: 137 // 典型的OOM退出码 ``` ### 二、紧急抢救:加内存,治标不治本! 面对 OOMKilled,第一反应很直接:内存不够?那就加! • 简单粗暴: 将 Pod 的 MEM Limits 从 2Gi 暴力提升到 8Gi。 • 结果: 应用... 居然真的启动了! (暂时松了一口气) BUT! 真的解决了吗?监控数据很快泼来冷水: 1. 资源消耗异常: CPU、内存、线程数统统飙高,远超正常运行的兄弟Pod。 2. 神秘磁盘写入: 更诡异的是,监控捕捉到异常的磁盘写入活动,连 strace 都追踪不到来源! 3. 成本飙升预警: 每个应用都靠狂吃资源续命?这成本谁扛得住?这绝不是长久之计! ### 三、抽丝剥茧:锁定“元凶”—— JVM 的认知偏差 关键线索指向了 JVM 对资源的认知。我们祭出神器 jcmd VM.flags,对比 正常Pod 和 异常Pod 的JVM参数: ```shell 健康宝宝 (2c2g Pod,参数合理) -XX:CICompilerCount=2 # 编译器线程数 ≈ CPU核数 -XX:InitialHeapSize=33554432 # 初始堆≈32MB -XX:MaxHeapSize=536870912 # 最大堆≈512MB (远小于2Gi限制) ... (其他参数略) ... 异常患者 (同样是2c2g Pod,参数“疯了”!) -XX:CICompilerCount=15 # 编译器线程数=15?! (远超2核) -XX:InitialHeapSize=2147483648 # 初始堆=2GB?! (直接吃满限制) -XX:MaxHeapSize=32210157568 # 最大堆≈30GB?! (做梦呢?) ... (其他参数略) ... ``` 真相大白! • 异常Pod里的JVM,完全无视了Pod的2c2g限制! • 它以为自己运行在一个拥有海量CPU和内存(几十GB!) 的土豪主机上! • 于是它“自信满满”地按照这个错误的认知去分配资源(超大堆、超多线程),结果瞬间触发 OOMKilled。 • 即使我们强塞给它8Gi内存,它也只是勉强启动,但运行效率低下且浪费资源(编译器线程15个抢2个核?不慢才怪!),神秘的磁盘写入也可能与此相关(比如频繁GC或交换)。 ### 四、真凶浮现:cgroup v2 的“水土不服” 为什么JVM会“看走眼”?根源在于新操作系统 Ubuntu 22.04 默认启用了 cgroup v2,而旧系统 CentOS 7.9 使用的是 cgroup v1。 • 关键点: 许多旧版/未更新的Java运行时 (JVM) 和依赖库,无法正确识别 cgroup v2 的资源限制! 它们还活在 cgroup v1 的世界观里。 • 悬疑点:部分应用 OK 的原因在于,设置了 JVM 参数Xmx等,可参考,京东技术「JVM线程和内存参数合理性设置 」https://cloud.tencent.com/developer/article/2317441 五、终极解决方案:两条明路 方案一:升级!拥抱 cgroup v2 (推荐,面向未来) Cgroup v2 简化了目录结构,支持了 Memory Qos。 确保你的 Java运行时 和 关键依赖库 升级到完全支持 cgroup v2 的版本: |运行时名称| 支持 cgroup v2 的最低版本| | ------------ | ------------ | | OpenJDK / HotSpot | JDK 8u372, 11.0.16, 15 及更高| |IBM Semeru Runtimes | 8.0.382.0, 11.0.20.0, 17.0.8.0 及更高| | IBM Java | 8.0.8.6 及更高| | uber-go/automaxprocs | v1.5.1 或更高(Go应用常用,用于设置GOMAXPROCS) | 方案二:回退!切回 cgroup v1 (临时/兼容性方案) 如果暂时无法升级所有应用,可以将Ubuntu节点切回 cgroup v1: 1. 确认当前cgroup版本: stat -fc %T /sys/fs/cgroup/ • 输出 cgroup2fs -> v2 • 输出 tmpfs -> v1 2. 修改 /etc/default/grub: 找到 GRUB_CMDLINE_LINUX 行,在引号内的参数末尾 添加: systemd.unified_cgroup_hierarchy=0 (例如:GRUB_CMDLINE_LINUX="...原有参数... systemd.unified_cgroup_hierarchy=0") 3. 更新配置并重启: sudo update-grub sudo reboot 4. 重启后验证: 再次运行 stat -fc %T /sys/fs/cgroup/ 应输出 tmpfs (v1)。 重要: 将此修改固化到你的主机装机模版中,确保新节点也是 v1。 转载自: >https://mp.weixin.qq.com/s/KTrNDaH2W6Js1CCsewkudw