使用多集群负载伸缩扩缩工作负载
应用场景
在一些复杂的业务场景下,可能有固定时间段高峰业务,又有日常突发高峰业务,若只使用标准的FederatedHPA功能,需要足够的时间来扩展工作负载,在预期的负载峰值可能会导致服务不可用。此种情况下,用户既期望能定时弹性伸缩应对固定时间段高峰业务,又期望能基于指标弹性伸缩应对日常突发高峰业务。联动FederatedHPA策略与CronFederatedHPA策略可实现复杂场景下的工作负载扩缩能力。
本小节将以hpa-example应用为例,指导您搭配使用FederatedHPA策略与CronFederatedHPA策略,实现复杂业务场景下的工作负载扩缩。
方案流程
使用负载伸缩策略的流程如图1,具体流程如下:
- 准备工作。在创建负载伸缩策略前,您需要准备两个已注册至UCS的华为云集群,并为其安装Kubernetes Metrics Server插件,并构建一个名称为hpa-example的镜像。
- 创建工作负载。基于准备工作中的镜像创建无状态工作负载,并配置服务,并为其创建与部署调度策略。
- 创建负载伸缩策略。使用命令行工具创建FederatedHPA策略与CronFederatedHPA策略。
- 观察负载伸缩过程。查看工作负载中的Pod的数量变动,观察所创建的负载伸缩策略效果。
准备工作
- 注册两个华为云集群cluster01和cluster02。若您还未注册华为云集群,请参考华为云集群进行注册。
- 为集群安装Kubernetes Metrics Server插件。若未安装,请参考Kubernetes Metrics Server进行安装。
- 登录集群节点,准备一个算力密集型的应用。当用户请求时,需要先计算出结果后才返回给用户结果,如下所示。
- 创建一个名为index.php的PHP文件,文件内容是在用户请求时先循环开方1000000次,然后再返回“OK!”。
index.php文件的内容如下:
<?php $x = 0.0001; for ($i = 0; $i <= 1000000; $i++) { $x += sqrt($x); } echo "OK!"; ?>
- 使用如下命令编写Dockerfile制作镜像。
Dockerfile的内容如下:
FROM php:5-apache COPY index.php /var/www/html/index.php RUN chmod a+rx index.php
- 执行如下命令构建镜像,镜像名称为hpa-example,版本为latest。
- (可选)登录SWR管理控制台,在左侧导航栏选择“组织管理”,单击页面右上角的“创建组织”,创建一个组织。如已有组织可跳过此步骤。
- 在左侧导航栏选择“我的镜像”,单击右侧“客户端上传”,在弹出的页面中单击“生成临时登录指令”,单击复制登录指令。
- 在集群节点上执行上一步中复制的登录指令,登录成功会显示“Login Succeeded”。
- 使用如下命令,为hpa-example镜像添加标签。
命令示例如下:
docker tag hpa-example:latest swr.cn-east-3.myhuaweicloud.com/cloud-develop/hpa-example:latest
- 使用上传镜像至镜像仓库。
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: **
- 返回容器镜像服务控制台,在“我的镜像”页面,执行刷新操作后可查看到对应的镜像信息。
- 创建一个名为index.php的PHP文件,文件内容是在用户请求时先循环开方1000000次,然后再返回“OK!”。
创建工作负载
- 使用构建的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
- 创建一个端口号为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
- 为工作负载和服务创建一个调度策略,并将其部署到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
创建负载伸缩策略
- 为工作负载创建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 # 期望的平均利用率
- 创建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 # 时区
验证负载伸缩结果
- 查看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
- 通过如下命令访问工作负载,其中{ip:port}为负载的访问地址,可以在工作负载的详情页中查询。
while true;do wget -q -O- http://{ip:port}; done
- 观察工作负载自动扩容过程。
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
- 停止访问负载,观察工作负载自动缩容过程。
查看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
- 达到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