每当谈及Kubernetes,我们经常听到诸如资源管理、调度和负载均衡等术语。虽然Kubernetes提供了许多功能,但更关键的还是要了解这些概念,只有这样才能更好地理解如何放置、管理并恢复工作负载。在这篇文章中,我提供了每个功能的概述,并解释了它们是如何在Kubernetes中实现的,以及它们如何相互作用,以提供高效的容器工作负载管理。
资源管理
资源管理是对基础设施资源的有效配置。在Kubernetes中,资源可以通过容器或pod来请求、分配或消耗。拥有一个通用的资源管理模型是非常必要的,因为在Kubernetes中,包括调度器、负载均衡器、工作池管理器甚至应用程序本身的许多组件,都需要有资源意识。如果资源利用不足,这就意味着浪费,意味着成本效益低下。如果资源被过度订购,可能会导致应用程序故障、停机或错误的SLA等。
资源以它所描述的资源类型的单位来表示。例如,内存的字节数或计算容量的毫秒级。Kubernetes为定义资源及其各种属性提供了明确的规范。
虽然,当今使用的主要资源类型是CPU和内存,但资源模型是可扩展的,允许多种系统以及由用户自定义的资源类型。其他类型包括网络带宽、网络操作和存储空间。
资源规格在不同的环境下具有不同的含义。在Kubernetes中指定资源的三种主要方式如下:
ResourceRequest指的是为容器或Pod请求的一组资源。例如,对于每个Pod实例,一个Pod可以请求1.5个CPU和600MB内存。ResourceRequest可以视为描述应用服务对资源的“需求”。
ResourceLimit是指容器或pod可以消耗的组合资源的上限。例如,如果一个pod在运行时使用了超过2.5个CPU或1.2GB的内存,我们可能会认为它由于内存泄漏或其他问题而变得“流氓”了。在这种情况下,以防干扰其他集群租户,调度器可能会考虑将pod作为驱逐的候选对象。
ResourceCapacity规范描述了集群节点上可用的资源量。例如,一个物理集群主机可能具有48个内核和64GB或RAM。集群可以由具有不同资源容量的节点组成。容量规范可以被视为描述资源“供应”。
调度
在Kubernetes中,调度是将pod (由调度器管理的基本实体)与可用资源相匹配的过程。调度器考虑资源需求、资源可用性以及其他用户提供的约束和策略指令,如服务质量、亲和性/反亲和性需求、数据局部性等等。本质上,调度器的作用是将资源“供应”匹配到工作负载“需求”,如下所示:
一些调度约束(简称FitPredicates)是强制性的。例如,如果pod需要具有四个CPU内核和2GB内存的集群节点,则该pod将保持在一个暂挂状态,直到找到满足此要求的集群主机为止。
在其他情况下,可能有多个主机满足强制性标准。在这种情况下,PriorityFunctions被视为反映调度首选项。基本上,调度器采用满足强制性FitPredicates的主机列表,根据用户可配置的优先级功能的结果对每个主机打分,并找到满足最大调度优先级数量的最佳优化配置方案。
在Kubernetes中,工作负载可以由数量不定的pod组成,每个pod都具有特定的资源需求。此外,工作负载和集群都是动态的,并具有伸缩性和自动扩展功能,因此,由于需要调度程序不断地重新评估位置决策,pod的数量可能会发生变化。另外,由于Kubernetes的功能类似于cron作业,调度器需要考虑的不仅是当前的供应、需求和集群状态,还需要考虑未来工作负载的预留容量。
把调度挑战想象成俄罗斯方块游戏,理解起来就不会那么难了。我们的目标是尽可能紧密地打包所有部分(有效利用资源)。但是,它们是多维的(需要特定的内存、CPU、标签选择器等等),而不是二维的游戏片段(pod)。无法匹配游戏的部分类似于无法运行的应用程序。游戏板不是静态的,它随着主机进出服务和服务规模的变化而变化。这就是Kubernetes调度的挑战。
负载均衡
负载均衡最终涉及将应用负载均匀地扩展到可变数量的集群节点上,以便有效利用资源。应用程序服务需是可伸缩的,即使关闭单个节点或组件出现故障仍可访问。负载均衡与调度相比是另一个不同的挑战,但这两个概念具有关联性。
Kubernetes依靠pod的概念来实现水平伸缩。提示:pod是与在同一主机上运行的应用程序功能相关的容器集合。要实现可伸缩,共享一个公共标签的多个pod将跨多个集群主机运行。复制控制器负责确保应用程序中目标数量的pod正在运行,并根据需要创建或销毁pod,以满足此目标。每个pod都将在集群上拥有自己的虚拟IP地址,并可以随时间而变,这就是服务的切入点。
Kubernetes的服务抽象出一组pod,提供了一个网络端点。因为服务IP地址(如pod)具有仅在群集内可路由的IP,所以服务通常与入口资源耦合,提供了将外部IP地址和端口代理到服务端点的方法。这就使应用程序可用于外部世界。尽管在Kubernetes(包括使用云提供商提供的负载均衡器)中实现负载均衡有多种方式,但最通常使用的方式是上文介绍的涉及入站和服务的方式。
总结
这一切与调度有什么关系?如上所述,通过pod的自动可伸缩功能,通过观察到的CPU使用率动态,Kubernetes可以据此调整由复制控制器管理的pod数量。控制器定期查询资源指标API以获取每个pod的利用率,将其与创建自动伸缩控制器时指定的目标CPU利用率进行比较,并根据结果指示复制控制器来调整pod副本的目标数量。
其结果是负载均衡和调度之间交互作用。当外部客户端创建负载时,通过入口访问应用程序服务,pod所使用的CPU将会增加或下降。超出某些阈值,自动伸缩控制器将与复制控制器和调度程序进行交互,根据负载调整pod数量。该服务将会提供修改后的pod数及其位置,因此,pod数可能已经改变的事实对内网客户和外部客户来说是透明的。
平衡资源需求与应用需求的微妙之处就在于自动伸缩控制器、复制控制器和Kubernetes调度程序在资源需求、供应、约束和优先级方面的持续性的互相协调。所有这些都是在客户端应用程序意识不到的情况下进行的。Kubernetes之所以成为容器化的工作负载领域广受欢迎的编排解决方案。就在于它能够高效、透明和可靠地执行这些操作,以便应用程序正常运行。
了解更多关于Kubernetes的信息,以及如何在Rancher上实现Kubernetes,可下载电子书《Deploying and Scaling Kubernetes with Rancher》