
# 应用紧凑型缩容功能
紧凑型缩容功能是指在工作负载缩容过程中，控制器会根据节点上NPU的碎片状态，优先释放导致NPU碎片的Pod。该策略通过释放出更完整、连续的NPU资源块，提升集群的NPU利用率并降低资源浪费。在具体实现上，Volcano调度器会依据设定的紧凑型缩容策略，对由Deployment（也间接包括[ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/)）及其他指定工作负载类型管理的Pod进行评分。Pod所在节点的NPU占用率越低，其得分也越低。缩容时，控制器优先移除得分较低的Pod，若存在多个得分相同的Pod，则随机驱逐相应数量的Pod。这样有助于提高后续调度的成功率和整体NPU资源的使用效率。
假设Deployment A在两个节点上各有两个Pod，每个Pod使用一个NPU芯片。其中一个节点没有空闲的NPU芯片，而另一个节点有4个空闲的NPU芯片。当Deployment A需要缩容两个副本时，将会根据Pod的NPU碎片得分优先缩减得分低的两个Pod（即空闲NPU节点中的Pod），以释放更多NPU资源，供其他业务调度。
图1紧凑型缩容示例   
![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002337246542.png "点击放大")
#### 约束与限制
- 集群中需安装Volcano调度器插件，且插件版本在1.18.1及以上。
- 当前紧凑型缩容能力仅支持基于节点NPU碎片进行打分。
- 紧凑型缩容能力默认支持的工作负载类型为Deployment（也间接包括[ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/)）。如果需要支持第三方工作负载类型，请参考[开启紧缩型缩容功能]进行配置。
- 关闭紧凑型缩容能力后，集群中Pod上已有的缩容分值注解不会清理，这些未清理注解的Pod仍会按照紧凑型缩容策略处理。但当Pod重启时，其对应的分值注解将被自动移除，后续将不再使用紧凑型缩容功能。
 
 #### 开启紧缩型缩容功能
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称，进入集群"概览页"。
2. 在左侧导航栏单击"配置中心"，右侧选择"调度配置"页签。在"设置集群默认调度器 \> 默认调度器"中选择"Volcano调度器"，并在"专家模式"中单击"开始使用"。
3. 在"专家模式（Volcano调度）"页面的YAML中，配置如下参数，用于开启紧凑型缩容功能。 
   ```
   ...
   enable_scale_in_score: true
   scale_in_priority: binpack
   workload_balancer_score_annotation_key: 'controller.kubernetes.io/pod-deletion-cost'
   workload_balancer_scoring_qps: 100
   workload_balancer_third_party_types: ''
   ...
   ```
   表1紧缩型缩容功能参数说明 
   | 参数                                     | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   |:---|:---|
   | enable_scale_in_score                  | 表示紧凑型缩容功能的开关，具体取值如下： - true：表示开启紧凑型缩容功能。  - false：默认值，表示关闭紧凑型缩容功能。                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | scale_in_priority                      | 当多种缩容策略共存时，用于配置缩容策略的优先级，具体取值如下： - binpack：默认值，表示缩容时优先考虑节点NPU占用率低的Pod。  - die：缩容时优先考虑未占满单个NPU卡中所有DIE芯片的Pod。1.19.10及以上版本的集群支持该配置。  - wl：缩容时优先考虑[应用扩缩容优先级策略](https://support.huaweicloud.com/usermanual-cce/cce_10_0746.html)，使用该策略前需要提前开启应用扩缩容优先级策略开关。                                                                                                                                                                       |
   | workload_balancer_third_party_types    | 通过配置该参数，可将紧凑型缩容策略的适用范围扩展至第三方工作负载类型。 参数格式为第三方工作负载的"\<group\>/\<version\>/\<resources\>"拼接成的字符串，其中resources需要为复数形式，多种工作负载资源类型间以英文逗号分隔。例如："apps.kruise.io/v1alpha1/clonesets"表示配置了OpenKruise的CloneSet类型的工作负载。 如果格式错误，会导致Volcano异常退出；如果指定的CRD在集群上不存在，会导致应用紧凑型缩容策略无法正常工作。 **若期望第三方工作负载按照紧凑型缩容策略缩容，还要求在其控制器代码中实现对应的缩容逻辑，即优先移除分值注解中得分较低的Pod，具体代码实现请参见Kubernetes源码的[Pod缩容优先级排序](https://github.com/kubernetes/kubernetes/blob/b2f27c0649fc0f3d2a4a6dd29135ecc81781f7e4/pkg/controller/controller_utils.go#L836)。**                                                                              |
   | workload_balancer_score_annotation_key | 表示用于Pod缩容分值注解的名称，Volcano调度器将在此注解中写入计算得到的Pod得分。工作负载缩容时，根据各Pod缩容分值注解上的得分，判断缩容优先级。具体取值如下： - controller.kubernetes.io/pod-deletion-cost：是Kubernetes社区官方支持的缩容分值注解名称，更多信息请参见[ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/#scaling-a-replicaset)。  - openvessel.io/workload-balancer-score：若"workload_balancer_score_annotation_key"为空，则默认表示使用该注解名称。配置此注解名称时，需要提前开启[应用扩缩容优先级策略](https://support.huaweicloud.com/usermanual-cce/cce_10_0746.html)。   |
   | workload_balancer_scoring_qps          | 表示Pod打分请求的QPS限制，需设置为正数。实际的QPS上限取决API-Server的限制。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
      
   
   
4. 完成上述配置后，单击右下角"确认配置"。在"确认配置"弹窗中，确认修改信息，无误后单击"保存"。
 
#### 紧凑型缩容功能使用示例
本示例将演示在开启紧凑型缩容功能后，如何使用该功能。假设在该示例中，紧凑型缩容相关参数配置如下：
```
...
enable_scale_in_score: true
scale_in_priority: binpack
workload_balancer_score_annotation_key: 'controller.kubernetes.io/pod-deletion-cost'
...
```
1. 依次执行以下命令，创建一个Deployment类型的工作负载。 
   1. 执行以下命令，创建该工作负载的YAML文件，文件名称支持自定义。
      ```
      vim deploy1.yaml
      ```
      文件内容如下：
      ```
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: deploy1
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: deploy1
        template:
          metadata:
            labels:
              app: deploy1
          spec:
            containers:
              - name: container1
                image: busybox:latest   # 请替换为待使用镜像
                command: ["sh", "-c", "echo Hello, Kubernetes! && sleep 3600"]
                resources:
                  requests:
                    cpu: 100m
                    memory: 200Mi
                    huawei.com/ascend-310: "2"  # 需与limits.huawei.com/ascend-310保持一致
                  limits:
                    cpu: 100m
                    memory: 200Mi
                    huawei.com/ascend-310: "2"   # 表示申请的NPU资源数量
      ```
      
   
   2. 执行以下命令，创建该工作负载。
      ```
      kubectl apply -f deploy1.yaml
      ```
      回显结果如下：
      ```
      deployment.apps/deploy1 created
      ```
      
   
   
   
   
2. 执行以下命令，查看Pod的运行情况。 
   ```
   kubectl get pod
   ```
   回显结果如下，所有Pod的STATUS皆为Running，则说明工作负载创建成功。
   ```
   NAME                           READY   STATUS    RESTARTS        AGE 
   deploy1-b8c6765cd-8tkdx        1/1     Running   0               2s 
   deploy1-b8c6765cd-cwzsk        1/1     Running   0               2s
   ```
   
   
3. 依次执行以下命令，查询每个Pod的缩容优先级得分。 
   1. 执行以下命令，查询deploy1-b8c6765cd-8tkdx的详细信息。
      ```
      kubectl describe pod deploy1-b8c6765cd-8tkdx
      ```
      回显结果如下：
      ```
      Name:             deploy1-b8c6765cd-8tkdx
      Namespace:        default
      Labels:           app=deploy1
                        pod-template-hash=b8c6765cd
      Annotations:      ......
                        controller.kubernetes.io/pod-deletion-cost: -200  # 当前Pod的缩容优先级得分
                        ......
      Status:           Running
      ......
      ```
      
   
   2. 执行以下命令，查询deploy1-b8c6765cd-cwzsk的详细信息。
      ```
      kubectl describe pod deploy1-b8c6765cd-cwzsk
      ```
      回显结果如下：
      ```
      Name:             deploy1-b8c6765cd-cwzsk
      Namespace:        default
      Labels:           app=deploy1
                        pod-template-hash=b8c6765cd
      Annotations:      ......
                        controller.kubernetes.io/pod-deletion-cost: -100  # 当前Pod的缩容优先级得分
                        ......
      Status:           Running
      ......
      ```
      
   
   
   
   
4. 依次执行以下命令，验证紧缩型缩容策略是否生效，即是否优先移除缩容优先级评分更低的Pod。 
   1. 执行以下命令，对该工作负载进行缩容操作。
      ```
      kubectl scale --replicas=1 deployment deploy1    # deploy1请替换为待缩容的工作负载名称
      ```
      回显结果如下：
      ```
      deployment.apps/deploy1 scaled
      ```
      
   
   2. 执行以下命令，查看得分更低的deploy1-b8c6765cd-8tkdx是否已被移出
      ```
      kubectl get pod
      ```
      回显结果如下：
      ```
      NAME                           READY   STATUS    RESTARTS      AGE 
      deploy1-b8c6765cd-cwzsk        1/1     Running   0             10m
      ```
      由回显结果可知，名为deploy1-b8c6765cd-8tkdx的Pod已被移除，说明紧缩型缩容策略已生效。
      
   
   
   
   
 
#### 相关文档
- [资源利用率优化调度](https://support.huaweicloud.com/usermanual-cce/cce_10_0768.html)
- [应用扩缩容优先级策略](https://support.huaweicloud.com/usermanual-cce/cce_10_0746.html)
 
