负载感知调度
Volcano调度器提供节点CPU、Memory的负载感知调度能力,感知集群内节点CPU、Memory的负载情况,将Pod优先调度到负载较低的节点,实现节点负载均衡,避免出现因单个节点负载过高而导致的应用程序或节点故障。
前提条件
- 已创建v1.21及以上版本的集群,详情请参见购买Standard/Turbo集群。
- 已安装Volcano 1.11.14及以上版本的插件,详情请参见Volcano调度器。
- 已安装CCE云原生监控插件(kube-prometheus-stack),并开启“本地数据存储”模式,详情请参见云原生监控插件。
- 使用kubectl连接集群,具体操作步骤请参见通过kubectl连接集群。
功能介绍
原生Kubernetes调度器只能基于资源的申请值进行调度,然而Pod的真实资源使用率,往往与其所申请资源的Request/Limit差异很大,这直接导致了集群负载不均的问题:
- 集群中的部分节点,资源的真实使用率远低于资源申请值的分配率,却没有被调度更多的Pod,这造成了比较大的资源浪费。
- 集群中的另外一些节点,其资源的真实使用率事实上已经过载,却无法为调度器所感知到,这极大可能影响到业务的稳定性。
Volcano提供基于真实负载调度的能力,在资源满足的情况下,Pod优先被调度至真实负载低的节点,集群各节点负载趋于均衡。
随着集群状态,工作负载流量与请求的动态变化,节点的利用率也在实时变化,为防止Pod调度完成后,集群再次出现负载极端不均衡的情况下,Volcano同时提供重调度能力,通过负载感知和热点打散重调度结合使用,可以获得集群最佳的负载均衡效果。关于热点打散重调度能力的使用请参见重调度(Descheduler)。
工作原理
负载感知调度能力由Volcano与CCE云原生监控插件配合完成,开启该能力时,按照Prometheus adapt规则定义负载感知调度所需的CPU、Memory指标信息,CCE云原生监控系统按照定义的指标规则采集并保存各节点的CPU、Memory的真实负载信息,Volcano根据CCE云原生监控系统提供的CPU、Memory真实负载信息对节点进行打分排序,优先选择负载更低的节点参与调度。
负载感知调度能力考虑CPU和Memory两个维度,采用加权平均的方式对各节点打分,包括CPU、Memory资源维度权重和负载感知策略自身权重,优先选择得分最高的节点参与调度。CPU、Memory和插件自身权重可以通过“配置中心>调度配置”自定义配置。
节点得分计算公式: 负载感知策略权重 *((1 - CPU资源利用率) * CPU权重 + (1 - Memory资源利用率) * 内存权重)/(CPU权重 + 内存权重)
- CPU资源利用率:所有节点最近10分钟的CPU平均利用率,采集频率可通过Prometheus adapt规则进行修改。
- Memory资源利用率:所有节点最近10分钟的Memory平均利用率
- 安装CCE云原生监控插件后,您需要开启Metrics API以提供容器资源指标的能力,如CPU、内存使用量。
仅云原生监控插件开启本地数据存储时,可通过Metrics API提供资源指标。
首先执行以下命令查询集群中是否已开启Metrics API,如果已开启则可跳过本步骤。
kubectl get APIServices | grep v1beta1.metrics.k8s.io
若存在回显,则表示Metrics API已开启,可跳过本步骤进行下一步添加指标采集规则。
若未查询到Metrics API,要将其开启,可手动创建对应APIService对象。
- 创建一个文件,命名为metrics-apiservice.yaml。文件内容如下:
apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: labels: app: custom-metrics-apiserver release: cceaddon-prometheus name: v1beta1.metrics.k8s.io spec: group: metrics.k8s.io groupPriorityMinimum: 100 insecureSkipTLSVerify: true service: name: custom-metrics-apiserver namespace: monitoring port: 443 version: v1beta1 versionPriority: 100
- 然后执行以下命令创建对应APIService对象。
kubectl create -f metrics-apiservice.yaml
- 再次执行以下命令查询集群中是否已开启Metrics API。
kubectl get APIServices | grep v1beta1.metrics.k8s.io
开启Metrics API后,如果需要卸载云原生监控插件,请执行以下kubectl命令,同时删除APIService对象,否则残留的APIService资源将导致Kubernetes Metrics Server插件安装失败。
kubectl delete APIService v1beta1.metrics.k8s.io
- 创建一个文件,命名为metrics-apiservice.yaml。文件内容如下:
- 添加自定义指标采集规则。
- 修改user-adapter-config配置项。
kubectl edit configmap user-adapter-config -n monitoring
- 在rules字段下添加自定义指标采集规则。
自定义指标采集规则如下,红色为本次添加的指标采集规则,黑色为已有规则,在已有规则基础上添加红色规则即可。
... data: config.yaml: > rules: - seriesQuery: '{__name__=~"node_cpu_seconds_total"}' resources: overrides: instance: resource: node name: matches: node_cpu_seconds_total as: node_cpu_usage_avg metricsQuery: avg_over_time((1 - avg (irate(<<.Series>>{mode="idle"}[5m])) by (instance))[10m:30s]) - seriesQuery: '{__name__=~"node_memory_MemTotal_bytes"}' resources: overrides: instance: resource: node name: matches: node_memory_MemTotal_bytes as: node_memory_usage_avg metricsQuery: avg_over_time(((1-node_memory_MemAvailable_bytes/<<.Series>>))[10m:30s]) resourceRules: cpu: containerQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!="",pod!=""}[1m])) by (<<.GroupBy>>) nodeQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id='/'}[1m])) by (<<.GroupBy>>) resources: overrides: instance: resource: node namespace: resource: namespace pod: resource: pod containerLabel: container memory: containerQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>,container!="",pod!=""}) by (<<.GroupBy>>) nodeQuery: sum(container_memory_working_set_bytes{<<.LabelMatchers>>,id='/'}) by (<<.GroupBy>>) resources: overrides: instance: resource: node namespace: resource: namespace pod: resource: pod containerLabel: container window: 1m ...
- CPU平均利用率采集规则
- Memory平均利用率采集规则
- 重新部署monitoring命名空间下的custom-metrics-apiserver工作负载。
kubectl rollout restart deployment custom-metrics-apiserver -n monitoring
- 验证自定义规则配置成功。
- 执行以下命令,若可以正常返回自定义指标信息,表示Prometheus侧指标采集配置成功。
kubectl get --raw=/apis/custom.metrics.k8s.io/v1beta1
- 执行以下命令,查询集群内节点信息。
kubectl get nodes
然后任选一个节点执行以下命令,其中xxxx替换为查询到的node_name,如果需要查询所有节点资源信息,可以使用*代替xxxx:
kubectl get --raw=/apis/custom.metrics.k8s.io/v1beta1/nodes/xxxx/node_cpu_usage_avg
查询结果示例如下:
- 执行以下命令,若可以正常返回自定义指标信息,表示Prometheus侧指标采集配置成功。
- 修改user-adapter-config配置项。
- 开启负载感知调度能力。
安装Volcano后,您可通过“配置中心 > 调度配置”选择开启或关闭负载感知调度能力,默认关闭。
- 登录CCE控制台。
- 单击集群名称进入集群,在左侧选择“配置中心”,在右侧选择“调度配置”页签。
- 在“资源利用率优化调度”配置中,修改负载感知调度配置。
为达到最优的负载感知调度效果,可以选择关闭装箱(binpack)策略。装箱策略(binpack)根据Pod的Request资源信息,将Pod优先调度到资源消耗较多的节点,在一定程度上会影响负载感知调度的效果。多种策略的结合使用案例可参考资源利用率优化调度配置案例。
参数
说明
默认值
负载感知调度策略权重
增大该权重值,可提高负载感知策略在整体调度中的影响力。
5
CPU权重
增大该权重值,优先均衡CPU资源。
1
内存权重
增大该权重值,优先均衡内存资源。
1
真实负载阈值生效方式
- 软约束:节点CPU、内存真实负载达到阈值后,新的任务优先被分配至真实负载未达到阈值的节点,但是该节点依然允许调度。
- 硬约束:节点CPU、内存真实负载达到阈值后,该节点不允许调度新的任务。
硬约束
CPU真实负载阈值
节点CPU真实利用率超过该阈值后,会根据真实负载阈值生效方式中的约束调度工作负载。新下发的工作负载将被优先或强制调度到其他节点,节点中已经运行的工作负载不受影响。
80
内存真实负载阈值
节点内存真实利用率超过该阈值后,会根据真实负载阈值生效方式中的约束调度工作负载。新下发的工作负载将被优先或强制调度到其他节点,节点中已经运行的工作负载不受影响。
80