java 程序员应该知道的 k8s 容器资源申请攻略
省流版:非核心应用 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%,
版权声明: 本文为 InfoQ 作者【你头顶的那片星空】的原创文章。
原文链接:【http://xie.infoq.cn/article/29b37d6a29e3b34225f384e76】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论