Kubernetes集群建设规划之work-node选型

内容提要:
    本系列文章意在讨论如何在理想状态下规划设计一个比较符合实际作业环境的Kubernetes集群。本篇文章主要讨论了以理性经济投入为约束的情况下在云资源池上构建Kubernetes集群时work-node节点主机的选型方式。

当创建一个Kubernetes集群时,首要的问题之一是:“应该使用什么规格的work-node、需要多少个这样规格的work-node?是应该采购一些上一代的高性能服务器,还是利用数据中心中闲置的几台老旧机器呢?”
Kubernetes集群可以被看作是将一组独立的节点抽象为一个大的“超级节点”。这个超级节点的总计算能力(包括CPU和内存)是所有组成节点的能力之和。
假设需要一个总计算能力为8个CPU核心和32 GB内存的集群。以下是两种可能存在的集群设计方式:
        Kubernetes集群建设规划之work-node选型_第1张图片
这两种方案都会得到相同算力的Kubernetes集群,新的问题是:哪种方案更好呢?
每个工作节点都是一个运行这kubelet(Kubernetes代理)的计算单元,kubelet是一个连接到控制平面的工具,用于将节点的当前状态与集群的状态同步。当Kubernetes-scheduler将一个Pod分配给特定的work-node时,会创建一个Binding对象并将其存储在etcd中。kubelet定期检查集群的状态,一旦它注意到将一个新分配的Pod分配给其节点,它就会开始下载Pod的规范并创建它。因而,通常将kubelet部署为SystemDeamon服务,并作为OS-Level的一部分运行。这也就意味着,并不是work-node上的算力资源都可被用于运行pod。只有扣除了OS-Level、Kubelet、驱逐阈值等对算力的消耗后,剩余的算力资源才能被用于运行pod。
在理想状态下,一个work-node上需要被扣除掉的算力一般是:
CPU[ 每个CPU核心是1000毫核的规格。]:第一个核心的6%。 后续核心的1%(最多2个核心的情况下)。 接下来的两个核心的0.5%(最多4个核心的情况下)。 四个核心以上的任何核心的0.25%。
Mem:前4GB内存的25%。 接下来的4GB内存的20%(最多8GB)。 接下来的8GB内存的10%(最多16GB)。 接下来的112GB内存的6%(最多128GB)。 超过128GB的任何内存的2%。
POD驱逐阈值:100MB。

假定一个运行某个pod需要消耗300毫核CPU资源和2GB Mem资源的算力,那么在一个规格为4C16G的work-node上可以运行多少个pod副本呢?
这个work-node需要扣除掉的算力为:
CPU:1st核心的6%;2nd核心的1%;3rd核心的0.5%;4th核心的0.5%
     总计需要扣除掉的CPU算力为1000×(6%+1%+0.5%+0.5%)=80毫核
     可用于运行pod的CPU算力为 4×1000-80=3920毫核
Mem:1st4GB的25%;2nd4GB的20%;closely8GB的10%
     总计需要扣除掉的Mem算力为 4GB×25%+4GB×20%+8GB×10%=2.6GB
     再扣除掉100MB的驱逐阈值
     可用于运行pod的Mem算力为 16GB-2.6GB-0.1GB=13.3GB
以CPU资源衡量pod的个数:3920÷300=13.06667
以Mem资源衡量pod的个数:13.3÷2=6.65
因此,这个4C16G的work-node上最多可运行6个规格为300毫核CPU资源和2GB Mem资源的pod。鉴于pod的不可分割性,这个8C/32G算力的Kubernetes集群最多可运行 6×2=12 个此规格的pod。
那么,在规格为2C/8G的work-node上最多可以运行多少个规格为00毫核CPU资源和2GB Mem资源的pod呢?
这个work-node需要扣除掉的算力为:
CPU:1st核心的6%;2nd核心的1%
     总计需要扣除掉的CPU算力为1000×(6%+1%)=70毫核
     可用于运行pod的CPU算力为 2×1000-80=1930毫核
Mem:1st4GB的25%;2nd4GB的20%
     总计需要扣除掉的Mem算力为 4GB×25%+4GB×20%=1.8GB
     再扣除掉100MB的驱逐阈值
     可用于运行pod的Mem算力为 8GB-1.8GB-0.1GB=6.1GB
以CPU资源衡量pod的个数:1930÷300=6.43333
以Mem资源衡量pod的个数:6.1÷2=3.5
因此,这个2C8G的work-node上最多可运行3个规格为300毫核CPU资源和2GB Mem资源的pod。鉴于pod的不可分割性,这个8C/32G算力的Kubernetes集群最多可运行 3×4=12 个此规格的pod。

接下来讨论在这两种集群假设方案下各有多少算力资源被浪费了。
在一个规格为4C16G的work-node上,被浪费掉的算力资源为:
CPU:3920-6×300=2120毫核
Mem:13.3-6×2=1.3 GB
那么这个Kubernetes集群中被浪费掉的算力资源为:
CPU:2120×2=4240毫核
Mem:1.3×2=2.6 GB

在一个规格为2C/8G的work-node上,被浪费掉的算力资源为:
CPU:1930-300×3=130毫核
Mem:6.1-2×3=0.1 GB
那么这个Kubernetes集群中被浪费掉的算力资源为:
CPU:130×4=520毫核
Mem:0.1×4=0.4 GB

因此,从算力资源是否被充分利用的角度讲,应该尽量选择和pod消耗资源相接近的work-node来承载目标pod。在实践中的可行做法是以pod的副本数量的三分之一的算力资源消耗为基准确立work-node的算力规格。这种情况下,当pod规模扩大是就意味着work-node的节点数量增加了,带来的问题就是Kubernetes API、Kubernetes控制平面会有很大的交互压力,还会给网络I/O带来很大的数据流量。解决这个新问题就意味着需要对当前Kubernetes集群的控制平面集群进行扩容了。这种情况,公有云环境下的Kubernetes集群极易遇到,这就要求公有云服务商提供Kubernetes集群自动伸缩功能、且具备Kubernetes-Master控制平面自动伸缩功能。
在考虑完硬件设备资源充分利用效率的问题后,我们还需要思考的问题是“在pod副本进行规模临时性扩张时,集群中work-node是否有足额的pod轮转资源?”因为pod副本数进行临时性扩张时,一般不会考虑对Kubernetes集群节点进行增加,除非是周期性的或者持续增长性的pod副本数扩张。这个问题就要求我们构建的Kubernetes集群能够在运行额定数量的pod之外提供一些可供额外数量的pod运行的算力资源。
假定我们需要一个总计算能力为8个CPU核心和32 GB内存的Kubernetes集群,它有如下两种规划中的建设模式:

Kubernetes集群建设规划之work-node选型_第2张图片

假定,即将被运行的某个pod所需的算力资源为200毫核CPU和1.5 GB的Mem,设定pod的副本数为3。
根据前文所述,在方案1的work-node中共可容纳8个这样规格的pod,扣除掉额定的3个pod外,在方案1的work-node中还提供了5个同等规格的pod算力资源可供轮转。
同理,在方案2的work-node中共可容纳4个这样规格的pod,扣除掉额定的3个pod外,在方案2的work-node中还提供了1个同等规格的pod算力资源可供轮转。
假定作业环境规定pod的轮转数量和pod的副本数量按照1:1配置,则方案1的work-node中提供了充分的pod轮转资源、而方案2的work-node中则不能提供对应的pod轮转资源。
因此,从work-node能否提供pod临时扩张所需的轮转资源来讲,应该选择使用计算资源较充分的高性能主机作为work-node。
接下来,我们来讨论Kubernetes集群中的work-node不可用的问题。
当Kubernetes集群中的某个work-node不可用时,其上的pod会被重新调度到其他有足额空余算力资源的work-node上。当集群中剩余算力资源不足以承载待调度的pod时,这些pod中的一部分副本就会处于失效状态。在这里我们把这个问题简化一下,仅讨论pod副本失效或丢失的数量。命题被如此简化后虽然不能精确回答到底是那些副本失效或丢失了,但是可以从work-node选型的角度清晰地告知我们work-node选型应遵循一条规则。
仍以前述的两种方案构建相同算力的Kubernetes集群。假定方案1和方案2中的Kubernetes集群中的pod处于满载状态且各work-node实现了其最大pod承载量,现在其中各有一个节点故障,那么方案1中的pod丢失比例为50%、方案2中的pod丢失比例为25%。因此,从work-node不可用的角度讲,work-node的数量应该尽可能的多,这也就意味着在Kubernetes集群总算力不变的情况下,单个work-node的算力规格应以4倍pod所需算力为准、不宜偏大。
最后,总结一下从经济性角度对work-node的规格进行选型的结论:
关键的选型影响因素是即将承载的单个pod所需算力规格;
重要影响因素是规划的pod副本数量;
当pod所需算力规格单一时,一般不建议选择CPU和Mem规格偏大的主机作为Kubernetes的work-node;
当pod所需算力规格单一时,应尽量选择pod所需算力规格乘以pod副本数的CPU和Mem规格的主机作为Kubernetes的work-node。
此结论的前置条件:使用虚拟机主机或私有云资源池构建Kubernetes集群。

你可能感兴趣的:(java,开发语言)