文档

在ACK上使用UnitedDeployment

更新时间:

通过UnitedDeployment控制器自定义工作负载模板和弹性单元Subset的策略,可以动态分配在各弹性单元上面的副本数目。本文介绍如何在ACK上安装以及使用UnitedDeployment实现弹性伸缩,以此支持细粒度的更新和部署策略。

UnitedDeployment介绍

UnitedDeployment是Kruise社区提供的控制器。UnitedDeployment控制器支持通过自定义模板和Subset去创建和管理多个Workload,每个Subset都与一个Workload相关联。

使用限制

Subset仅可以是StatefulSet、Advanced StatefulSet、CloneSet、Deployment类型。关于资源的详细信息,请参见使用OpenKruise部署云原生应用

前提条件

场景一:多可用区的精细化部署场景

为了应用的高可用性,往往需要将应用的计算或存储资源分布在多个可用区上。以下示例介绍如何通过UnitedDeployment实现多可用区的精细化调度场景。

image
  1. 准备3个位于不同可用区的节点,为3个节点分别打上对应可用区的label。例如位于可用区a的节点打上Label:node=zone-a、可位于用区b的节点打上Label:node=zone-b、位于可用区c的节点打上Label:node=zone-c。

    kubectl label node cn-beijing.10.80.20.131 node=zone-a
    node/cn-beijing.10.80.20.131 labeled #节点10.80.20.131已打上Label node=zone-a。
    kubectl label node cn-beijing.10.80.20.132 node=zone-b
    node/cn-beijing.10.80.20.132 labeled  #节点10.80.20.132已打上Label node=zone-b。
    kubectl label node cn-beijing.10.80.20.133 node=zone-c
    node/cn-beijing.10.80.20.133 labeled  #节点10.80.20.133已打上Label node=zone-c。
  2. 准备自定义的UnitedDeployment对象YAML。

    apiVersion: apps.kruise.io/v1alpha1
    kind: UnitedDeployment
    metadata:
      name: sample-ud
    spec:
      replicas: 6
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: sample
      template:
        # statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate
        statefulSetTemplate:
          metadata:
            labels:
              app: sample
          spec:
            selector:
              matchLabels:
                app: sample
            template:
              metadata:
                labels:
                  app: sample
              spec:
                containers:
                - image: nginx:alpine
                  name: nginx
      topology:
        subsets:
        - name: subset-a
          nodeSelectorTerm:
            matchExpressions:
            - key: node
              operator: In
              values:
              - zone-a
          replicas: 1
        - name: subset-b
          nodeSelectorTerm:
            matchExpressions:
            - key: node
              operator: In
              values:
              - zone-b
          replicas: 50%
        - name: subset-c
          nodeSelectorTerm:
            matchExpressions:
            - key: node
              operator: In
              values:
              - zone-c
      updateStrategy:
        manualUpdate:
          partitions:
            subset-a: 0
            subset-b: 0
            subset-c: 0
        type: Manual

    YAML详解:

    在UnitedDeployment对象中,自定义工作负载的template,并为每个可用区定义一个Subset。

    • 工作负载是StatefulSet,工作负载模板定义在statefulSetTemplate字段中。UnitedDeployment会在每个Subset下按照这个模板生成一个StatefulSet。

    • Subsets字段为每个可用区定义了一个对应的Subset:subset-a的Pod将部署到Label为node=zone-a的节点,subset-b的Pod将部署到Label为node=zone-b的节点,subset-c的Pod将部署到Label为node=zone-c的节点。

  3. 执行如下命令,部署UnitedDeployment。

    kubectl apply -f test.yaml

    预期输出:

    uniteddeployment.apps.kruise.io/sample-ud created

    预期输出表明,UnitedDeployment已创建成功。

  4. 执行如下命令,查看Pod和Statefulset是否被成功创建。

    kubectl get pod
    NAME                                     READY   STATUS    RESTARTS   AGE
    sample-ud-subset-a-cplwg-0               1/1     Running   0          6m5s
    sample-ud-subset-b-rj7kt-0               1/1     Running   0          6m4s
    sample-ud-subset-b-rj7kt-1               1/1     Running   0          5m49s
    sample-ud-subset-b-rj7kt-2               1/1     Running   0          5m43s
    sample-ud-subset-c-g6jvx-0               1/1     Running   0          6m5s
    sample-ud-subset-c-g6jvx-1               1/1     Running   0          5m51s
    
    kubectl get statefulset
    NAME                       READY   AGE
    sample-ud-subset-a-cplwg   1/1     7m34s
    sample-ud-subset-b-rj7kt   3/3     7m34s
    sample-ud-subset-c-g6jvx   2/2     7m34s

    预期输出表明,Pod和Statefulset已创建成功。

场景二:ECS、ECI资源混合使用场景

为了应对业务高峰,需要用多种手段保证集群节点资源充足,同时又希望维持合理的成本,所以常常需要在同一个集群内让应用既可部署在ECS上,也可以在ECS资源紧张时自动使用ECI。

image
  1. 准备自定义的UnitedDeployment对象YAML。

    apiVersion: apps.kruise.io/v1alpha1
    kind: UnitedDeployment
    metadata:
      name: ud-nginx
    spec:
      replicas: 6
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: ud-nginx
      template:
        # statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate
        deploymentTemplate:
          metadata:
            labels:
              app: ud-nginx
          spec:
            selector:
              matchLabels:
                app: ud-nginx
            template:
              metadata:
                labels:
                  app: ud-nginx
              spec:
                containers:
                - image: nginx:alpine
                  name: nginx
      topology:
        subsets:
        - name: subset-a
          nodeSelectorTerm:
            matchExpressions:
            - key: alibabacloud.com/nodepool-id
              operator: In
              values:
              - np92019eec42004d878fcdc990fcb9****   #需要替换为节点池A的ID。
          replicas: 1
        - name: subset-b
          nodeSelectorTerm:
            matchExpressions:
            - key: alibabacloud.com/nodepool-id
              operator: In
              values:
              - np011de1f2de3d48bd8a92a015fc5c****  #需要替换为节点池B的ID。
          replicas: 1
        - name: subset-c
          nodeSelectorTerm:
            matchExpressions:
            - key: node
              operator: In
              values:
              - zone-c
          replicas: 1
        - name: subset-eci
          nodeSelectorTerm:
            matchExpressions:
            - key: type
              operator: In
              values:
              - virtual-kubelet
          tolerations:
          - key: virtual-kubelet.io/provider
            operator: Exists
          replicas: 3
      updateStrategy:
        manualUpdate:
          partitions:
            subset-a: 0
            subset-b: 0
            subset-c: 0
        type: Manual

    YAML详解:

    • subset-a、subset-b和subset-c均使用ECS资源,并指定了副本数,这三个Subset的指定副本数的Pod将部署在满足条件的ECS节点上。

    • 最后的subset-d具备部署在ECI上的nodeSelectorTerm和Toleration,因此会被部署在ECI节点资源上。

  2. 执行如下命令,部署UnitedDeployment。

    kubectl apply -f test.yaml

    预期输出:

    uniteddeployment.apps.kruise.io/ud-nginx created
  3. 执行如下命令,查看Pod是否成功创建。

    kubectl get pod -o wide
    NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE                            NOMINATED NODE   READINESS GATES
    ud-nginx-subset-a-7lbtd-5b5bd77549-5bw6l   1/1     Running   0          73s   192.168.0.126    cn-hangzhou.10.80.20.131       <none>           <none>
    ud-nginx-subset-b-nvvfw-5c9bcd6766-lv6sp   1/1     Running   0          73s   192.168.10.239   cn-hangzhou.10.80.20.132      <none>           <none>
    ud-nginx-subset-c-r2mkr-7675856649-vh7zr   1/1     Running   0          73s   192.168.0.127    cn-hangzhou.10.80.20.133       <none>           <none>
    ud-nginx-subset-d-m78fd-7796b66fd8-7p52j   1/1     Running   0          73s   192.168.0.130    virtual-kubelet-cn-hangzhou-h   <none>           <none>
    ud-nginx-subset-d-m78fd-7796b66fd8-fd7f7   1/1     Running   0          73s   192.168.0.129    virtual-kubelet-cn-hangzhou-h   <none>           <none>
    ud-nginx-subset-d-m78fd-7796b66fd8-mn4qb   1/1     Running   0          73s   192.168.0.131    virtual-kubelet-cn-hangzhou-h   <none>           <none>

    预期输出表明,Pod按照UnitedDeployment对象定义部署,符合预期。

场景三:UnitedDeployment和HPA配合使用

说明

如您需要HPA和UnitedDeployment配合使用,您的Kruise版本需要为v1.5.0及以上。

当您想在副本数目达到某个数值后,控制超出副本的调度策略,比如副本数10以内优先使用包年包月的ECS资源,超出10个不超出20个的使用Spot资源,超出20个的再使用ECI资源。UnitedDeployment需要使用字段maxReplicas,超出则使用优先级低的资源。可以通过设置HPA来控制UnitedDeployment的水平扩缩,Pod扩容和缩容的顺序是按自定义的资源顺序来执行的。

image
  1. 准备test.yaml文件。

    apiVersion: apps.kruise.io/v1alpha1
    kind: UnitedDeployment
    metadata:
      name: ud-nginx
    spec:
      replicas: 6
      selector:
        matchLabels:
          app: sample
      template:
        deploymentTemplate:
          metadata:
            labels:
              app: sample
          spec:
            selector:
              matchLabels:
                app: sample
            template:
              metadata:
                labels:
                  app: sample
              spec:
                containers:
                - image: nginx:alpine
                  name: nginx
                  resources:
                    requests:
                      cpu: "500m"
      topology:
        subsets:
        - name: ecs
          maxReplicas: 4
        - name: eci
          maxReplicas: null
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: united-deployment-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps.kruise.io/v1alpha1
        kind: UnitedDeployment
        name: ud-nginx  #需要替换为UnitedDeployment的实际Name。
      minReplicas: 4
      maxReplicas: 10
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 50

    YAML详解:

    • 第4个副本,Pod会调度到ECS上(满足ECS最多规划4个副本的需求)。

    • 第5个副本,Pod会调度到ECI上(满足ECI弹性需求)。

    • 5个副本缩容到4个副本时,优先缩容ECI上的副本。

    • 缩容到4个副本以下时,缩容部署在ECS上的Pods。

    HPA与UnitedDeployment配合使用时,HPA的scaleTargetRef字段配置为UnitedDeployment及其名称即可。

  2. 执行如下命令,部署UnitedDeployment。

    kubectl apply -f test.yaml

    预期输出:

    horizontalpodautoscaler.autoscaling/united-deployment-hpa created

    预期输出表明,UnitedDeployment已创建成功。

  3. 执行如下命令,查看Pod状态。

    kubectl get pod -o wide
    NAME                                  READY   STATUS    RESTARTS       AGE   IP               NODE                       NOMINATED NODE   READINESS GATES
    ud-nginx-eci-dxfbz-864bdb77b-2d4t9    1/1     Running   0             3m9s   192.168.5.129   cn-hangzhou.192.168.5.120   <none>           <none>
    ud-nginx-eci-dxfbz-864bdb77b-zppfh    1/1     Running   0             3m9s   192.168.8.11    cn-hangzhou.192.168.8.251   <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-5mlgh   1/1     Running   0             3m9s   192.168.8.4     cn-hangzhou.192.168.8.251   <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-6bdkz   1/1     Running   0             3m9s   192.168.6.145   cn-hangzhou.192.168.6.32    <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-dnsfl   1/1     Running   0             3m9s   192.168.6.150   cn-hangzhou.192.168.6.20    <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-mrzwc   1/1     Running   0             3m9s   192.168.5.128   cn-hangzhou.192.168.5.120   <none>           <none>

    预期输出表明,Deployment的Pod副本数目是根据设定的调度策略进行动态分配。

  4. 触发HPA缩容,然后执行如下命令,查看Pod状态。

    kubectl get pod -o wide
    NAME                                  READY   STATUS    RESTARTS       AGE    IP              NODE                        NOMINATED NODE   READINESS GATES
    ud-nginx-ecs-5lm7r-868c4ccd5d-5mlgh   1/1     Running   0             8m14s   192.168.8.4     cn-hangzhou.192.168.8.251   <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-6bdkz   1/1     Running   0             8m14s   192.168.6.145   cn-hangzhou.192.168.6.32    <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-dnsfl   1/1     Running   0             8m14s   192.168.6.150   cn-hangzhou.192.168.6.20    <none>           <none>
    ud-nginx-ecs-5lm7r-868c4ccd5d-mrzwc   1/1     Running   0             8m14s   192.168.5.128   cn-hangzhou.192.168.5.120   <none>           <none>

    预期输出表明,6个副本缩容到4个副本,会优先将调度到ECI上的副本删除。