当前位置: 首页 > 科技观察

如何管理Kubernetes集群的容量和资源

时间:2023-03-14 18:23:13 科技观察

【.com快译】众所周知,系统资源不是无限的。在那些大规模的集群即服务场景中,我们需要仔细布局和规划集群资源的配比。然而,在各类软件项目中,开发者往往错误地认为虚拟化和容器化可以让资源看起来更像一个巨大的池子,可以随意使用。例如,如果他们试图运行一个资源密集型应用程序,尤其是在启用了自动缩放的集群上,他们可能会看到类似这样的内容:运行5个pod。此时,你可能非常希望通过Kubernetes集群资源的管理,自动实现容量和资源的分配。上图显示了两个示例,假设我们有一个Kubernetes集群,手头有16个虚拟CPU和64GBRAM。那么,我们能否顺利运行一个需要20GB内存的AI容器呢?假设集群中有4个worker,每个worker需要有16GB的可用内存(实际上,DaemonSet和系统服务都需要运行一个节点,占用的资源很少,所以实际可用内存可能更少).那么,在这种情况下,如果我们只给容器分配16GB的内存,就无法保证它的顺利运行。事实上,不仅部署这么大的容器,我们还在做其他复杂的部署,甚至使用Helm图表(参见--https://grapeup.com/blog/asp-net-core-ci-cd-on-azure-pipelines-with-kubernetes-and-helm/)开箱即用的产品必须始终考虑资源限制。让我们看另一个例子——将Ceph部署到同一个集群中。我们的实现目标是将1TB的存储空间划分为10个OSD(objectstoragedaemon,对象存储守护进程)和3个cephMON(监视器)。我们想把它放在两个节点上,剩下的两个留给需要使用存储的部署。这将是一个高度可扩展的架构。一般用户第一时间能想到的就是设置OSD数量为10,MON设置为3,给Cephpod加上tolerations,给Node1和Node2匹配taint。以及所有的cephdeployments和pods将nodeSelector设置为仅针对节点1和2。如下图所示,Kubernetes会让mon-1、mon-2和5个osd运行在第一个worker上,让mon-3和另外5个osd运行在第二个worker上。应用程序可以快速将大量大容量文件保存到Ceph。如果我们还部署仪表板,并创建一个复制池,我们还可以可视化1TB的可用存储空间和10个OSD的状态。但是运行一段时间后,我们会发现真正可用的存储空间只剩下400GB,出现很多被逐出的OSDpod,同时有4个OSD在运行。对此,我们需要重新审视最初的部署配置。限制和范围通常,即使我们运行13个pod(其中可能有3个监视器),也不会占用太多资源,但OSD就不一样了。由于Ceph在内存中缓存了大量的数据,我们越使用它,它需要的资源就越多。同时,各种存储容器的数据复制和均衡也会消耗一定的空间。因此,在初始部署后,内存分配将如下图所示:连续运行几个小时后,集群将出现如下情况:正如您所看到的,我们已经丢失了将近50%的pod。这还不是最终状态,如果高吞吐量的目标是剩余的容器,那么我们会损失得更快。那么,这是否意味着我们需要配置32GB以上内存的Ceph集群呢?没有。只要我们正确设置限制(参见--https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-requests-and-limits-of-pod-and-container),A单个OSD无法从其他pod获取所有可用内存。也就是说,在这种情况下,我们最简单的方法就是:为mon整体分配预留2GB内存,每块内存限制为650MB;将30GB的总内存除以10个OSD(见下图):由于我们为OSD分配了15GB内存,并为每个Pod配置了650MB内存,因此第一个节点需要:15+2*0.65=16.3GB。此外,我们还需要考虑到运行在同一节点上的DaemonSet日志。因此,更正后的值应该是:QualityofService如果我们也对刚好符合限制的Pod设置了请求,那么Kubernetes会区别对待这样的Pod,如下图所示:这个配置将Kubernetes中的QoS设置为Guaranteed(否则突发)。有Guaranteed的Pod永远不会被驱逐。通过设置相同的请求和限制,我们可以保证Pod的资源使用,而不必担心Kubernetes移动或管理它。这一举措虽然降低了调度器的灵活性,但是可以让整个部署方式更加灵活。在环境中自动扩展资源对于关键任务系统(参见--https://grapeup.com/),只需预估所需的资源,匹配集群的大小,并做好相关限制即可足够的。有时,我们需要通过更复杂的配置和不固定的集群容量来实现水平扩展和调整可用worker的数量。假设资源会线性扩展,那么我们可以同时规划最小和最大集群的容量。如果允许一个pod在集群扩展时跟踪那些成比例的水平和垂直扩展,它可能会在按比例缩小时“驱逐”其他pod。为了缓解这个问题,Kubernetes提出了两个主要概念:PodPriority和PodDisruptionBudget。接下来,让我们通过创建一个测试场景来开始我们的讨论。这次我们不需要大量节点,只需创建一个包含两个节点组的集群:一个由常规实例(称为持久性)组成,另一个由可抢占/spot实例组成。如下图所示,当一个VM(已有节点)的CPU使用率超过0.7(即70%)时,会扩容抢占节点组。抢占式实例的优势在于,在同等性能??下,它们比普通虚拟机更容易实现。唯一的缺点是无法保证其使用寿命。也就是说,当云提供商决定它需要在别处维护该实例时,或在24小时后,该实例可能会被“驱逐”。因此,我们只能在其中运行那些容错的无状态工作负载。那么,为什么集群中只有一个持久节点呢?这是针对极端情况的。当所有可抢占节点都没有运行时,它维护了一组最小的容器来管理和保证应用程序的可操作性。下表显示了此类例程的结构。我们可以使用节点选择器将redismaster配置为能够在持久节点上运行。在Pod优先级下面,让我们看一个Horizo??ntalPodAutoscaler(HPA)的示例。Front-end:Back-end:VideoConverter:作为一个视频转换器,它的目标是降低平均资源占用。也就是说,通过检查缩放策略,当存在多个平均CPU使用率可以快速达到25%的转换队列时,它会产生新的自动缩放。示例:如果在大约10分钟内需要50个视频转换,转换器将扩展到25个实例。然后,为了防止集群中的其他容器被逐出,我们可以创建一个优先级类别(参见--https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption):优先级较高的pod具有更高的值对调度程序具有更高的值;可以驱逐优先级较低的pod。因此,如果我们给转换器较低的优先级,则默认情况下前端和后端Pod更重要。在最坏的情况下,视频转换器可能会从集群中被逐出。PodDisruptionBudget作为一种更好的Pod控制和调度方法,PodDisruptionBudget(PDB)允许我们一次配置最少的Pod数量。它比仅使用PodPriority更具限制性,因为它有效地防止了节点资源被耗尽。如果其他worker上没有足够的空间来重新安排pod,它将确保副本的数量不少于可用的预留。上表显示了最基本的配置。其中,前端副本数不少于2,我们可以通过这个给所有pod分配一个最小值,保证始终至少有1或2个pod可以处理请求。这是确保Pod自动扩展和集群扩展的最简单和最安全的方法。我们只要配置最小的中断预留容器集,就可以在不影响整体稳定性的情况下,满足最小的集群容量和各种请求的最小处理要求。至此,我们拥有创建稳定解决方案所需的所有组件。我们可以将HPA配置为与PDB具有相同的最小副本数,以简化调度程序的工作。同时,我们需要保证限制数量不仅与最大集群数量的请求数量相同,而且pod不会被驱逐。具体配置如下表所示:基于上述调度器的灵活性,当前后端负载过低,但有大量数据需要转换时,转换器会自动扩展19-21个实例。自动扩容注意事项关于自动扩容,我们需要注意以下两个方面:第一,因为我们无法确定云服务商的虚拟机的启动时间(可能几秒,也可能需要几分钟),我们不能保证自动扩展。缩放绝对可以解决峰值负载的问题。其次,当集群收缩时,对于那些正在运行的组件,我们需要反复测试,让调度器能够快速将负载转移到其他worker上,从而在不中断应用程序运行的情况下,有效地关闭虚拟机。原标题:KubernetesClusterManagement:SizeandResources,作者:AdamKozlowski