在K8S集群中,如何正确选择工作节点资源大小?1

简介: 在K8S集群中,如何正确选择工作节点资源大小?

简要概述:本文讨论了在Kubernetes集群中选择较少数量的较大节点和选择较多数量的较小节点之间的利弊。


当创建一个Kubernetes集群时,最初的问题之一是:"我应该使用什么类型的工作节点,以及需要多少个?"


如果正在构建一个本地集群,是应该采购一些上一代的高性能服务器,还是利用数据中心中闲置的几台老旧机器呢?


或者,正在使用像Google Kubernetes Engine(GKE)这样的托管式Kubernetes服务,是应该选择八个n1-standard-1实例还是两个n1-standard-4实例来实现所需的计算能力呢?


目录


  1. 集群容量

  2. Kubernetes工作节点中的预留资源

  3. 工作节点中的资源分配和效率

  4. 弹性和复制

  5. 扩展增量和前导时间

  6. 拉取容器镜像

  7. Kubelet和扩展Kubernetes API

  8. 节点和集群限制

  9. 存储

  10. 总结和结论


集群容量


一般来说,Kubernetes集群可以被看作是将一组独立的节点抽象为一个大的"超级节点"。这个超级节点的总计算能力(包括CPU和内存)是所有组成节点的能力之和.


有多种实现这一目标的方法.例如,假设需要一个总计算能力为8个CPU核心和32GB内存的集群。以下是两种可能的集群设计模式:划分成两台机子或四台机子。


Kubernetes集群中的小型节点与大型节点 | 这两种选择都会得到相同容量的集群。左边的选择使用了四个较小的节点,而右边的选择使用了两个较大的节点。


问题是:哪种方法更好呢?---为了做出明智的决策,让我们深入了解如何在工作节点中分配资源。


Kubernetes工作节点中的预留资源


Kubernetes集群中的每个工作节点都是一个运行kubelet(Kubernetes代理)的计算单元。


kubelet是一个连接到控制平面的二进制文件,用于将节点的当前状态与集群的状态同步。


例如,当kubernetes调度程序将一个Pod分配给特定节点时,它不会直接向kubelet发送消息。相反,它会创建一个Binding对象并将其储存在etcd中。


kubelet定期检查集群的状态。一旦它注意到将一个新分配的Pod分配给其节点,它就会开始下载Pod的规范并创建它。


通常将kubelet部署为SystemD服务,并作为操作系统的一部分运行。


kubelet、SystemD和操作系统需要资源,包括CPU和内存,以确保正确运行。


因此,并不是所有工作节点的资源都仅用于运行Pod。


CPU和内存资源通常分配如下:


操作系统。Kubelet。Pods。驱逐阈值。


Kubernetes节点中的资源分配

e1da32c82c1df4f8808e8b635520f53b.png



您可能想知道这些组件分配了哪些资源。虽然具体配置可能会有所不同,但CPU分配通常遵循以下模式:


第一个核心的6%。后续核心的1%(最多2个核心)。接下来的两个核心的0.5%(最多4个核心)。四个核心以上的任何核心的0.25%。内存分配可能如下:


小于1GB内存的机器分配255 MiB内存。前4GB内存的25%。接下来的4GB内存的20%(最多8GB)。接下来的8GB内存的10%(最多16GB)。接下来的112GB内存的6%(最多128GB)。超过128GB的任何内存的2%。最后,驱逐阈值通常保持在100MB。


驱逐阈值 驱逐阈值代表内存使用的阈值。如果一个节点超过了这个阈值,kubelet将开始驱逐Pod,因为当前节点的内存不足。


考虑一个具有8GB内存和2个虚拟CPU的实例。资源分配如下:


70毫核虚拟CPU和1.8GB供kubelet和操作系统使用(通常一起打包)。保留100MB用于驱逐阈值。剩余的6.1GB内存和1930毫核可以分配给Pod。只有总内存的75%用于执行工作负载。


aa6c196a69c11f6424711faf12a0d78a.png


但这还不止于此。


您的节点可能需要在每个节点上运行一些Pod(例如DaemonSets)以确保正确运行,而这些Pod也会消耗内存和CPU资源。


例如,Kube-proxy、诸如Fluentd或Fluent Bit的日志代理、NodeLocal DNSCache或CSI驱动程序等。


这是一个固定的成本,无论节点大小如何,您都必须支付。


552afa38b13da88b06e1eb38c0ef8896.png


带有DaemonSets的Kubernetes节点中的资源分配 考虑到这一点,让我们来看一下"较少数量的较大节点"和"较多数量的较小节点"这两种截然相反的方法的利弊。


请注意,本文中的"节点"始终指的是工作节点。关于控制平面节点的数量和大小的选择是一个完全不同的主题。


工作节点中的资源分配和效率

随着更大实例的使用,kubelet预留的资源会减少。


让我们来看两种极端情况。


您想要为一个请求0.3个vCPU和2GB内存的应用部署七个副本。


在第一种情况下,您将为一个单独的工作节点提供资源以部署所有副本。在第二种情况下,您在每个节点上部署一个副本。为简单起见,我们假设这些节点上没有运行任何DaemonSets。


七个副本所需的总资源为2.1个vCPU和14GB内存(即7 x 300m = 2.1个vCPU和7 x 2GB = 14GB)。


一个4个vCPU和16GB内存的实例能够运行这些工作负载吗?


我们来计算一下CPU的预留:


第一个核心的6% = 60m +
第二个核心的1% = 10m +
剩余核心的0.5% = 10m
总计 = 80m

用于运行Pod的可用CPU为3.9个vCPU(即4000m - 80m)——绰绰有余。


接下来,我们来看一下kubelet预留的内存:


前4GB内存的25% = 1GB
接下来的4GB内存的20% = 0.8GB
接下来的8GB内存的10% = 0.8GB
总计 = 2.8GB

分配给Pod的总内存为16GB -(2.8GB + 0.1GB)——这里的0.1GB考虑到了100MB的驱逐阈值。


最后,Pod可以使用最多13.1GB的内存。


带有2个vCPU和16GB内存的Kubernetes节点中的资源分配


3e472b7b0d66def1fcdeb01d868971df.png


不幸的是,这还不够(即7个副本需要14GB的内存,但您只有13.1GB),您应该为部署这些工作负载提供更多内存的计算单元。


如果使用云提供商,下一个可用的增量计算单元是4个vCPU和32GB内存。


带有2个vCPU和16GB内存的节点不足以运行七个副本

4da074f504276af7f69f7c9e022a540d.png



太好了!


接下来,让我们看一下另一种情况,即我们尝试找到适合一个副本的最小实例,该副本的请求为0.3个vCPU和2GB内存。


我们尝试使用具有1个vCPU和4GB内存的实例类型。


预留的CPU总共为6%或60m,可用于Pod的CPU为940m。


由于该应用仅需要300m的CPU,这足够了。


kubelet预留的内存为25%或1GB,再加上额外的0.1GB的驱逐阈值。


Pod可用的总内存为2.9GB;由于该应用仅需要2GB,这个值足够了。


太棒了!


d82c3f7176a17ca352f2772e48e8d8d0.png


带有2个vCPU和16GB内存的Kubernetes节点中的资源分配 现在,让我们比较这两种设置。


第一个集群的总资源只是一个单一节点 — 4个vCPU和32GB。


第二个集群有七个实例,每个实例都有1个vCPU和4GB内存(总共为7个vCPU和28GB内存)。


在第一个示例中,为Kubernetes预留了2.9GB的内存和80m的CPU。


而在第二个示例中,预留了7.7GB(1.1GB x 7个实例)的内存和360m(60m x 7个实例)的CPU。


您已经可以注意到,在配置较大的节点时,资源的利用效率更高。


在单一节点集群和多节点集群之间比较资源分配情况


6e931bb32bf8fc3da750a3a2a1d574de.png


但还有更多。


较大的实例仍然有空间来运行更多的副本 — 但有多少个呢?


预留的内存为3.66GB(3.56GB的kubelet + 0.1GB的驱逐阈值),可用于Pod的总内存为28.44GB。预留的CPU仍然是80m,Pods可以使用3920m。此时,您可以通过以下方式找到内存和CPU的最大副本数:


Total CPU   3920 /
Pod CPU      300
------------------
Max Pod       13.1

您可以为内存重复进行计算:

总内存 28.44 /
Pod内存 2
最大Pod 14.22

以上数字表明,内存不足可能会在CPU之前用尽,而在4个vCPU和32GB工作节点中最多可以托管13个Pod。


2c46cc51f8c1a4ab9dfc5224052126ee.png


为2个vCPU和32GB工作节点计算Pod容量 那么第二种情况呢?


是否还有空间进行扩展?


实际上并没有。


虽然这些实例仍然具有更多的CPU,但在部署第一个Pod后,它们只有0.9GB的可用内存。

e39554809f91c63f8b9fa49344377da8.png



为1个vCPU和4GB工作节点计算Pod容量 总之,不仅较大的节点能更好地利用资源,而且还可以最小化资源的碎片化并提高效率。


这是否意味着您应该始终提供较大的实例?


让我们来看另一个极端情况:节点意外丢失时会发生什么?

弹性和复制

较少数量的节点可能会限制您的应用程序的有效复制程度。


例如,如果您有一个由5个副本组成的高可用应用程序,但只有两个节点,那么有效的复制程度将降低为2。


这是因为这五个副本只能分布在两个节点上,如果其中一个节点失败,可能会一次性失去多个副本。


具有两个节点和五个副本的集群的复制因子为两个


c04d08c59dce1374128cc13b0e9375f0.png


另一方面,如果您至少有五个节点,每个副本都可以在一个单独的节点上运行,而单个节点的故障最多会导致一个副本失效。


因此,如果您有高可用性要求,您可能需要在集群中拥有一定数量的节点。

6f3db128e0771a46940cb88a67505573.png



具有五个节点和五个副本的集群的复制因子为五 您还应该考虑节点的大小。


当较大的节点丢失时,一些副本最终会被重新调度到其他节点。


如果节点较小,仅托管了少量工作负载,则调度器只会重新分配少数Pod。


虽然您不太可能在调度器中遇到任何限制,但重新部署许多副本可能会触发集群自动缩放器。


并且根据您的设置,这可能会导致进一步的减速。


让我们来探讨一下原因。


扩展增量和前导时间


您可以使用水平扩展器(即增加副本数量)和集群自动缩放器(即增加节点计数)的组合来扩展部署在Kubernetes上的应用程序。


假设您的集群达到总容量,节点大小如何影响自动缩放?


首先,您应该知道,当集群自动缩放器触发自动缩放时,它不会考虑内存或可用的CPU。


换句话说,总体上使用的集群不会触发集群自动缩放器。


相反,当一个Pod因资源不足而无法调度时,集群自动缩放器会创建更多的节点。


此时,自动缩放器会调用云提供商的API,为该集群提供更多的节点。

d8807dba16ecfcef2c03ca15b5bd7744.png



集群自动缩放器在Pod由于资源不足而处于挂起状态时提供新的节点。


d8807dba16ecfcef2c03ca15b5bd7744.png


集群自动缩放器在Pod由于资源不足而处于挂起状态时提供新的节点。



9d5f1553f52317713e355b8b73da9e34.png

不幸的是,通常情况下,配置节点是比较缓慢的。


要创建一个新的虚拟机可能需要几分钟的时间。


提供较大或较小实例的配置时间是否会改变?


不,通常情况下,无论实例的大小如何,配置时间都是恒定的。


此外,集群自动缩放器不限于一次添加一个节点;它可能会一次添加多个节点。


我们来看一个例子。


有两个集群:


第一个集群有一个4个vCPU和32GB的单一节点。第二个集群有13个1个vCPU和4GB的节点。一个具有0.3个vCPU和2GB内存的应用程序部署在集群中,并扩展到13个副本。


这两种设置都已达到总容量

381c26d952b7471473a033ae71488909.png



当部署扩展到15个副本时会发生什么(即增加两个副本)?


在两个集群中,集群自动缩放器会检测到由于资源不足,额外的Pod无法调度,并进行如下配置:


对于第一个集群,增加一个具有4个vCPU和32GB内存的额外节点。对于第二个集群,增加两个具有1个vCPU和4GB内存的节点。由于在为大型实例或小型实例提供资源时没有时间差异,这两种情况下节点将同时可用。

030110b8e26db057ea3ef24018b7c0a7.png



然而,你能看出另一个区别吗?


第一个集群还有空间可以容纳11个额外的Pod,因为总容量是13个。


而相反,第二个集群仍然达到了最大容量。


你可以认为较小的增量更加高效和更便宜,因为你只添加所需的部分。


c9f1301e815be82cadd6f936f7eba250.png


但是让我们观察一下当您再次扩展部署时会发生什么——这次扩展到17个副本(即增加两个副本)。


第一个集群在现有节点上创建了两个额外的Pod。而第二个集群已经达到了容量上限。Pod处于待定状态,触发了集群自动缩放器。最终,又会多出两个工作节点。

bee7faf70ed07dd72e93122502789fc4.png



在第一个集群中,扩展几乎是瞬间完成的。


而在第二个集群中,您必须等待节点被配置完毕,然后才能让Pod开始提供服务。


换句话说,在前者的情况下,扩展速度更快,而在后者的情况下,需要更多的时间。


通常情况下,由于配置时间在几分钟范围内,您应该谨慎考虑何时触发集群自动缩放器,以避免产生更长的Pod等待时间。


换句话说,如果您能够接受(潜在地)没有充分利用资源的情况,那么通过使用较大的节点,您可以实现更快的扩展。


但事情并不止于此。


拉取容器镜像也会影响您能够多快地扩展工作负载,这与集群中的节点数量有关。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4月前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
426 1
|
4月前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
300 89
|
9月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
445 9
|
9月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
11月前
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
1017 33
|
11月前
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
631 19
|
11月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
11月前
|
Kubernetes API 网络安全
当node节点kubectl 命令无法连接到 Kubernetes API 服务器
当Node节点上的 `kubectl`无法连接到Kubernetes API服务器时,可以通过以上步骤逐步排查和解决问题。首先确保网络连接正常,验证 `kubeconfig`文件配置正确,检查API服务器和Node节点的状态,最后排除防火墙或网络策略的干扰,并通过重启服务恢复正常连接。通过这些措施,可以有效解决与Kubernetes API服务器通信的常见问题,从而保障集群的正常运行。
904 17
|
11月前
|
Kubernetes Shell Windows
【Azure K8S | AKS】在AKS的节点中抓取目标POD的网络包方法分享
在AKS中遇到复杂网络问题时,可通过以下步骤进入特定POD抓取网络包进行分析:1. 使用`kubectl get pods`确认Pod所在Node;2. 通过`kubectl node-shell`登录Node;3. 使用`crictl ps`找到Pod的Container ID;4. 获取PID并使用`nsenter`进入Pod的网络空间;5. 在`/var/tmp`目录下使用`tcpdump`抓包。完成后按Ctrl+C停止抓包。
423 12
|
11月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
454 0
OpenAI故障复盘丨如何保障大规模K8s集群稳定性

推荐镜像

更多