You need to enable JavaScript to run this app.
导航

Capacity 调度

最近更新时间2023.01.19 14:39:07

首次发布时间2023.01.19 10:29:54

容器服务提供 Capacity 调度功能,用于支持大数据和机器学习场景的资源弹性场景。本文介绍如何使用 Capacity 调度功能。

说明

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

背景信息

部分企业使用集群场景中,一个集群可能会被多个部门(用户)使用。原生 Kubernetes 通过 ResourceQuota 为每个用户分配固定的资源,从而实现用户资源容量隔离。但该方法有一个弊端,即各用户之间的资源无法实现弹性利用,比如在同一个集群中,如果一个部门的可用集群资源比较紧张,而另一个部门资源比较空闲时,资源使用紧张的部门无法使用空闲部门的资源,导致集群资源利用率不高。在大数据和机器学习场景下,这种情况尤其明显。

容器服务基于 Scheduling Framework 的扩展机制,在调度侧通过引入弹性配额(ElasticQuota),实现了 Capacity 调度功能。在确保用户资源分配的基础上通过资源共享的方式来提升集群的整体资源利用率。

功能概述

Capacity 调度核心能力

容器服务提供的 Capacity 调度有以下功能:

  • 支持定义不同层级的弹性配额资源。
    alt
    • 最多可以设置两级 ElasticQuota。如下图 root.1 和 root.2 是第一级,root.1.1 和 root.1.2 是第二级。

    • 叶子级 ElasticQuota 必须和命名空间关联。如下图 root.2、root.1.1、root.1.2 是叶子级 ElasticQuota,因此必须关联自定义命名空间。

    • 单个 ElasticQuota 支持关联多个命名空间。

    • 同一个命名空间只能关联一个叶子级 ElasticQuota。

    • 通过 Label 表示 ElasticQuota 的层级关系。

      Label默认值说明

      vke.volcengine.com/elasticquota-is-parent

      false

      该 ElasticQuota 是否可以挂载叶子级 ElasticQuota。取值如下:

      • true:可以挂载。
      • false:不能挂载。

      vke.volcengine.com/elasticquota-parent

      root

      该 ElasticQuota 的父级。取值如下:

      • root:第一级 ElasticQuota 的父级都是 root。root 为系统默认创建根节点。
      • 自定义:第二级 ElasticQuota 的父级为关联的第一级 ElasticQuota 自定义名称。
  • 支持不同 ElasticQuota 之间的资源借用和回收。
    • 通过 Label 表示 ElasticQuota 资源是否可以被借用。

      Label默认值说明

      vke.volcengine.com/elasticquota-allow-lent

      true

      是否允许该 ElasticQuota 的资源被借用。取值如下:

      • true:允许。
      • false:不允许。
    • 通过设置资源使用上限(Max)和资源使用保障(Min),保证不同 ElasticQuota 之间的资源借用和回收策略的运行。

      • 子级 ElasticQuota 的 Min 之和 ≤ 父级 ElasticQuota 的 Min。
      • 系统会自动计算一级 ElasticQuota Min 之和以及集群可保障的资源,要求一级 ElasticQuota Min 之和 ≤ 集群可保障资源。
  • 支持设置 CPU、GPU、内存等多种资源配额。
  • 支持按照 ElasticQuota 权重(Weight)公平分配资源,ElasticQuota 未使用的 Min 资源将按照权重公平分配给其他 ElasticQuota。

集群资源弹性配额划分

集群资源弹性配额划分示意图如下所示。
alt
容器服务中,集群资源按照弹性配额角度划分为两部分:

  • 用户自定义配额:
    用户自定义配置 ElasticQuota,设置一级和二级 ElasticQuota,配置层级关系并在叶子级配额下关联自定义命名空间(例如上图中的 namespace-1、namespace-2、namespace-3 三个命名空间)。
  • 系统默认配额:
    • System 组:即 kube-system 命名空间的 ElasticQuota,由系统自动计算,用户不可设置。
    • Default 组:未加入 System 组和自定义组的资源,都会被纳入 Default 组并由系统计算配额。

使用限制

目前仅支持在创建集群时开启 Capacity 调度功能,且开启后暂不支持修改。

使用方法

步骤一:创建集群并开启 Capacity 调度

本文通过两台 4 vCPU 16 GiB 规格的 ECS 实例(节点),描述容器服务中 Capacity 调度的实现原理和使用方法。

  1. 登录 容器服务控制台
  2. 在容器服务的左侧导航栏,选择 集群
  3. 单击 创建集群,并根据系统提示和实际需求配置集群参数。
    其中部分参数按如下说明配置,其余参数的详细配置说明,请参见 创建集群
    • ② 节点池配置(可选) 步骤中 计算规格 选择任意规格族的 4 vCPU16 GiB 规格,并将 节点数量 设置为2
      alt
    • ③ 组件配置 步骤的 scheduler-plugin 参数配置 中打开 Capacity 调度 按钮。
      alt
  4. 确认配置并单击 确定,创建完成集群。

步骤二:规划弹性配额

本文以创建 root.1root.2root.1.1root.1.2 四个 ElasticQuota 并关联 namespace-1namespace-2namespace-3 三个命名空间为例,规划弹性配额。

  1. 通过 kubectl 连接集群。详细操作,请参见 连接集群
  2. 执行如下命令,创建 3 个命名空间。
    kubectl create ns namespace-1
    kubectl create ns namespace-2
    kubectl create ns namespace-3
    
  3. 执行创建 YAML 文件命令,定义四个 ElasticQuota。

    注意

    ElasticQuota 必须在 kube-system 命名空间下创建,并将叶子级 ElasticQuota 关联到自定义的命名空间。

    • root.1
      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuota
      metadata:
        labels:
          vke.volcengine.com/elasticquota-allow-lent: "true" # 空闲时保障资源是否可租借给其他 ElasticQuota。
          vke.volcengine.com/elasticquota-is-parent: "true" # 该 ElasticQuota 下可以挂载叶子级配额。
          vke.volcengine.com/elasticquota-parent: root # 该 ElasticQuota 的父级为 root。
        name: root.1
        namespace: kube-system # 必须为 kube-system 才生效。
      spec:
        max:
          cpu: 4
          memory: 40Gi
          nvidia.com/gpu: 2
        min:
          cpu: 2
          memory: 40Gi
          nvidia.com/gpu: 2
      
    • root.2
      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuota
      metadata:
        labels:
          vke.volcengine.com/elasticquota-allow-lent: "true" # 空闲时保障资源是否可租借给其他 ElasticQuota。
          vke.volcengine.com/elasticquota-is-parent: "false" # 该 ElasticQuota 下不可以挂载叶子级配额。
          vke.volcengine.com/elasticquota-parent: root # 该 ElasticQuota 的父级为 root。
        name: root.2
        namespace: kube-system # 必须为 kube-system 才生效。
      spec:
        max:
          cpu: 6
          memory: 40Gi
          nvidia.com/gpu: 2
        min:
          cpu: 4
          memory: 20Gi
          nvidia.com/gpu: 1
        namespaces:        # ElasticQuota 关联的命名空间。
        - namespace-3        
      
    • root.1.1
      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuota
      metadata:
        labels:
          vke.volcengine.com/elasticquota-allow-lent: "true" # 空闲时保障资源是否可租借给其他 ElasticQuota。
          vke.volcengine.com/elasticquota-is-parent: "false" # 该 ElasticQuota 下不可以挂载叶子级配额。
          vke.volcengine.com/elasticquota-parent: root.1 # 该 ElasticQuota 的父级为 root.1。
        name: root.1.1
        namespace: kube-system # 必须为 kube-system 才生效。
      spec:
        max:
          cpu: 4
          memory: 40Gi
          nvidia.com/gpu: 2
        min:
          cpu: 1
          memory: 20Gi
          nvidia.com/gpu: 1
        namespaces:        # ElasticQuota 关联的命名空间。
        - namespace-1   
      
    • root.1.2
      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuota
      metadata:
        labels:
          vke.volcengine.com/elasticquota-allow-lent: "true" # 空闲时保障资源是否可租借给其他 ElasticQuota。
          vke.volcengine.com/elasticquota-is-parent: "false" # 该 ElasticQuota 下不可以挂载叶子级配额。
          vke.volcengine.com/elasticquota-parent: root.1 # 该 ElasticQuota 的父级为 root.1。
        name: root.1.2
        namespace: kube-system # 必须为 kube-system 才生效。
      spec:
        max:
          cpu: 4
          memory: 40Gi
          nvidia.com/gpu: 2
        min:
          cpu: 1
          memory: 20Gi
          nvidia.com/gpu: 1
        namespaces:        # ElasticQuota 关联的命名空间。
        - namespace-2
      
  4. 创建完四个 ElasticQuota 后,查看 Capacity 调度相关各资源信息。
    • 执行如下命令查看生成的 Quota 树(ElasticQuotaTree)。

      kubectl get ElasticQuotaTree -n kube-system system-elasticquota-tree -o yaml
      

      预期返回结果如下:

      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuotaTree
      metadata:
        annotations:
          cluster-capacity-resource: '{"cpu":"7800m","ephemeral-storage":"189273916718","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"26811077427200m","pods":"126"}'
          default-quota-used-resource: '{"cpu":"200m","memory":"128Mi"}'
          guaranteed-sum-min-resource: '{"cpu":"7160m","ephemeral-storage":"189273916718","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"26058199859200m","pods":"126"}'
          root-children-sum-min-resource: '{"cpu":"6","memory":"60Gi","nvidia.com/gpu":"3"}'
          system-quota-used-resource: '{"cpu":"440m","memory":"590Mi"}'
        name: system-elasticquota-tree
        namespace: kube-system
      spec:  # 弹性配额的层级关系以及资源配置。
        root:
        - name: root.1
          children:
          - name: root.1.1
            max: '{"cpu":"4","memory":"40Gi","nvidia.com/gpu":"2"}'
            min: '{"cpu":"1","memory":"20Gi","nvidia.com/gpu":"1"}'
            other: '{"is_parent":false,"namespaces":["namespace-1"]}'
          - name: root.1.2
            max: '{"cpu":"4","memory":"40Gi","nvidia.com/gpu":"2"}'
            min: '{"cpu":"1","memory":"20Gi","nvidia.com/gpu":"1"}'
            other: '{"is_parent":false,"namespaces":["namespace-2"]}'
          max: '{"cpu":"4","memory":"40Gi","nvidia.com/gpu":"2"}'
          min: '{"cpu":"2","memory":"40Gi","nvidia.com/gpu":"2"}'
          other: '{"is_parent":true}'
        - name: root.2
          max: '{"cpu":"6","memory":"40Gi","nvidia.com/gpu":"2"}'
          min: '{"cpu":"4","memory":"20Gi","nvidia.com/gpu":"1"}'
          other: '{"is_parent":false,"namespaces":["namespace-3"]}'
      

      重点参数说明如下所示。

      参数描述
      cluster-capacity-resource集群可用的总资源配额。
      default-quota-used-resourceDefault 组已使用的资源配额。
      root-children-sum-min-resource一级 ElasticQuota 的 Min 之和。
      system-quota-used-resourceSystem 组已使用的资源配额。

      guaranteed-sum-min-resource

      系统自动计算的可保障资源配额。

      注意

      • guaranteed-sum-min-resource 的计算方式如下:guaranteed-sum-min-resource = cluster-capacity-resource - system-quota-used-resource - default-quota-used-resource
        集群开启 Capacity 调度后,您可以通过查看 Quota 树,获取上述参数的值。
      • 要求root-children-sum-min-resourceguaranteed-sum-min-resource。您需要定义 ElasticQuota 的 Min 后,才可以被集群保障资源配额。
    • 查看已创建的 root.1root.2root.1.1root.1.2 四个 ElasticQuota YAML 文件内容,系统会自动为 ElasticQuota 添加 Capacity 调度相关 Annotation。
      下文以 root.1 的 YAML 文件为例。

      apiVersion: scheduling.vke.volcengine.com/v1beta1
      kind: ElasticQuota
      metadata:
        annotations:
          vke.volcengine.com/elasticquota-fair-share: '{"cpu":"3160m"}' # 该 ElasticQuota 根据公平性计算以后最终可以用于分配的资源。
          vke.volcengine.com/elasticquota-request: '{"cpu":"4"}' # 表示该 ElasticQuota 关联 Namespace 的 Pod 总请求。
        labels:
          vke.volcengine.com/elasticquota-allow-lent: "true" # 空闲时保障资源是否可租借给其他 ElasticQuota 。
          vke.volcengine.com/elasticquota-is-parent: "true" # 该 ElasticQuota 下可以挂载叶子级配额。
          vke.volcengine.com/elasticquota-parent: root # 该 ElasticQuota 的父级是 root。
        name: root.1
        namespace: kube-system
      spec:
        max:      # 可以使用的资源上限。
          cpu: 4
          memory: 40Gi
          nvidia.com/gpu: "2"
        min:      # 可以使用的保障资源。所有用户使用的 Min 之和需要小于集群的总资源量。
          cpu: "2"
          memory: 40Gi
          nvidia.com/gpu: "2"
        weight:   # 该 ElasticQuota 的权重。权重越大,分到的剩余资源能力越强。默认使用 Max,大部分场景不建议您自定义 weight。
          cpu: 4
          memory: 40Gi
          nvidia.com/gpu: "2"
      status:
        used:
          cpu: "2"        
      

步骤三:部署应用

以部署 Nginx 无状态负载(Deployment)为例,从 CPU 维度验证 Capacity 调度能力是否正常。

说明

您可以参考镜像仓库的 推送和拉取镜像 文档内容,提前上传 Nginx 镜像到火山引擎镜像仓库中。

  1. namespace-1 命名空间下创建一个无状态负载 nginx-in-ns1
    本示例中部分参数按如下说明配置,其余参数的详细配置说明,请参见 创建无状态负载
    • ① 基本信息 步骤中 命名空间 选择已创建的 namespace-1实例个数 设置为2
      alt
    • ② 容器配置 步骤的 资源配额CPU 请求 设置为2 Core、CPU 上限 设置为2 Core。
      alt
  2. nginx-in-ns1 创建成功后,单击负载名称进入详情页,然后单击 实例列表 页签,查看 Pod 实例的运行状态。
    因为节点上的资源充足,因此两个 Pod 实例的状态都为 Running
    alt
  3. namespace-3 命名空间下创建一个无状态负载 nginx-in-ns3
    本示例中部分参数按如下说明配置,其余参数的详细配置说明,请参见 创建无状态负载
    • ① 基本信息 步骤中 命名空间 选择已创建的 namespace-3实例个数 设置为4
      alt
    • ② 容器配置 步骤的 资源配额CPU 请求 设置为1 Core、CPU 上限 设置为1 Core。
      alt
  4. nginx-in-ns1 创建成功后,单击负载名称进入详情页,然后单击 实例列表 页签,查看 Pod 实例的运行状态。
    因为集群资源被之前创建的 nginx-in-ns1 使用导致剩余资源不足,因此四个 Pod 实例中只有两个状态为 Running,另外两个为 Pending
    alt
    等待 2~3 分钟后,因该集群开启了 Capacity 调度并定义了四个 ElasticQuota,所以 ElasticQuota 关联命名空间中的 Pod 实例资源使用情况会发生变化:
    • nginx-in-ns1 开始驱逐 Pod 实例,释放借用的资源。
      alt
    • nginx-in-ns3 获得从 nginx-in-ns1 中释放的资源,能够成功运行四个 Pod 实例。
      alt