
# 使用多集群负载伸缩扩缩工作负载
#### 应用场景
在一些复杂的业务场景下，可能有固定时间段高峰业务，又有日常突发高峰业务，若只使用标准的FederatedHPA功能，需要足够的时间来扩展工作负载，在预期的负载峰值可能会导致服务不可用。此种情况下，用户既期望能定时弹性伸缩应对固定时间段高峰业务，又期望能基于指标弹性伸缩应对日常突发高峰业务。联动FederatedHPA策略与CronFederatedHPA策略可实现复杂场景下的工作负载扩缩能力。
本小节将以hpa-example应用为例，指导您搭配使用FederatedHPA策略与CronFederatedHPA策略，实现复杂业务场景下的工作负载扩缩。
#### 方案流程
使用负载伸缩策略的流程如[图1]，具体流程如下：
1. 准备工作。在创建负载伸缩策略前，您需要准备两个已注册至UCS的华为云集群，并为其安装Kubernetes Metrics Server插件，并构建一个名称为hpa-example的镜像。
2. 创建工作负载。基于准备工作中的镜像创建无状态工作负载，并配置服务，并为其创建与部署调度策略。
3. 创建负载伸缩策略。使用命令行工具创建FederatedHPA策略与CronFederatedHPA策略。
4. 观察负载伸缩过程。查看工作负载中的Pod的数量变动，观察所创建的负载伸缩策略效果。
图1复杂场景下负载伸缩策略使用流程   
![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000002079429245.png "点击放大")
#### 准备工作
- 注册两个华为云集群cluster01和cluster02。若您还未注册华为云集群，请参考[华为云集群](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0154.html)进行注册。
- 为集群安装Kubernetes Metrics Server插件。若未安装，请参考[Kubernetes Metrics Server](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0301.html)进行安装。
- 登录集群节点，准备一个算力密集型的应用。当用户请求时，需要先计算出结果后才返回给用户结果，如下所示。
  1. 创建一个名为index.php的PHP文件，文件内容是在用户请求时先循环开方1000000次，然后再返回"OK!"。 **vi index.php**
     index.php文件的内容如下：
     ```
     <?php
       $x = 0.0001;
       for ($i = 0; $i <= 1000000; $i++) {
         $x += sqrt($x);
       }
       echo "OK!";
     ?>
     ```
     
  
  2. 使用如下命令编写Dockerfile制作镜像。 **vi Dockerfile**
     Dockerfile的内容如下：
     ```
     FROM php:5-apache
     COPY index.php /var/www/html/index.php
     RUN chmod a+rx index.php
     ```
     
  
  3. 执行如下命令构建镜像，镜像名称为hpa-example，版本为latest。 **docker build -t hpa-example:latest .**
     
  
  4. （可选）登录[SWR控制台](https://console.huaweicloud.com/swr/#/swr/dashboard)，在左侧导航栏选择"组织管理"，单击页面右上角的"创建组织"，创建一个组织。如已有组织可跳过此步骤。
  
  5. 在左侧导航栏选择"我的镜像"，单击右侧"客户端上传"，在弹出的页面中单击"生成临时登录指令"，单击![](https://support.huaweicloud.com/bestpractice-ucs/zh-cn_image_0000001826230017.png)复制登录指令。
  
  6. 在集群节点上执行上一步中复制的登录指令，登录成功会显示"Login Succeeded"。
  
  7. 使用如下命令，为hpa-example镜像添加标签。
     **docker tag \[镜像名称1:版本名称1\] \[镜像仓库地址\]/\[组织名称\]/\[镜像名称2:版本名称2\]**
     表1标签参数说明 
     | 参数                  | 参数说明                                               |
     |:---|:---|
     | **\[镜像名称1:版本名称1\]** | 请替换为您本地所要上传的实际镜像的名称和版本名称。                          |
     | **\[镜像仓库地址\]**      | 请替换为[5]中登录指令末尾的域名。 |
     | **\[组织名称\]**        | 请替换为[4]中创建的组织名称。      |
     | **\[镜像名称2:版本名称2\]** | 请替换为SWR镜像仓库中需要显示的镜像名称和镜像版本。                        |
        
     命令示例如下：
     **docker tag hpa-example:latest swr.cn-east-3.myhuaweicloud.com/cloud-develop/hpa-example:latest**
     
  
  8. 使用上传镜像至镜像仓库。 **docker push** **\[镜像仓库地址\]/\[组织名称\]/\[镜像名称2:版本名称2\]**
     命令示例如下：
     **docker push swr.cn-east-3.myhuaweicloud.com/cloud-develop/hpa-example:latest**
     终端显示如下信息，表明上传镜像成功。
     ```
     6d6b9812c8ae: Pushed 
     ... 
     fe4c16cbf7a4: Pushed 
     latest: digest: sha256:eb7e3bbd*** size: **
     ```
     
  
  9. 返回[SWR控制台](https://console.huaweicloud.com/swr/#/swr/dashboard)，在"我的镜像"页面，执行刷新操作后可查看到对应的镜像信息。
   
 
#### 创建工作负载
1. 使用构建的hpa-example镜像创建无状态工作负载，Pod数为1。镜像地址与上传到的SWR仓库有关，需要替换为实际取值。 
   ```
   kind: Deployment
   apiVersion: apps/v1
   metadata:
     name: hpa-example
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: hpa-example
     template:
       metadata:
         labels:
           app: hpa-example
       spec:
         containers:
         - name: container-1
           image: 'hpa-example:latest'   # 替换为您上传到SWR的镜像地址
           resources:
             limits:                      # limits与requests建议取值保持一致，避免扩缩容过程中出现震荡
               cpu: 500m
               memory: 200Mi
             requests:                    
               cpu: 500m
               memory: 200Mi
         imagePullSecrets:
         - name: default-secret
   ```
   
   
2. 创建一个端口号为80的服务。 
   ```
   kind: Service
   apiVersion: v1
   metadata:
     name: hpa-example
   spec:
     ports:
       - name: cce-service-0
         protocol: TCP
         port: 80
         targetPort: 80
         nodePort: 31144
     selector:
       app: hpa-example
     type: NodePort
   ```
   
   
3. 为工作负载和服务创建一个调度策略，并将其部署到cluster01和cluster02两个集群，使用权重拆分的方式部署，每个集群的权重为1，以保证两个集群的相同优先级。 
   ```
   apiVersion: policy.karmada.io/v1alpha1
   kind: PropagationPolicy
   metadata:
     name: hpa-example-pp
     namespace: default
   spec:
     placement:
       clusterAffinity:
         clusterNames:
         - cluster01
         - cluster02
       replicaScheduling:
         replicaDivisionPreference: Weighted
         replicaSchedulingType: Divided
         weightPreference:
           staticWeightList:
           - targetCluster:
               clusterNames:
               - cluster01
             weight: 1
           - targetCluster:
               clusterNames:
               - cluster02
             weight: 1
     preemption: Never
     propagateDeps: true
     resourceSelectors:
     - apiVersion: apps/v1
       kind: Deployment
       name: hpa-example
       namespace: default
     - apiVersion: v1
       kind: Service
       name: hpa-example
       namespace: default
   ```
   
   
 
#### 创建负载伸缩策略
1. 为工作负载创建FederatedHPA策略。 
   **vi hpa-example-hpa.yaml**
   YAML文件内容如下。该策略作用于名称为hpa-example的负载，稳定窗口时长为扩容0秒、缩容100秒，最大Pod数为100、最小Pod数为2，包含一条系统指标规则，期望的CPU利用率为50%。
   ```
   apiVersion: autoscaling.karmada.io/v1alpha1     
   kind: FederatedHPA
   metadata:
     name: hpa-example-hpa                               # FederatedHPA策略名称
     namespace: default                                  # 工作负载所在命名空间名称 
   spec:
     scaleTargetRef:
       apiVersion: apps/v1
       kind: Deployment
       name: hpa-example                                 # 工作负载名称
     behavior:
       scaleDown:
         stabilizationWindowSeconds: 100                 # 缩容的稳定窗口时长为100秒
       scaleUp:
         stabilizationWindowSeconds: 0                   # 扩容的稳定窗口时长为0秒
     minReplicas: 2                                      # 最小Pod数为2
     maxReplicas: 100                                    # 最大Pod数为100
     metrics:
       - type: Resource
         resource:
           name: cpu                                     # 扩缩指标基于CPU数据
           target:
              type: Utilization                          # 指标类型为利用率
              averageUtilization: 50                     # 期望的平均利用率
   ```
   
   
2. 创建CronFederatedHPA策略。 
   **vi cron-federated-hpa.yaml**
   YAML文件内容如下。该策略作用于名称为hpa-example-hpa的FederatedHPA策略，期望每天8:30扩容工作负载至10个Pod，每天10:00缩容工作负载至2个Pod。
   ```
   apiVersion: autoscaling.karmada.io/v1alpha1 
   kind: CronFederatedHPA 
   metadata: 
     name: cron-federated-hpa                            # CronFederatedHPA策略名称  
   spec: 
     scaleTargetRef: 
       apiVersion: apps/v1 
       kind: FederatedHPA                               # 作用于FederatedHPA策略 
       name: hpa-example-hpa                             # FederatedHPA的名称 
     rules: 
     - name: "Scale-Up"                                  # 规则名称 
       schedule: 30 08 * * *                             # 触发时间
       targetReplicas: 10                                # 目标Pod数，非负整数 
       timeZone: Asia/Shanghai                           # 时区
     - name: "Scale-Down"                                # 规则名称
       schedule: 0 10 * * *                              # 触发时间
       targetReplicas: 2                                 # 目标Pod数，非负整数 
       timeZone: Asia/Shanghai                           # 时区
   ```
   
   
 
#### 验证负载伸缩结果
1. 查看FederatedHPA策略，结果显示工作负载的CPU使用率为0%。 
   **kubectl get FederatedHPA hpa-example-hpa**
   ```
   NAME              REFERENCE                TARGETS   MINPODS   MAXPODS   REPLICAS   AGE 
   hpa-example-hpa   Deployment/hpa-example   0%/50%    1         100       1          6m
   ```
   
   
2. 通过如下命令访问工作负载，其中{ip:port}为负载的访问地址，可以在工作负载的详情页中查询。 
   **while true;do wget -q -O- http://** *{ip:port}* **; done**
   
   
3. 观察工作负载自动扩容过程。 
   **kubectl get federatedhpa** **hpa-example-hpa** **--watch**
   查看FederatedHPA策略，可以看到6m23s时负载的CPU使用率为200%，超过了目标值，此时触发了FederatedHPA策略，将工作负载扩容为4个Pod，随后的几分钟内，CPU使用并未下降，直到到8m16s时CPU使用率才开始下降，这是因为新创建的Pod并不一定创建成功，可能是因为资源不足Pod处于Pending状态，这段时间内在扩容节点。
   到8m16s时CPU使用率开始下降，说明Pod创建成功，开始分担请求流量，到8分钟时下降到81%，还是高于目标值，在容忍度范围外，说明还会再次扩容，到9m31s时再次扩容到7个Pod，这时CPU使用率降为51%，在容忍度范围内，不会再次扩缩，因此此后Pod数量一直稳定在7个。
   ```
   NAME              REFERENCE                TARGETS    MINPODS   MAXPODS   REPLICAS   AGE 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       1          6m 
   hpa-example-hpa   Deployment/hpa-example   200%/50%   1         100       1          6m23s 
   hpa-example-hpa   Deployment/hpa-example   200%/50%   1         100       4          6m31s 
   hpa-example-hpa   Deployment/hpa-example   210%/50%   1         100       4          7m16s 
   hpa-example-hpa   Deployment/hpa-example   210%/50%   1         100       4          7m16s 
   hpa-example-hpa   Deployment/hpa-example   90%/50%    1         100       4          8m16s 
   hpa-example-hpa   Deployment/hpa-example   85%/50%    1         100       4          9m16s 
   hpa-example-hpa   Deployment/hpa-example   51%/50%    1         100       7          9m31s 
   hpa-example-hpa   Deployment/hpa-example   51%/50%    1         100       7          10m16s 
   hpa-example-hpa   Deployment/hpa-example   51%/50%    1         100       7          11m
   ```
   查看FederatedHPA策略事件，可以看到策略的生效时间。
   **kubectl describe federatedhpa hpa-example-hpa**
   
   
4. 停止访问负载，观察工作负载自动缩容过程。 
   查看FederatedHPA策略，可以看到从13m开始CPU使用率为21%，18m时Pod数量缩为3个，到23m时Pod数量缩为1个。
   **kubectl get federatedhpa hpa-example-hpa --watch**
   ```
   NAME              REFERENCE                TARGETS    MINPODS   MAXPODS   REPLICAS   AGE 
   hpa-example-hpa   Deployment/hpa-example   50%/50%    1         100       7          12m 
   hpa-example-hpa   Deployment/hpa-example   21%/50%    1         100       7          13m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       7          14m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       7          18m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          18m
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          19m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          19m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          19m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          19m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          23m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       3          23m 
   hpa-example-hpa   Deployment/hpa-example   0%/50%     1         100       1          23m
   ```
   查看FederatedHPA策略事件，可以看到策略的生效时间。
   **kubectl describe federatedhpa hpa-example-hpa**
   
   
5. 达到CronFederatedHPA策略的触发时间后，观察工作负载的自动扩缩容过程。 
   可以看到118m时Pod数量扩为4个，到123m时Pod数量扩为10个。
   **kubectl get cronfederatedhpa** **cron-federated-hpa** **--watch**
   ```
   NAME                 REFERENCE                TARGETS    MINPODS   MAXPODS   REPLICAS   AGE 
   cron-federated-hpa   Deployment/hpa-example   50%/50%    1         100       1          112m 
   cron-federated-hpa   Deployment/hpa-example   21%/50%    1         100       1          113m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       4          114m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       4          118m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       4          118m
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       4          119m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       7          119m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       7          119m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       7          119m
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       7          123m  
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       10         123m 
   cron-federated-hpa   Deployment/hpa-example   0%/50%     1         100       10         123m
   ```
   查看CronFederatedHPA策略事件，可以看到策略的生效时间。
   **kubectl describe cronfederatedhpa cron-federated-hpa**
   
   
 
