ACK部署使用elastic-workload

本文介绍如何通过阿里云Kubernetes集群(ACK)安装和使用elastic-workload(弹性负载)。

前提条件

您已经成功创建了ACK集群并部署了虚拟节点。

背景信息

在Kubernetes中,弹性包括调度层弹性(Pod)和资源层弹性(Node)两个层次,通常会通过HPA、CronHPA、VPA等模型进行Pod的弹性伸缩,再通过cluster-autoscaler或者virtual-kubelet进行资源层的弹性伸缩。两层之间通过Pod进行解耦,这样设计的好处是两层职责明确,坏处是解耦后相互结合的策略过于简单,无法实现更精细的调度策略,在Kubernetes中最小的生命周期管理单元是一个Pod,而传统的Kubernetes负载控制器(例如:Deployment、StatefulSet)管理的Pod是共享相同的调度策略的。因此,如果您想要控制一个负载在不同资源上的细粒度分配时,您可以通过elastic-workload来实现。

部署ack-kubernetes-elastic-workload

  1. 登录容器服务管理控制台

  2. 在左侧导航栏,选择市场>应用目录

  3. 阿里云应用页签下,找到ack-kubernetes-elastic-workload应用,然后单击该应用。

    阿里云应用页签下包含较多应用,您可以通过右上角的搜索框进行关键字检索。

  4. ack-kubernetes-elastic-workload页面右侧的创建区域,选择目标集群,单击创建部署弹性负载1

  5. 查看部署结果。

    1. 在左侧导航栏,单击集群

    2. 单击目标集群的ID。

    3. 在集群信息页面的左侧导航栏,选择应用>Helm

    4. 查看ack-kubernetes-elastic-workload对应的状态是否为已部署部署弹性负载

使用elastic-workload

假设:有一个应用经过容量规划,预计最多有4个副本运行在ECS上,平时低峰时保留2个副本,超过4个副本时弹性伸缩到虚拟节点,防止干扰其他正常容量规划的应用。

在Kubernetes中,任何一种负载都要解决两个问题,一个是调度问题,一个是生命周期管理问题。如果想要实现上述场景,需要解决以下问题:

  • 当副本数目达到某个数值后,如何控制调度策略的变化。

  • 在生命周期管理时,如何优先处理某些Pod。

针对上述场景和问题,下文为您介绍elastic-workload的使用方法。

  1. 创建一个简单的Deployment类型应用。

    apiVersion: apps/v1 
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9 
            ports:
            - containerPort: 80
            resources:
              requests:    #如果要配合使用HPA,必须要指定requests
                cpu: "500m"      
                memory: "1024Mi"  
  2. 使用弹性负载表达。

    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: ElasticWorkload
    metadata:
      name: elasticworkload-sample
    spec:
      sourceTarget:
        name: nginx-deployment-basic
        kind: Deployment
        apiVersion: apps/v1
        min: 2        #最小副本数
        max: 4        #最大副本数
      replicas: 6
      elasticUnit:
      - name: virtual-kubelet
        labels:
          alibabacloud.com/eci: "true"

    弹性负载的使用方式就像HPA,它通过外部挂载的方式使用,并不影响原有业务。部署弹性负载2

    弹性负载会监听原始负载,并根据弹性单元设定的调度策略,克隆并生成弹性单元的负载。根据弹性负载中副本的变化,动态地分配原始负载和弹性单元上的副本数目。

    一个典型的弹性负载主要包括两个部分:

    • sourceTarget部分主要定义原始负载的类型、副本数目可变化的范围。

    • elasticUnit部分是一个数组,定义弹性单元的调度策略,如果有多个弹性单元,则按照模板的顺序定义。

    在上述示例中:

    • sourceTarget中定义了副本数目的上下限为2~4个,表示ElasticWorkload的replicas为2~4个副本时,会调度到sourceTarget,当超过4个副本时,会调度到弹性单元,即虚拟节点virtual-kubelet。

    • elasticUnit中定义了弹性单元为虚拟节点virtual-kubelet,对应的调度策略为labels:alibabacloud.com/eci=true

  3. 查看部署结果。

    • 查看当前状态

      kubectl describe ew elasticworkload-sample

      返回示例如下,其中Status中的每个单元的Desired Replicas表示弹性负载的分配副本数目。

      Name:         elasticworkload-sample
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  autoscaling.alibabacloud.com/v1beta1
      Kind:         ElasticWorkload
      Metadata:
        Creation Timestamp:  2021-05-21T01:53:58Z
        Generation:          4
        Managed Fields:
          API Version:  autoscaling.alibabacloud.com/v1beta1
          Fields Type:  FieldsV1
          fieldsV1:
            f:spec:
              .:
              f:elasticUnit:
              f:replicas:
              f:sourceTarget:
                .:
                f:apiVersion:
                f:kind:
                f:max:
                f:min:
                f:name:
          Manager:      Apache-HttpClient
          Operation:    Update
          Time:         2021-05-21T01:53:58Z
          API Version:  autoscaling.alibabacloud.com/v1beta1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              .:
              f:elasticUnitsStatus:
              f:replicas:
              f:selector:
              f:sourceTarget:
                .:
                f:apiVersion:
                f:desiredReplicas:
                f:kind:
                f:name:
                f:updateTimestamp:
          Manager:         manager
          Operation:       Update
          Time:            2021-05-21T01:56:45Z
        Resource Version:  8727
        Self Link:         /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/elasticworkloads/elasticworkload-sample
        UID:               c4a508aa-2702-4d17-ac25-e6a207c0761a
      Spec:
        Elastic Unit:
          Labels:
            alibabacloud.com/eci:  true
          Name:                    virtual-kubelet
        Replicas:                  6
        Source Target:
          API Version:  apps/v1
          Kind:         Deployment
          Max:          4
          Min:          2
          Name:         nginx-deployment-basic
      Status:
        Elastic Units Status:
          Desired Replicas:  2
          Name:              nginx-deployment-basic-unit-virtual-kubelet
          Update Timestamp:  2021-05-21T01:56:45Z
        Replicas:            6
        Selector:            app=nginx
        Source Target:
          API Version:       apps/v1
          Desired Replicas:  4
          Kind:              Deployment
          Name:              nginx-deployment-basic
          Update Timestamp:  2021-05-21T01:56:45Z
      Events:
        Type    Reason                 Age                  From             Message
        ----    ------                 ----                 ----             -------
        Normal  SourceUpdate           12m                  ElasticWorkload  Source Target scale from 2 to 4
        Normal  UnitCreation           12m                  ElasticWorkload  ElasticWorkloadUnit nginx-deployment-basic-unit-virtual-kubelet created
        Normal  ElasticWorkloadUpdate  9m27s (x9 over 12m)  ElasticWorkload  ElasticWorkload update
        Normal  UnitUpdate             9m27s (x8 over 12m)  ElasticWorkload  ElasticWorkloadUnit virtual-kubelet has been updated
    • 查看Pod情况

      kubectl get pod -o wide

      返回示例如下,弹性负载已经克隆出新的Deployment与Pod,且Deployment的Pod副本数目是根据设定的调度策略进行动态分配。

      NAME                                                           READY   STATUS    RESTARTS   AGE   IP              NODE                           NOMINATED NODE   READINESS GATES
      nginx-deployment-basic-5bf87f5f59-22jnw                        1/1     Running   0          16m   10.34.0.131     cn-beijing.172.16.0.1          <none>           <none>
      nginx-deployment-basic-5bf87f5f59-gfp24                        1/1     Running   0          13m   10.34.0.133     cn-beijing.172.16.0.1          <none>           <none>
      nginx-deployment-basic-5bf87f5f59-pw2zx                        1/1     Running   0          13m   10.34.0.134     cn-beijing.172.16.0.1          <none>           <none>
      nginx-deployment-basic-5bf87f5f59-qvh7m                        1/1     Running   0          16m   10.34.0.132     cn-beijing.172.16.0.1          <none>           <none>
      nginx-deployment-basic-unit-virtual-kubelet-65fb6f4cd7-48ssb   1/1     Running   0          13m   172.16.22.157   virtual-kubelet-cn-beijing-e   <none>           <none>
      nginx-deployment-basic-unit-virtual-kubelet-65fb6f4cd7-gjqhm   1/1     Running   0          13m   172.16.22.158   virtual-kubelet-cn-beijing-e   <none>           <none>

此外,弹性负载支持与HPA配合使用,可以将HPA作用在弹性负载上。弹性负载会根据HPA的状态动态调整每个单元的副本分布,例如:如果当前是从6个副本缩容到4个副本,会优先将弹性单元的副本进行缩容。示例如下:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: elastic-workload-demo
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: autoscaling.alibabacloud.com/v1beta1
    kind: ElasticWorkload
    name: elasticworkload-sample
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

总的来说,弹性负载一方面通过克隆和覆写调度策略的方式生成多个Deployment,实现了调度策略的管理,另一方面通过上层的副本计算,调整原始负载和弹性单元的副本分配,实现了针对一部分Pod的优先处理。