2.1 计算资源管理
计算资源在云平台上主要指应用程序运行时所需的资源,也主要指CPU资源和内存资源。由于云平台默认的基本要求是为多个租户提供服务,所以在同一台工作节点的服务器(物理机或虚拟机)上就有可能同时运行多个租户的应用容器。这些应用容器如何共享该节点上的CPU和内存资源,以及如何避免不必要的资源争抢,是云平台首先要解决的问题。
在Kubernetes体系中,对计算资源的管理可以在Namespace、Pod和Container三个级别完成,同时可以根据应用计算资源的需求和限制,提供不同级别的服务质量(QoS)管理。下面先看看在Namespace级别对资源的管理。
2.1.1 多集群资源管理
在一个大型企业中,将企业各数据中心的服务器全部纳入一个Kubernetes集群中进行管理是不切实际的,常见的考虑因素如下。
◎ 需要容灾备份的数据中心提供服务,保证业务的高可用性。
◎ 多个数据中心分布在不同的地区,数据中心之间的网络延时较长。
◎ 服务器由不同的云服务商托管,相互之间无法直接互联互通。
◎ 多个数据中心的安全策略和安全等级不同。
基于以上因素,我们通常需要部署多个Kubernetes集群,来共同完成应用的发布和运行。
在容器云平台上,对资源的管理首先是将多个Kubernetes集群纳入管理,以便能够对所有资源进行统一分配和管理。如图2-1所示,容器云平台应对所有Kubernetes集群统一进行资源管理。
图2-1
将多个Kubernetes集群纳入统一管理的常见方案有如下两种。
(1)通过对接每个Kubernetes集群的Master,来完成集群内的资源管理和应用部署管理。
(2)通过使用统一的Federation控制平面(Kubernetes的一个子项目)来对多个Kubernetes集群进行统一管理。
在采用第1种方案时,容器云平台需要通过Kubernetes Master提供的Restful API去控制整个集群,包括对各种Kubernetes资源对象的创建、更新、删除、查询等管理功能。还需要完成应用的多集群部署管理、跨集群水平扩展、跨集群的服务发现和自动灾难切换等多集群管理,并设置相应的网络策略,以保护各集群的Master不被攻击。
第2种方案来自Kubernetes的子项目——Federation,也被称为集群联邦。Federation的设计目标是对多个Kubernetes集群进行统一管理,将用户的应用部署到不同地域的数据中心或者云环境下,通过动态优化部署来节约运营成本。在Federation架构中,引入了一个位于所有Kubernetes集群之上的Federation控制平面,屏蔽了后端的各Kubernetes子集群,向客户提供了一个统一的管理入口,如图2-2所示。
图2-2
Federation控制平面“封装”了多个Kubernetes集群的Master角色,提供了一个统一的Master,包括Federation API Server、Federation Controller Manager,用户可以像操作单个集群一样操作Federation;还统一管理了全部Kubernetes集群的DNS、ConfigMap,并将数据保存在集中的etcd数据库中。
在方便用户统一操作多个Kubernetes集群的同时,Federation也带来了一些新的问题。
◎ 为确保所有集群的运行状态符合预期,Federation控制平面会持续监控所有集群,导致网络开销和成本显著增加。
◎Federation控制平面是“中心化”的总控节点,一旦出现问题,就可能会影响到所有集群。
◎Federation出现较晚,还不很成熟,目前Kubernetes中的资源对象只有一部分在Federation中是可用的。
2.1.2 资源分区管理
在容器云平台纳管了全部Kubernetes集群之后,平台管理员就可以进行资源分配的工作,为多个租户提供应用部署环境了。
在一个Kubernetes集群中,提供计算资源的实体被称为Node,也叫作工作节点。Node既可以是物理机服务器,也可以是虚拟机服务器。每个Node都提供了CPU、内存、网络、磁盘等资源,应用系统则是这些资源的使用者。
为了支持多租户模型,Kubernetes的Namespace提供了一种将一个集群进一步划分为多个虚拟分区进行管理的方法。每个Namespace为某个租户提供的一个逻辑上的分区,与其他租户的应用相互隔离、互不干扰。与互联网的域名类似,Namespace的名称可以被看作一级域名,在Namespace中部署的服务名称则可以被看作二级域名。例如,在名为default 的Namespace下部署的myweb服务,在Kubernetes集群中具有唯一的域名形式的服务名myweb.default.svc;我们在另一个名为test的Namespace中也能部署名为myweb的服务,其服务名为myweb.test.svc,与default中的myweb互不影响。
在Kubernetes集群中,Namespace的“分区”概念是逻辑上的,Namespace并不与特定的物理资源进行绑定。多个Namespace下的应用可以共享相同的Node资源,将“小而轻”的容器应用以更加合理的方式在物理资源中进行调度。以图2-3为例,分别属于Project1、Project2和Project3的Namespace应用被部署在3个Node上,以尽可能最大化地利用Node的资源。
图2-3
对于某些独享资源的租户,则需要为其划分固定的Node范围。在Kubernetes中,对Node的管理也很方便,通过给Node设置特定的Label(标签),就可以标注该Node属于哪个租户。在总体资源不够充分的情况下,也可以将一个Node设置多个Label,让多个租户共享。如图2-4所示,租户1独享Node1和Node2的资源,租户2和租户3共享Node3的资源,租户3和租户4共享Node4的资源。
图2-4
2.1.3 资源配额和资源限制管理
在共享使用资源的环境下,管理员需要为租户设置更精细的资源配额和资源限制的管理。各租户在自己的资源分区上部署应用时,将只能使用被分配到的总资源数量。容器云平台应该持续监控和统计各租户对资源的使用情况,为未来是否应该为租户增加资源或减少资源提供依据。
在Kubernetes体系中,为了完成资源的配额管理和限制管理,可以从Namespace、Pod 和Container三个级别进行管理。
(1)在Container(容器)级别可以对两种计算资源进行管理:CPU 和内存。对它们的配置项又包括两种:一种是资源请求(Resource Requests),表示容器希望被分配到的可完全保证的资源量,Requests的值会被提供给Kubernetes调度器(Scheduler),以便于优化基于资源请求的容器调度;另一种是资源限制(Resource Limits),Limits是容器能用的资源上限,这个上限的值会影响在节点上发生资源竞争时的解决策略。图2-5显示了在设置CPU Request和Limit后,容器可以使用的CPU资源的范围。对于内存的设置是类似的。
图2-5
(2)在Pod级别,由于一个Pod可以包含多个Container,所以可以对Pod所含的全部容器所需的CPU和内存资源进行管理。在Kubernetes中,可以通过创建LimitRange资源对象完成设置。LimitRange对象作用于Namespace,例如:
从这个例子可以看出,可以在Pod级别和Container级别设置CPU和内存资源的最小值、最大值及Limit与Request的最大比例,在Container级别还可以额外设置默认的Request 和Limit值。
(3)在Namespace级别,则可以通过对ResourceQuota资源对象的配置,提供一个总体的资源使用量限制:一方面可以设置该Namespace中Pod可以使用到的计算资源(CPU和内存)的总量上限;另一方面可以限制该Namespace中某种类型对象的总数量上限(包括可以创建的Pod、RC、Service、Secret、ConfigMap及PVC等对象的数量)。
如下所示,在compute-resources.yaml中设置了Namespace“default”的所有容器的CPU Request总和不能超过1,CPU上限为2,内存Request的总和不能超过1GB,内存上限为2GB,Pod的数量不能超过4个,Service的数量不能超过10个,等等:
在一个定义了ResourceQuota的Kubernetes集群中部署了许多符合资源条件的容器应用之后,系统会统计出容器已经使用的资源数量,例如:
2.1.4 服务端口号管理
对于租户来说,只要服务的名称保证唯一性,不同的服务(Service)便可以使用相同的端口号。但是,对于需要对外提供服务的Service来说,需要映射服务端口号到Node上(NodePort模式)。容器云平台应该对映射到Node上的服务端口号提供统一管理,以保证各服务的NodePort端口号不会冲突,同时要确保与Node上其他应用监听的端口号不会产生冲突。
在容器云平台上,对端口的管理至少应该包含以下功能。
(1)可以查看当前对外服务使用的NodePort列表,如表2-1所示。
表2-1
(2)在部署新的服务且用户输入NodePort时,平台应该提示该端口号是否已被之前部署的服务使用了。
(3)Kubernetes集群外的服务可以被作为虚拟的Service纳入Kubernetes集群中,统一管理其在物理机上监听的端口号,如表2-2所示。
表2-2