【百度云原生导读】随着Kubernetes(以下简称『K8S』)被业界越来越广泛地使用,单个集群规模也逐渐增大,很多人都会发现自己维护的 K8S 集群普遍存在一个问题:分配率较高,而利用率偏低。
比如,一个有1000+节点的集群,在分配率达到80%后,常常会因为集群碎片的原因,很多大规格的 Pod 就无法再被创建出来。而与此同时,整个集群的日均 CPU 利用率却不足15%,常态使用率偏低。那么,如何才能把剩余的闲置资源尽可能利用到极致呢?
今天这篇文章,是百度云原生团队分享云原生混部实战的第一弹,我们一起探索 K8S 原理,用 K8S 原生的方式来解决这个问题。
1. 原生 K8S 能否解决资源利用率问题?
首先,我们来看下图这个示例。图中黄色框代表2个 Node,这两个 Node 的 CPU 总数都是40核,并且都已经分配了38核。其中 NodeA 的真实用量是35核,NodeB 的真实用量是10核。而蓝色框则代表现在我们还有3个待调度的 Pod。
若想调度3个 Pod:
-
PodA 的 Request 和 Limit 都是5c,此时它无法被调度,即使Node B上还有空闲资源;
-
PodB 的 Request 为1c,Limit 为10c,该 Pod 超发比较严重,它可以被调度到 NodeA 或 NodeB,但是调度到 NodeA 时可能被驱逐;
-
PodC 的 Request 和 Limit 都没有填写,此时它可以被调度,但是当调度到 NodeA 时可能被驱逐
基于以上场景,可以尝试总结一下为什么原生 K8S 没办法直接解决资源利用率的问题:
第一,资源使用是动态的,而配额是静态限制。在线业务会根据其使用的峰值去预估Quota(Request和Limit),配额申请之后就不能再修改,但资源用量却是动态的,白天和晚上的用量可能都不一样。
第二,原生调度器并不感知真实资源的使用情况。所以对于 PodB,PodC 这种想要超发的业务来说,无法做到合理的配置。
基于这些原因,团队进行了下一阶段的方案设计:引入动态资源视图
2. 引入动态资源视图
通过添加一个 Agent 去收集单机的资源用量情况,并且汇总计算得到动态的资源视图(机器真实的用量情况),将其上报到调度器,在调度器中配置相关策略,可以将上文中提到的 PodB 和 PodC 准确的调度到 NodeB 上。
也就是说通过构建资源视图,可以将 Limit 大于 Request 的 Pod 或者没填 Request 和Limit 的 Pod,调用到真实用量更少的 Node。这个方法可以解决由于不知道机器到底用了多少资源,所以调度失败被驱逐的问题,最终达到提升 CPU 利用率的效果。
但是这样做需要付出什么代价?如果要将 PodB 和 PodC 调度到 NodeB 上,NodeB 的配额只多分配了1核,但是用量却上升了20核,这就造成了超量使用。(申请量非常少