在同一节点上同时运行多个Pod时,Pod之间可能会因为CPU资源的争抢带来频繁的上下文切换,导致性能抖动。针对性能敏感型应用,您可以启用CPU拓扑感知调度功能,将Pod固定在节点的CPU Core上运行,缓解因CPU上下文切换、跨NUMA访存导致的应用性能下降问题。
为了帮助您更好地理解本文档并使用本功能,推荐您参见Kubernetes官方文档了解Pod Qos类、为容器和 Pod 分配内存资源、节点上的CPU管理策略(例如CPU管理策略、none
策略、static
策略)等概念。
使用场景
在Kubernetes集群中,多个Pod会在同一个节点上共享CPU核心。但在以下场景中,某些应用可能需要固定在部分CPU核心上运行。
应用尚未完成对云原生场景的适配,例如在设置线程数量时未考虑容器规格(而是整机物理核数量),导致应用出现性能下降问题。
应用运行在神龙裸金属(Intel、AMD)等多核机器上,且出现大量因跨NUMA访存带来的应用性能下降问题。
应用对CPU上下文切换十分敏感,无法承受因此带来的性能抖动。
虽然Kubernetes提供了CPU Manager以解决此问题,支持为对CPU亲和性和性能有更高要求的应用配置static
策略,允许这些应用独占节点上的特定CPU Core,以获得稳定的计算资源。但CPU Manager仅提供节点维度的CPU调度选择,无法在集群维度选择最优的CPU Core组合。此外,通过CPU Manager为应用配置static
策略时,Pod仅支持对Guaranteed类型的Pod生效,即Pod中的每个容器必须声明了CPU Request和CPU Limit且两者取值相等,无法适用于其他类型的Pod,包括Burstable和BestEffort。
为此,ACK集群基于新版的Scheduling Framework实现了CPU拓扑感知调度功能,支持通过Pod Annotation直接启用,以更好地保障CPU敏感型工作负载的服务性能。
前提条件
已创建ACK集群Pro版,且节点池的CPU Policy为None,请参见创建ACK Pro版集群。
已安装ack-koordinator组件,且组件版本为0.2.0及以上,请参见ack-koordinator。
费用说明
ack-koordinator组件本身的安装和使用是免费的,不过需要注意的是,在以下场景中可能产生额外的费用:
ack-koordinator是非托管组件,安装后将占用Worker节点资源。您可以在安装组件时配置各模块的资源申请量。
ack-koordinator默认会将资源画像、精细化调度等功能的监控指标以Prometheus的格式对外透出。若您配置组件时开启了ACK-Koordinator开启Prometheus监控指标选项并使用了阿里云Prometheus服务,这些指标将被视为自定义指标并产生相应费用。具体费用取决于您的集群规模和应用数量等因素。建议您在启用此功能前,仔细阅读阿里云Prometheus计费说明,了解自定义指标的免费额度和收费策略。您可以通过账单和用量查询,监控和管理您的资源使用情况。
步骤一:部署示例应用
本文以一个Nginx应用为例,介绍如何启用CPU拓扑感知调度,实现CPU绑核。
使用以下YAML示例,部署一个Nginx应用。
在Pod对应的节点上,执行以下命令,查看当前容器的CPU核心绑定情况。
# 具体路径可根据Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus
预期输出:
# 未指定自动绑核策略前,可使用的CPU编号范围为0~31,表示CPU目前没有约束。 0-31
步骤二:启用CPU拓扑感知调度功能
您可以通过Pod Annotation启用CPU拓扑感知调度功能,实现对Pod的绑核,具体策略如下。
在使用CPU拓扑感知调度时,请勿在Pod上直接指定nodeName
,kube-scheduler并不参与这类Pod的调度过程。您可以使用nodeSelector
等字段配置亲和性策略,来指定节点调度。
普通绑核策略
您可以通过Pod Annotation cpuset-scheduler
启用CPU拓扑感知调度功能,系统会为您实现CPU绑核。
在Pod YAML的
metadata.annotations
中,配置cpuset-scheduler
为true
,启用CPU拓扑感知调度。说明如需在工作负载(例如Deployment)中配置,请在
template.metadata
字段下配置Pod对应的Annotation。在
Containers
字段下,配置resources.limit.cpu
的取值(该值需为整数),限定CPU绑核范围。
自动绑核策略
您可以通过Annotation开启CPU拓扑感知调度功能并同步启用自动绑核策略。配置后,调度器会根据Pod规格自动规划绑核数量,尽量避免出现跨NUMA访问内存的情况。
在Pod YAML的
metadata.annotations
中,配置cpuset-scheduler
为true
,且cpu-policy
为static-burst
,启用自动绑核策略。说明如需在工作负载(例如Deployment)中配置,请在
template.metadata
字段下配置Pod对应的Annotation。在
Containers
字段下,配置resources.limit.cpu
的取值(该值需为整数),做为CPU绑核范围的参考值。
结果验证
以普通绑核策略为例,验证CPU拓扑感知调度是否成功启用。自动绑核策略的验证流程类似。
在Pod对应的节点上,再次执行以下命令,查看启用自动绑核策略后容器的CPU核心绑定情况。
# 具体路径可根据Pod的UID以及Container的ID拼接得到。
cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus
预期输出:
# 和limit数量相同
0-3
预期输出表明,容器可用的CPU编号范围为0~3,与YAML中声明的resources.limit.cpu
一致。