通过UnitedDeployment控制器自定义工作负载模板和弹性单元Subset的策略,可以动态分配在各弹性单元上面的副本数目。本文介绍如何在ACK上安装以及使用UnitedDeployment实现弹性伸缩,以此支持细粒度的更新和部署策略。
UnitedDeployment介绍
UnitedDeployment是Kruise社区提供的控制器。UnitedDeployment控制器支持通过自定义模板和Subset去创建和管理多个Workload,每个Subset都与一个Workload相关联。
使用限制
Subset仅可以是StatefulSet、Advanced StatefulSet、CloneSet、Deployment类型。关于资源的详细信息,请参见使用OpenKruise部署云原生应用。
前提条件
已安装ack-kruise组件。详细信息,请参见管理组件。
已通过kubectl工具连接集群。详细信息,请参见获取集群KubeConfig并通过kubectl工具连接集群。
如果使用ECI资源,请安装ACK Virtual Node组件。详细信息,请参见管理组件。
场景一:多可用区的精细化部署场景
为了应用的高可用性,往往需要将应用的计算或存储资源分布在多个可用区上。以下示例介绍如何通过UnitedDeployment实现多可用区的精细化调度场景。
准备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。
准备自定义的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的节点。
执行如下命令,部署UnitedDeployment。
kubectl apply -f test.yaml
预期输出:
uniteddeployment.apps.kruise.io/sample-ud created
预期输出表明,UnitedDeployment已创建成功。
执行如下命令,查看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。
准备自定义的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节点资源上。
执行如下命令,部署UnitedDeployment。
kubectl apply -f test.yaml
预期输出:
uniteddeployment.apps.kruise.io/ud-nginx created
执行如下命令,查看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扩容和缩容的顺序是按自定义的资源顺序来执行的。
准备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及其名称即可。
执行如下命令,部署UnitedDeployment。
kubectl apply -f test.yaml
预期输出:
horizontalpodautoscaler.autoscaling/united-deployment-hpa created
预期输出表明,UnitedDeployment已创建成功。
执行如下命令,查看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副本数目是根据设定的调度策略进行动态分配。
触发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上的副本删除。