写点什么

java 程序员应该知道的 k8s 容器资源申请攻略

  • 2023-08-18
    北京
  • 本文字数:1645 字

    阅读完需:约 5 分钟

省流版:非核心应用 cpu 2c,核心应用多申请;jdk 选择 8u191 版本以上。


k8s 已经是如今云计算的事实标准。


如今云计算发展迅猛,大多数的程序不是部署在阿里云、腾讯云或者 AWS 之类的共有云,就是部署在公司内部的私有云上,而这些云都是基于 k8s 来打造的。


虽然 k8s 有专门的运营人员来管理,但是广大的 java 程序才是 k8s 的最终使用用户。学好 k8s,能够帮助我们在云上更好得使用 java,从而更轻松工作。


正如本文标题,本文介绍的是 k8s request limit,这是涉及 k8s 资源分配的关键参数.

k8s 容器调度

k8s 是资源调度系统,当有部署需求时,它会从所管理的一堆机器中,跳出来一部分符合条件的机器来部署对应的容器。k8s 中使用 request 和 limit 来描述一个容器所需要的资源。


request : 满足容器启动的最小资源需求。


limit : 容器可以使用的最大资源。


比如,一个容器的内存 request 是 200MB,limit 是 300MB,那么就会被分配到一台至少有 200MB 空闲内存的机器上,同时当它使用内存超过 300MB 时,将其 kill。


上面说完了资源描述方式,接下来说一下资源,资源可以分为可压缩资源和不可压缩资源。


可压缩资源:cpu、带宽不可压缩资源:内存、硬盘


可压缩资源,指资源不够的时候,也还能运行,但是会慢一些;cpu 和带宽都属于这一类。


不可压缩资源,指资源不够时,就无法运行。内存不够了,就会触发系统的 oom kiil。

云计算中的超卖

即便我们已经警告过用户了,用户依然会成倍的申请得资源。 -- google 云计算副总裁


新增的所有算力,都会被浪费。


因为用户总是想用尽可能多的资源来保障服务质量,所以现实中,大多数集群都是超额申请资源,同时资源使用率非常低。


从而导致资源有巨大的浪费。比如,一台物理机器,40c,老实人做法:只分配 40c 的资源,比如 4c * 10. 结果物理机的 cpu 使用率只有 5%.造成了大量的浪费


结合实际应用使用率的现状,为了提升整体资源的使用率,云平台就出现了超卖现象。


比如在一个 40c 的机器上,分配超过 40c 的容器,比如 80c,甚至 400c。


cpu 是容易被超卖的资源,常见的超卖倍数:2~10 倍,而内存/硬盘则不太容易,超卖风险太高,一般超卖比例在 0-10%.

cpu 限流问题

k8s 中使用 cfs 算法进行 cpu 调度,该算法每 100ms 调度一次 cpu,如果应用恰好在这 100ms 有徒增的 cpu 需求,超过了设定的 limit,就会触发 cpu 限流,导致应用在 100ms 剩下的时间内无 cpu 可用,从而导致应用 rt 上涨,出现超时。


如图所示,图中 cpu 使用率最高才 60%左右,但是依然出现了很多的 cpu 限流时间。


因为调度周期是 100ms,而传统监控工具采集数据间隔往往是秒级甚至分钟级,所以从 cpu 使用率监控上很难发现是否存在 cpu 限流,最好的解决办法是结合容器的限速时间指标来分析来分析,如果服务指标不满足 slo 同时出现大量 cpu 限流时间,则可以尝试增大 cpu 来避免出现 cpu 限流问题。

java 应用在 k8s 上部署的建议

基于上述提到的问题,同时加上 java 语言非常早,不像 go 之类的语言和云适配器非常好,所以需要我们手动干预,来使 java 和云更亲和。


版本:选择 jdk8u191 以上的版本,因为从这个版本开始,jvm 才能读取到容器正确的 cpu 核数,之前的版本会读取到物理机的核心数;


cpu :


  • 核心低延迟/cpu 密集应用设置足量的 cpu 来避免 cpu 限流。

  • 非核心应用建议 2 个 cpu 起步,因为 jvm 识别到系统为 1cpu 时,会做一些串行化的设置,比如启用 SerialGC.


内存:


  • 保持容器内存使用率接近 70~80%,避免浪费,毕竟这是不可压缩资源,浪费了内存就是浪费了真金白银。

  • 设置 heap 大小上限以及 non-heap 大小上限,防止应用使用了超过 limit 的内存,导致被 kill。如果没有设置上限,同时使用了低于 8u191 的版本,jvm 将会读取到物理机的内存,自动将 heap 的最大值设置为物理机内存的 1/4,比如物理机为 128g,那么 jvm 相当于-Xmx32g 。heap 上限可以使用-Xmx 设置,non-heap 可以使用-MaxMetaSpaceSize(jdk8+) 或者 -MaxPermGenSize(jdk6-7)


我们曾经线上一台机器的 jvm 参数是"-Xms4g -Xms4g", 实际它的堆上限是 32g,相当于一个定时炸弹运行在线上。

总结

  • 应用部署:

  • jdk 版本:8u191+

  • cpu : 普通应用 2c;cpu 密集/核心低延迟服务,尽量多,直到满足 slo。

  • 内存:使用率 70~80%,


发布于: 刚刚阅读数: 7
用户头像

公众号:摸鱼编程 学习事半功倍的编程技巧 2018-05-27 加入

我是小亢,现某大厂架构师,专注提供java、jvm、架构、finops领域知识。

评论

发布
暂无评论
java程序员应该知道的k8s容器资源申请攻略_Java_你头顶的那片星空_InfoQ写作社区