当前位置: 首页 > Linux

Kubelet从入门到弃用:拓扑管理(上)

时间:2023-04-06 20:50:27 Linux

<从Kubelet入门到弃用>系列将从基础知识到源码,对Kubelet组件进行深度回顾。上一篇zouyee带大家看了CPU管理的相关内容,其中提到了拓扑管理。本文将对其进行详细分析。拓扑管理在Kubernetes1.18升级到Beta。TopologyManager功能支持CPU、内存和外围设备(如SR-IOVVF和GPU)的NUMA对齐,使集群能够满足低延迟要求。1.背景说明:以下TopologyManager简称为TopologyManager1.1需求说明随着单个服务器节点中处理器、硬件加速器等外设的数量越来越多,越来越多的系统采用CPU和硬件加速器的组合来支持并行计算具有高延迟要求和高吞吐量的任务。此类工作负载包括电信、科学计算、机器学习、金融服务和数据分析等。如何优化对延迟敏感的高性能并行计算应用程序的性能已成为主要挑战。在引入拓扑管理器之前,CPU、内存和设备管理器在资源分配决策上相互独立。这可能导致资源分配与多处理系统的预期不匹配。由于这些不均匀的分配,对性能或延迟敏感的应用程序将受到影响。例如,CPU和设备是从不同的NUMA节点分配的,因此会造成额外的延迟。为了获得最佳性能,需要对CPU隔离、内存和设备局部性等进行优化。拓扑管理器是Kubelet中ContainerManager组件的一部分,其作用是存储资源分配信息,以便ContainerManager组件做出适合拓扑的资源分配决策,从而实现资源分配时的拓扑对齐。请注意,拓扑管理不能单独工作。它与CPU管理器、内存管理器和设备管理器协同工作,为Pod分配资源并优化资源访问。1.2NUMA在CPU管理中,我们已经介绍过NUMA技术(复习一遍)。NUMANUMA以内存访问不一致为代价,降低了总线和内存的带宽需求。这种结构对进程调度算法要求很高,尽量减少跨Node访问内存的次数,提高系统性能。总线和内存等资源在核心之间共享。如果核心数少,没有问题,但随着核心数的增加,对总线和内存带宽的需求会大幅增加,最终总线和内存会成为系统性能的瓶颈。如下图所示,一个NUMANode包括一个或多个Sockets以及与之相连的本地内存。一个多核Socket有多个Cores。如果CPU支持HT,OS也会把这个Core当作两个LogicalProcessor。Socket是一个物理概念,指的是主板上的cpu插槽。Node是一个逻辑概念,上图中没有提到。由于SMP系统中每个CPU只能通过单一通道访问内存,内存访问成为瓶颈,CPU再多也没用。后来引入了NUMA。通过划分节点,每个节点都有本地RAM,这样访问节点内的RAM会非常快。但是跨Node访问RAM的代价会比较高。我们使用Node之间的距离(Distance,一个抽象概念)来定义Node之间访问资源的代价。Core是一个物理cpu,一个独立的硬件执行单元,如寄存器、计算单元等。Thread是超线程(HyperThreading)的概念,一个逻辑cpu,共享核心上的执行单元*二、功能介绍2.1相关配置在Kubernetes1.18版本之前,如果需要开启拓扑管理器,需要在Kublet的功能门开启该功能。从Kubernetes版本1.18开始,此功能默认启用。--feature-gates="...,TopologyManager="为了满足自定义对齐要求,拓扑管理器提供了两种不同的方式:范围和策略。scope定义了资源对齐的粒度(目前有pod和container)。policy定义了对齐时实际使用的策略(目前提供best-effort、none、restricted、single-numa-node等)。注意:为了使Pod中的CPU与其他请求的资源保持一致,需要启用CPU管理并配置适当的CPU管理策略。A。Scope如上所述,拓扑管理器提供以下两种不同的资源对齐粒度:容器(默认)pod可以在kubelet启动时使用--topology-manager-scope标志配置任一粒度。1)containerscope默认使用containerscope,拓扑管理依次进行一系列的资源对齐,即为每个容器(包含在一个Pod中)单独计算对齐。拓扑管理任意地将单个容器对齐到NUMA节点上。2)Podscope启动kubelet时,配置--topology-manager-scope=pod,使粒度与pod对齐。该作用域允许将一个Pod中的所有容器作为一个组分配给一个公共NUMA节点,即拓扑管理会将一个Pod视为一个整体,并尝试将整个Pod(所有容器)分配给单个NUMA节点或一个公共NUMA节点一组NUMA节点。以下示例说明拓扑管理器在不同场景下使用的对齐方式:所有容器都可以分配给单个NUMA节点;所有容器都可以分配给一组共享的NUMA节点。整个Pod对某个资源的请求总量是通过request/limit公式计算出来的。因此,对于某个资源,总量等于以下值中的最大值:所有应用程序容器请求的总和和针对延迟敏感或IPC高吞吐量工作负载的Init容器请求的最大值,当配置Pod作用域和单numa-node拓扑管理策略,可以将一个Pod中的所有容器放在单个NUMA节点上,这样Pod就消除了NUMA通信开销。在单numa-node策略下,只有在可能的分配中有一组合适的NUMA节点时,Kubelet才会接纳Pod。如下例:当节点集只包含单个NUMA节点时,Pod被接纳当节点集包含多个NUMA节点时,Pod被拒绝简而言之,拓扑管理器首先计算出NUMA节点集,然后使用拓扑管理策略测试这个集合来决定是拒绝还是接受pod。b.PolicyTopology管理支持四种分配策略,可以在Kubelet启动时通过Kubelet命令行--topology-manager-policy进行设置。目前支持的策略有四种:none(default)best-effortstrictedsingle-numa-node1)none这是默认策略,不执行任何拓扑对齐。2)best-effort对于Guaranteed类Pod中的每个容器,配置了best-effort拓扑管理策略的kubelet会调用各个HintProvider来判断资源可用性。使用此信息,拓扑管理器存储容器的首选关联NUMA节点。如果亲和力不是首选,则拓扑管理器将存储亲和力并无论如何都允许pod进入节点。HintProvider然后在做出资源分配决策时使用此信息。3)受限策略对于Guaranteed类Pod中的每个容器,配置受限拓扑管理策略的Kubelet调用每个HintProvider来确定其资源可用性。使用此信息,拓扑管理器存储该容器的首选关联NUMA节点。如果亲和力不是首选,则拓扑管理器将拒绝来自该节点的pod。这将导致Pod处于终止状态。如果Pod调度失败,Kubernetes调度器不会尝试重新调度Pod。推荐使用ReplicaSet或Deployment部署Pod。如果允许Pod在节点上运行,则HintProvider可以在做出资源分配决策时使用此信息。4)单numa-node策略对于Guaranteed类Pod中的每个容器,配置了单numa-node拓扑管理策略的Kubelet调用各个HintProvider来判断其资源可用性。使用此信息,拓扑管理器确定单个NUMA节点关联是否可能。如果是这样,拓扑管理器会存储此信息,然后提示提供程序可以在做出资源分配决策时使用这些信息。否则,Pod将被拓扑管理器拒绝,这将导致Pod处于Terminated状态。一旦Pod处于Terminated状态,Kubernetes调度程序将不会尝试重新调度Pod。推荐使用ReplicaSet或Deployment重新部署Pod。2.2PodConfiguration注:三种PodQoS的介绍后面会详细介绍。由于未指定资源请求或限制,因此Pod以BestEffortQoS运行。spec:containers:name:nginximage:nginx因为请求少于限制,这个Pod以BurstableQoS运行。spec:containers:name:nginximage:nginxresources:limits:memory:"200Mi"requests:memory:"100Mi"对于上述Pod,如果选择的策略是none之外的任何其他策略,拓扑管理器将评估资源这些Pod使用。拓扑管理器将调用HintProvider来获取拓扑结果。如果该策略是静态的,则CPU管理器策略会返回默认的拓扑结构结果,因为这些Pod不会明确请求CPU资源。规格:容器:名称:nginximage:nginx资源:限制:内存:“200Mi”cpu:“2”example.com/device:“1”请求:内存:“200Mi”cpu:“2”example.com/device:“1”上面的Pod以GuaranteedQoS运行,因为它的requests值等于limits值。规格:容器:名称:nginx图像:nginx资源:限制:example.com/deviceA:“1”example.com/deviceB:“1”请求:example.com/deviceA:“1”example.com/deviceB:“1""上面的Pod以BestEffortQoS类运行,因为没有指定CPU和内存请求。总结如下:对于Guaranteed类的Pod,如果CPU请求数是整数,CPU管理器策略是static,它将返回与CPU请求相关的提示,设备管理器将返回有关所请求设备的提示。对于Pods(非整型CPU)可以共享的GuaranteedCPUrequests,当CPUmanagerpolicy为static时,会返回默认的topologyhint,因为没有exclusiveCPUrequest,devicemanager会返回有关请求的设备。暗示。对于以上两个GuaranteedPod,当CPUmanagerpolicy为none时,返回默认的topologyhint。对于BestEffortPod,由于没有CPU请求,当CPU管理器策略为静态时,会发送默认提示,设备管理器会为每个请求的设备发送提示。TopologyManager会根据这些信息计算出Pod的最佳提示,并存储这些信息以供HintProvider在资源分配时使用。2.3演示例如图1中包含2个NUMA节点,2个Socket(每个Socket有4个CPU,2个GPU和2个NIC),CPU0-3,GPU0和NIC0在Socket0上,其中,属于到NUMA0节点,CPU4-7、GPU1和NIC1在Socket1中,属于NUMA1节点。只有对应的外设实现了DevicePlugin接口,并且Kubelet开启了DeviceManager,Pod才能从deviceplugin提供的可用资源(如intel.com/sriov,nvidia.com/gpu等)中请求设备资源。).比如已经完成DevicePlugin接口的NvidiaGPU设备插件和IntelSRIOV网络设备插件。假设Kubelet为CPUManager启用了静态策略,并且gpu-vendor.com和nic-vendor.com的设备插件都实现了DevicePlugin接口,下面的Pod配置可以使用拓扑管理器来运行它选择的策略:spec:containers:name:numa-aligned-containerimage:alpineresources:limits:cpu:2memory:200Migpu-vendor.com/gpu:1nic-vendor.com/nic:1根据图1的资源情况,资源对齐结果如下例:{cpu:{0,1},gpu:0,nic:0}{cpu:{0,2},gpu:0,nic:0}{cpu:{0,3},gpu:0,nic:0}{cpu:{1,2},gpu:0,nic:0}{cpu:{1,3},gpu:0,nic:0}{cpu:{2,3},gpu:0,nic:0}{cpu:{4,5},gpu:1,nic:1}{cpu:{4,6},gpu:1,nic:1}{cpu:{4,7},gpu:1,nic:1}{cpu:{5,6},gpu:1,nic:1}{cpu:{5,7},gpu:1,nic:1}{cpu:{6,7},gpu:1,nic:1}注意:(再次)如果一个Pod被拓扑管理器拒绝,它的状态将被TerminatedwithaPodadmissionerror和“TopologyAffinityError”的原因描述。一旦Pod处于此状态,Kubernetes调度程序将不会尝试重新调度。