ack-koordinator提供动态资源超卖功能,通过对节点负载数据的实时收集,可以充分挖掘集群中已分配但未使用的资源量,以实现对集群资源的动态超卖。本文主要介绍如何使用动态资源超卖功能。
前提条件
- 仅支持ACK Pro版集群。具体操作,请参见创建ACK Pro版集群。
- 已安装ack-koordinator(原ack-slo-manager)。具体操作,请参见ack-koordinator。
背景信息
在Kubernetes系统中,Kubelet通过参考Pod的QoS等级来管理单机容器的资源质量,例如OOM(Out of Memory)优先级控制等。Pod的QoS级别分为Guaranteed、Burstable和BestEffort。QoS级别并不是显式定义,而是取决于Pod配置的Request和Limit(CPU、内存)。
- 节点可容纳低优任务的资源量没有任何参考,即使节点实际负载已经很高,由于BestEffort任务在资源规格上缺少容量约束,仍然会被调度到节点上运行。
- BestEffort任务间缺乏公平性保证,任务资源规格存在区别,但无法在Pod描述上体现。

针对以上问题,ACK的差异化SLO(Service Level Objectives)提供将这部分资源量化的能力。将上图中的红线定义为Usage,蓝线到红线预留部分资源定义为Buffered,绿色覆盖部分定义为Reclaimed。
如下图所示,Reclaimed资源代表可动态超卖的资源量。ack-koordinator会根据节点真实负载情况动态更新,并以标准扩展资源的形式实时更新到K8s的Node元信息中。低优的BestEffort任务可以通过在Request和Limit中定义的Recliamed资源配置来使用这部分资源,这部分配置同时也会体现在节点侧的资源限制参数上,保证BestEffort作业之间的公平性。
为体现与原生资源类型的差异性,ack-koordinator使用“Batch”优先级的概念描述该部分超卖资源,以下简称batch-cpu和batch-memory。

使用限制
组件 | 版本要求 |
---|---|
Kubernetes | ≥v1.18 |
ack-koordinator | ≥0.8.0 |
Helm版本 | ≥v3.0 |
操作步骤
- 使用以下命令,查看当前Batch资源总量。查看前请确保对应配置已经开启,详见步骤3中的描述。
# 将$nodeName替换为要查询的目标节点名称。 kubectl get node $nodeName -o yaml
预期输出:#Node status: allocatable: # 单位为千分之一核,以下表示50核。 kubernetes.io/batch-cpu: 50000 # 单位为字节,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200
- 创建Pod并申请Batch资源。在Label中指定QoS等级,并在Request和Limit中添加对应的Batch资源配置,即可让Pod使用动态超卖资源,具体示例如下。
申请Batch资源需注意:#Pod metadata: labels: # 必填,标记为低优先级Pod。 koordinator.sh/qosClass: "BE" spec: containers: - resources: requests: # 单位为千分之一核,如下表示1核。 kubernetes.io/batch-cpu: "1k" # 单位为字节,如下表示1 GB。 kubernetes.io/batch-memory: "1Gi" limits: kubernetes.io/batch-cpu: "1k" kubernetes.io/batch-memory: "1Gi"
- 若您通过Deployment或其它类型工作负载提交Pod,只需在对应的模板字段中参照上述示例,采用相同格式填写即可。同一个Pod不能同时申请Batch资源和普通的CPU或Memory资源。
- 由于节点的Batch资源总量根据当前实际负载动态计算得到,在边界情况下可能会因Kubelet未及时同步而被拒绝,此时您可以直接将被拒绝的Pod进行删除。
- 受K8s的约束,扩展资源必须以整数形式表达,因此
batch-cpu
资源需要以千分之一核为单位进行配置。
- 管理动态超卖资源。节点的Batch容量根据实际的资源利用率情况动态计算得到,CPU和内存维度默认的计算过程可以按如下公式简单推导:
nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podUsage(non-BE) - systemUsage
计算公式中各因子的含义如下:- nodeAllocatable:节点可分配资源总量。
- thresholdPercent:预留水位比例。
- podUsage(non-BE):高优先级Pod的资源用量,即非BE类型Pod的资源使用量。
- systemUsage:节点系统资源真实用量。
同时,对于内存维度的资源超卖,ack-koordinator还支持按请求量(Request)计算,具体配置参考后文有关memoryCalculatePolicy的描述,公式如下。其中podRequest(non-BE)
表示高优先级Pod的资源请求量,即非BE类型Pod的资源请求量(Request)之和。nodeBatchAllocatable = nodeAllocatable * thresholdPercent - podRequest(non-BE) - systemUsage
公式中的thresholdPercent为可配置参数,通过修改ConfigMap中的配置项可以实现对资源的灵活管理,配置示例及详细说明如下。apiVersion: v1 kind: ConfigMap metadata: name: ack-slo-config namespace: kube-system data: colocation-config: | { "enable": true, "metricAggregateDurationSeconds": 60, "cpuReclaimThresholdPercent": 60, "memoryReclaimThresholdPercent": 70, "memoryCalculatePolicy": "usage" }
字段名称 格式 含义 enable
Boolean 表示是否开启节点Batch资源的动态更新,关闭时Batch资源量会被重置为 0
。默认值为false
。metricAggregateDurationSeconds
Int Batch资源最小更新频率,单位为秒。通常建议保持为1分钟不必修改。 cpuReclaimThresholdPercent
Int 计算节点 batch-cpu
资源容量时的预留系数。默认值为65
,单位为百分比。memoryReclaimThresholdPercent
Int 计算节点 batch-memory
资源容量时的预留系数。默认值为65
,单位为百分比。memoryCalculatePolicy
String 计算节点batch-memory资源容量时的策略。 "usage"
:默认值,表示batch-memory内存资源按照高优先级Pod的内存真实用量计算,包括了节点未申请的资源,以及已申请但未使用的资源量。"request"
:表示batch-memory内存资源按照高优先级Pod的内存请求量计算,仅包括节点未申请的资源。
说明 ack-koordinator在单机端提供了针对Batch资源的压制和驱逐能力,包括弹性资源限制、容器内存QoS和容器L3 Cache及内存带宽隔离,能够有效避免低优的BestEffort容器带来的干扰问题。 - 查看命名空间
kube-system
下是否存在ConfigMapack-slo-config
。- 若存在ConfigMap
ack-slo-config
,请使用PATCH方式进行更新,避免干扰ConfigMap中其他配置项。kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)"
- 若不存在ConfigMap
ack-slo-config
,请执行以下命令进行创建Configmap。kubectl apply -f configmap.yaml
- 若存在ConfigMap
- (可选)通过Prometheus查看Batch资源使用情况。
如果您首次使用该功能的大盘,请进行重置操作,确保已安装动态资源超卖。关于重置的具体操作,请参见重置大盘。
通过ACK控制台Prometheus监控查看Batch资源使用情况的具体操作如下:
- 登录容器服务管理控制台。
- 在控制台左侧导航栏中,单击集群。
- 在集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情。
- 在集群管理左侧导航栏中,选择 。
- 在Prometheus监控页面,单击动态资源超卖页签。
您可以在动态资源超卖页签查看详细数据,包括集群以及单个节点的Batch总量和已申请量。更多信息,请参见阿里云Prometheus监控。
# 节点batch-cpu可分配总量。 koordlet_node_resource_allocatable{resource="kubernetes.io/batch-cpu",node="$node"} # 节点batch-cpu已分配量。 koordlet_container_resource_requests{resource="kubernetes.io/batch-cpu",node="$node"} # 节点batch-memory可分配总量。 kube_node_status_allocatable{resource="kubernetes.io/batch-memory",node="$node"} # 节点batch-memory已分配量。 koordlet_container_resource_requests{resource="kubernetes.io/batch-memory",node="$node"}
使用样例
- 使用以下命令,查看节点Reclaimed资源总量。查看前请确保对应配置已经开启,详见步骤3中的描述。
kubectl get node $nodeName -o yaml
预期输出:
#Node信息 status: allocatable: # 单位为千分之一核,以下表示50核。 kubernetes.io/batch-cpu: 50000 # 单位为字节,以下表示50 GB。 kubernetes.io/batch-memory: 53687091200
- 使用以下YAML内容,创建名为be-pod-demo.yaml文件。
apiVersion: v1 kind: Pod metadata: lables: koordinator.sh/qosClass: "BE" name: be-demo spec: containers: - command: - "sleep" - "100h" image: polinux/stress imagePullPolicy: Always name: be-demo resources: limits: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" requests: kubernetes.io/batch-cpu: "50k" kubernetes.io/batch-memory: "10Gi" schedulerName: default-scheduler
- 使用以下命令,部署be-pod-demo作为目标评测应用。
kubectl apply -f be-pod-demo.yaml
- 在单机端的cgroup分组中查看BE Pod资源限制的生效情况。
常见问题
当前已通过ack-slo-manager的旧版本协议使用了动态资源超卖功能,升级为ack-koordinator后是否继续支持?
旧版本的动态资源超卖协议包括两部分:
- 在Pod的Annotation中填写的
alibabacloud.com/qosClass
。 - 在Pod的Request和Limit中填写的
alibabacloud.com/reclaimed
。
ack-koordinator兼容以上旧版本协议,并在ACK Pro调度器中统一计算新旧版本协议的资源申请量和可用量。您可将组件无缝升级至ack-koordinator。
ACK Pro调度器和ack-koordinator对各版本协议的适配如下。
ACK调度器版本 | ack-koordinator版本(ack-slo-manager) | alibabacloud.com协议 | koordinator.sh协议 |
---|---|---|---|
≥1.18且<1.22.15-ack-2.0 | ≥0.3.0 | 支持 | 不支持 |
≥1.22.15-ack-2.0 | ≥0.8.0 | 支持 | 支持 |