UnitedDeployment支持通过弹性单元Subset来灵活、便捷地管理多个同质的工作负载。例如,当一个Deployment需要部署在多个可用区时,您可以为每个可用区的Deployment定义一个Subset。UnitedDeployment会基于Subset实现细粒度的资源更新和部署,无需您手动配置多个Deployment YAML文件。您也可以将UnitedDeployment和HPA配合使用,在集群有计算资源混用的场景下实现Pod的顺序扩容和逆序缩容,从而节省资源成本。
您可以参见Kruise官方文档UnitedDeployment了解更多关于UnitedDeployment的信息。下文结合典型使用场景介绍如何配置UnitedDeployment YAML。
支持的工作负载类型
仅支持StatefulSet、Advanced StatefulSet、CloneSet和Deployment。更多信息,请参见使用OpenKruise部署云原生应用。
前提条件
已安装ack-kruise组件。详细信息,请参见管理组件。
如需使用ECI资源,需已安装ACK Virtual Node组件,请参见管理组件。
已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
场景一:UnitedDeployment和HPA配合使用场景
如果您的集群存在多种计算资源,您可以在UnitedDeployment的YAML中定义所需使用的Subset,通过maxReplicas
字段配置当工作负载副本数达到某个数值时,超出的副本如何调度。使用HPA来控制UnitedDeployment的水平扩缩时,Pod扩容和缩容顺序支持按照自定义的资源顺序执行顺序扩容和逆序缩容操作。您需要将HPA的scaleTargetRef
字段配置为UnitedDeployment
及其名称。
使用本方案时,OpenKruise版本需为v1.5.0及以上。关于组件的变更说明,请参见OpenKruise。
以下示例中,假设您集群中存在节点池A(包含ECS包年包月实例)、节点池B(包含Spot实例),期望Pod优先部署到ECS包年包月的节点上,然后再部署到抢占式实例上,在资源不足时使用ECI资源。
参见以下自定义UnitedDeployment YAML准备test.yaml文件。
以下UnitedDeployment文件中配置了Deployment的
template
,并定义了3个Subset。subset-a、subset-b分别使用节点池A和节点池B的资源,即分别使用ECS包年包月实例和抢占式实例,副本均为1。
subset-c具备部署在ECI上的
nodeSelectorTerm
和tolerations
,因此会被部署在ECI节点资源上,副本为3。
apiVersion: apps.kruise.io/v1alpha1 kind: UnitedDeployment metadata: name: ud-nginx spec: replicas: 6 revisionHistoryLimit: 10 selector: matchLabels: app: ud-nginx template: deploymentTemplate: metadata: labels: app: ud-nginx spec: selector: matchLabels: app: ud-nginx template: metadata: labels: app: ud-nginx spec: containers: - image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0 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: 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
执行如下命令,部署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.XX.XX.126 cn-hangzhou.10.XX.XX.131 <none> <none> ud-nginx-subset-b-nvvfw-5c9bcd6766-lv6sp 1/1 Running 0 73s 192.XX.XX.239 cn-hangzhou.10.XX.XX.132 <none> <none> ud-nginx-subset-c-m78fd-7796b66fd8-7p52j 1/1 Running 0 73s 192.XX.XX.130 virtual-kubelet-cn-hangzhou-h <none> <none> ud-nginx-subset-c-m78fd-7796b66fd8-fd7f7 1/1 Running 0 73s 192.XX.XX.129 virtual-kubelet-cn-hangzhou-h <none> <none> ud-nginx-subset-c-m78fd-7796b66fd8-mn4qb 1/1 Running 0 73s 192.XX.XX.131 virtual-kubelet-cn-hangzhou-h <none> <none>
预期输出表明,Pod按照UnitedDeployment定义的配置部署到不同Subset上,符合预期。
场景二:多可用区部署场景
为了保障应用的高可用性,您可能需要将应用的计算或存储资源分布在多个可用区上。您可以为不同可用区的节点打上对应可用区的Label,然后在UnitedDeployment的YAML中指定不同Subset下Pod应该调度到哪个可用区的节点上。
准备3个位于不同可用区的节点,参见下方命令为3个节点分别打上对应可用区的label。
例如,位于可用区a的节点打上Label
node=zone-a
、可用区b的节点打上node=zone-b
、可用区c的节点打上node=zone-c
。kubectl label node cn-beijing.10.XX.XX.131 node=zone-a node/cn-beijing.10.80.20.131 labeled # 节点10.XX.XX.131已打上Label node=zone-a。 kubectl label node cn-beijing.10.XX.XX.132 node=zone-b node/cn-beijing.10.80.20.132 labeled # 节点10.XX.XX.132已打上Label node=zone-b。 kubectl label node cn-beijing.10.XX.XX.133 node=zone-c node/cn-beijing.10.80.20.133 labeled # 节点10.XX.XX.133已打上Label node=zone-c。
参见以下自定义UnitedDeployment YAML准备test.yaml文件。
以下代码中自定义了StatefulSet的
template
,并为每个可用区定义了一个Subset。在
statefulSetTemplate
字段中定义了StatefulSet的工作负载模板。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的节点。
apiVersion: apps.kruise.io/v1alpha1 kind: UnitedDeployment metadata: name: sample-ud spec: replicas: 6 revisionHistoryLimit: 10 selector: matchLabels: app: sample template: statefulSetTemplate: metadata: labels: app: sample spec: selector: matchLabels: app: sample template: metadata: labels: app: sample spec: containers: - image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0 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
执行如下命令,部署UnitedDeployment。
kubectl apply -f test.yaml
预期输出:
uniteddeployment.apps.kruise.io/sample-ud created
执行以下命令,查看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已创建成功,分别按顺序运行在位于可用区a、b、c的节点上。
场景三:ECS、ECI资源混合使用场景
为了应对业务高峰,您可能需要用多种手段保证集群节点资源充足,同时维持合理的成本。在ACK集群中,您可能需要让应用优先部署在ECS资源上,并在ECS资源紧张时指定后续副本自动调度到ECI Pod上。缩容时,集群也遵循逆序缩容,即先缩容ECI资源,后缩容ECS资源。
以下示例展示如何将第1~4个副本优先调度到ECS资源上,超过4个副本(但不超过10个副本)时再调度到ECI资源上。
参见以下自定义UnitedDeployment YAML准备test.yaml文件。
在
deploymentTemplate
字段中定义了Deployment的工作负载模板。UnitedDeployment会在每个Subset下按照此模板生成一个Deployment。在
subsets
字段中定义了2个Subset:第1~4个副本中,Pod调度到ECS上(满足ECS最多规划4个副本的需求);第5~10个确认副本中,Pod调度到ECI上(满足ECI弹性需求)。
apiVersion: apps.kruise.io/v1alpha1 kind: UnitedDeployment metadata: name: ud-nginx spec: replicas: 6 selector: matchLabels: app: sample template: # statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate deploymentTemplate: metadata: labels: app: sample spec: selector: matchLabels: app: sample template: metadata: labels: app: sample spec: containers: - image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/nginx_optimized:20240221-1.20.1-2.3.0 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
执行如下命令,部署UnitedDeployment。
kubectl apply -f test.yaml
预期输出:
horizontalpodautoscaler.autoscaling/united-deployment-hpa created
执行如下命令,查看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.XX.XX.129 cn-hangzhou.192.XX.XX.120 <none> <none> ud-nginx-eci-dxfbz-864bdb77b-zppfh 1/1 Running 0 3m9s 192.XX.XX.11 cn-hangzhou.192.XX.XX.251 <none> <none> ud-nginx-ecs-5lm7r-868c4ccd5d-5mlgh 1/1 Running 0 3m9s 192.XX.XX.4 cn-hangzhou.192.XX.XX.251 <none> <none> ud-nginx-ecs-5lm7r-868c4ccd5d-6bdkz 1/1 Running 0 3m9s 192.XX.XX.145 cn-hangzhou.192.XX.XX.32 <none> <none> ud-nginx-ecs-5lm7r-868c4ccd5d-dnsfl 1/1 Running 0 3m9s 192.XX.XX.150 cn-hangzhou.192.XX.XX.20 <none> <none> ud-nginx-ecs-5lm7r-868c4ccd5d-mrzwc 1/1 Running 0 3m9s 192.XX.XX.128 cn-hangzhou.192.XX.XX.120 <none> <none>
预期输出表明,Deployment的Pod副本数目已根据设定的调度策略完成动态分配,即前4个副本调度到ECS资源上,第5个副本起,调度到ECI资源上。
触发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上的副本删除。
相关文档
如需同时扩容多个可用区的节点,请参见多可用区同时快速弹性扩容。
推荐您搭配节点伸缩方案使用,在集群的容量规划无法满足应用Pod调度时自动扩容节点资源,请参见节点伸缩概述。