You need to enable JavaScript to run this app.
导航
负载感知调度
最近更新时间:2024.07.22 11:48:20首次发布时间:2023.03.01 18:21:10

本文主要描述如何使用容器服务提供的负载感知调度能力,实现节点负载均衡的目标。

说明

邀测·申请试用】:该功能目前处于邀测阶段,如需使用,请提交申请。

功能概述

负载感知调度是容器服务提供的基于节点真实负载,进行合理调度的策略。调度过程中,通过参考节点负载的历史统计,将 Pod 优先调度到负载较低的节点,实现节点负载均衡的目标,避免出现因单个节点负载过高而导致的应用程序或节点故障。

alt

在实际业务场景中,节点的利用率会随着时间、集群环境、工作负载的流量或请求等因素动态变化,针对此类情况,容器服务以 descheduler 组件方式提供重调度能力,防止在 Pod 调度完成后,集群再次出现负载极端不均衡的情况。因此,您可可以结合负载感知调度能力和重调度能力,帮助集群获得更好的负载均衡效果。

说明

  • 邀测·申请试用】:descheduler 组件目前处于邀测阶段,如需使用,请提交申请。
  • 安装 descheduler 组件并启用重调度能力时,Pod 可能会被驱逐(重调度),因此可能发生服务中断等情况。建议您结合自身场景,选择是否需要在启用负载感知调度能力时,安装 descheduler 组件并启用重调度能力。

前提条件

  • 已创建集群,且集群中存在两个及以上节点需要均衡节点的负载情况。详细操作,请参见 创建集群新增节点
  • 集群中已安装 scheduler-plugin 组件。详细操作,请参见 scheduler-plugin 组件

使用方法

通过 kubectl 启用

通过在 Pod 中添加 Annotations 来标识该 Pod 是否基于节点的真实负载情况,开启负载感知调度。

Annotation KeyAnnotation Value 示例值说明

vke.volcengine.com/load-aware-enabled

true

是否开启负载感知调度。取值如下:

  • true:开启。
  • false:不开启。

YAML 文件示例如下所示。

apiVersion: v1
kind: Pod
metadata:
  annotations:
    vke.volcengine.com/load-aware-enabled: "true"  # 是否开启负载感知调度。
  labels:
    app: load-aware-pod
  name: load-aware-pod  # Pod 名称。
  namespace: default  # Pod 所在命名空间。
spec:
  containers:
    - name: hello-pod # 容器名称。
      image: nginx:latest # 容器镜像地址。
      ports:
        - containerPort: 8080 # 容器端口。

通过控制台启用

容器服务支持通过控制台开启负载感知调度,但集群版本需要满足如下要求:

说明

若集群版本不满足要求,请升级集群版本。详细操作,请参见 升级集群

在满足条件的集群中,按如下步骤开启负载感知调度:

  1. 安装 scheduler-plugin 组件,并在组件配置中开启 负载感知调度 能力。详细操作,请参见 scheduler-plugin 组件
  2. 可选)启用重调度能力时,需要安装和配置 descheduler 组件。
    1. 安装 descheduler 组件。详细操作,请参见 安装组件

    2. 找到集群中 descheduler 组件对应的 ConfigMap(配置项),并修改对应的 YAML。
      alt

      enableDryRun参数值的,从true改为false。 代码片段如下所示:

      deschedulerPolicy:
        # nodeSelector: "key1=value1,key2=value2"
        # maxNoOfPodsToEvictPerNode: 10
        # maxNoOfPodsToEvictPerNamespace: 10
        profiles:
          - name: descheduler
            pluginConfig:   # 该部分配置不建议修改。
              - name: "DefaultEvictor"
                args:
                  nodeFit: true
                  evictLocalStoragePods: false
                  evictSystemCriticalPods: false
                  ignorePvcPods: false
                  evictFailedBarePods: false
              - name: "LowNodeLoad"
                args:
                  lowThresholds:
                    "cpu" : 30
                    "memory": 30
                  highThresholds:  # 负载上限。
                    "cpu" : 60
                    "memory": 70
                  evictableNamespaces:  # 配置不被驱逐的命名空间。
                    exclude:
                      - kube-system
                  excludeOwnerKinds:  # 配置不被驱逐的工作负载类型。
                    - "StatefulSet"
                  enableDryRun: false  # 修改为 false,即开启驱逐功能,true 则不会发起驱逐。
            plugins:
              balance:
                enabled:
                - "LowNodeLoad"
      
    3. 重启 descheduler 组件对应 Deployment。
      alt

使用示例

本文以集群中存在 3 个节点(4 Core、16 GiB 规格)为例,对比使用负载感知调度前后的节点负载差异,介绍如何将业务 Pod 调度到负载较小的节点上,实现节点负载均衡的方法。

未使用负载感知调度

  1. 连接目标集群。详细操作,请参见 连接集群
  2. 创建工作负载的 YAML 文件。下文以创建 Deployment 为例,示例文件stress-test.yaml代码如下所示。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: stress-test # Deployment 名称。
      namespace: default # Deployment 所属命名空间。
      labels:
        app: stress-test
    spec:
      replicas: 2 # Pod 实例个数。
      selector:
        matchLabels:
          app: stress-test
      template:
        metadata:
          name: stress-test
          labels:
            app: stress-test
        spec:
          containers:
            - args:
                - '--vm'
                - '3'
                - '--vm-bytes'
                - '1800M'
                - '-c'
                - '3'
                - '--vm-hang'
                - '10'
              command:
                - stress
              image: polinux/stress
              imagePullPolicy: Always
              name: stress
              resources:
                limits:
                  cpu: '3'
                  memory: 6Gi
                requests:
                  cpu: '3'
                  memory: 6Gi
          restartPolicy: Always
    
  3. 执行如下命令,创建工作负载。
    kubectl apply -f stress-test.yaml
    
  4. 查看上一步创建的工作负载的 Pod 被调度到的节点。
    kubectl get pods -owide
    
    预期返回结果如下所示,表示 Pod 被调度到192.168.1.5192.168.1.3节点上。
    alt
  5. 查看节点的资源使用情况。
    kubectl top nodes
    
    预期返回结果如下所示,表示192.168.1.5192.168.1.3节点是高负载节点。
    alt

使用负载感知调度

上述结果表示节点的负载不均衡,期望后续将 Pod 尽量调度到192.168.1.4节点时,按如下说明,在业务 Pod 中添加 Annotations,开启负载感知调度。

  1. 创建有 6 个 Pod 的工作负载并启用负载感知调度,每个 Pod 的容器申请 500 mCore CPU。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx # Deployment 名称。
    	namespace: default # Deployment 所属命名空间。
      labels:
        app: nginx
    spec:
      replicas: 6
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          annotations:
            vke.volcengine.com/load-aware-enabled: "true" #  开启负载感知调度。
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx-cantainer
            image: nginx:latest # Pod 的容器镜像地址和 Tag。
            resources:
              limits:
                cpu: 500m # 容器 CPU 上限。
              requests:
                cpu: 500m # 容器 CPU 请求。
    
  2. 查看上一步创建的工作负载的 Pod 被调度到的节点。
    kubectl get pods -owide
    
    预期返回结果如下所示,6 个 Pod 均被调度到192.168.1.4节点上。
    alt