可用区拓扑打散

高可用是分布式任务执行过程中的重要要求,在ACS集群中,您可以通过Kubernetes原生调度语义实现分布式任务的跨可用区打散,以达到高可用区部署的效果。您可以在拓扑分布约束协议字段TopologyKey中指定虚拟节点中的标签,实现对工作负载的可用区打散能力。本文详细介绍在ACS中拓扑约束的约束条件和使用方式。

前提条件

  • 已创建ACS集群。具体操作,请参见创建ACS集群

  • 已安装kube-scheduler组件,详见kube-scheduler

  • 已安装acs-virtual-node,版本为v2.12.0-acs.4及以上。

注意事项

ACS集群内的节点均为虚拟节点。您可以在拓扑分布约束协议字段TopologyKey中指定虚拟节点中的标签,实现对工作负载的可用区打散能力。

针对不同种类的虚拟节点,ACS分别支持以下拓扑标签。

虚拟节点类型

Label

含义

样例

普通虚拟节点

topology.kubernetes.io/zone

网络可用区

topology.kubernetes.io/zone: cn-shanghai-b

ACS支持多种计算类型(compute class),对于不同的compute class,在使用拓扑分布约束的其他协议字段时还存在以下约束。

计算类

协议字段

含义

约束条件

  • 通用型

  • 性能型

labelSelector

用于查找匹配的 Pod,匹配此标签的Pod将被统计,以确定相应拓扑域中Pod的数量。

其他计算类型(如GPU型)的Pod在计算匹配数量时将不参与统计。

matchLabelKeys

配合labelSelector使用的标签键列表,用于选择需要计算分布方式的Pod集合。

  • GPU型

labelSelector

用于查找匹配的 Pod,匹配此标签的Pod将被统计,以确定相应拓扑域中Pod的数量。

其他计算类型(通用型、性能型)的Pod在计算匹配数量时将不参与统计。

matchLabelKeys

配合labelSelector使用的标签键列表,用于选择需要计算分布方式的Pod集合。

nodeAffinityPolicy

表示在计算Pod拓扑分布偏差时将如何处理Pod的 nodeAffinity/nodeSelector。

不支持。

nodeTaintsPolicy

表示在计算Pod拓扑分布偏差时将如何处理节点污点。

不支持。

有关各字段详细信息的说明,请参考拓扑分布约束

操作步骤

  1. 执行以下命令查看集群中的虚拟节点。

    kubectl get node

    预期输出:

    NAME                            STATUS   ROLES   AGE     VERSION
    virtual-kubelet-cn-hangzhou-i   Ready    agent   5h42m   v1.28.3-xx
    virtual-kubelet-cn-hangzhou-j   Ready    agent   5h42m   v1.28.3-xx
  2. 使用以下YAML内容,创建dep-spread-demo.yaml文件。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dep-spread-demo
      labels:
        app: spread-demo
    spec:
      replicas: 4
      selector:
        matchLabels:
          app: spread-demo
      template:
        metadata:
          labels:
            app: spread-demo
        spec:
          containers:
          - name: spread-demo
            image: registry.cn-hangzhou.aliyuncs.com/acs/stress:v1.0.4
            command:
            - "sleep"
            - "infinity"
          # 指定可用区打散条件,maxSkew指定了各可用区之间的Pod数量相差不能超过一个
          topologySpreadConstraints:
          - maxSkew: 1
            topologyKey: topology.kubernetes.io/zone
            whenUnsatisfiable: DoNotSchedule
            labelSelector:
              matchLabels:
                app: spread-demo
  3. 执行以下命令,将dep-spread-demo部署到集群。

    kubectl apply -f dep-spread-demo.yaml
  4. 执行以下命令,查看Pod调度的分布情况。

    kubectl get pod -o wide

    预期输出:

    NAME                               READY   STATUS    RESTARTS   AGE     IP               NODE                            NOMINATED NODE   READINESS GATES
    dep-spread-demo-7c656dbf5f-6twkc   1/1     Running   0          2m29s   192.168.xx.xxx   virtual-kubelet-cn-hangzhou-i   <none>           <none>
    dep-spread-demo-7c656dbf5f-cgxr8   1/1     Running   0          2m29s   192.168.xx.xxx   virtual-kubelet-cn-hangzhou-j   <none>           <none>
    dep-spread-demo-7c656dbf5f-f4fz9   1/1     Running   0          2m29s   192.168.xx.xxx   virtual-kubelet-cn-hangzhou-j   <none>           <none>
    dep-spread-demo-7c656dbf5f-kc6xf   1/1     Running   0          2m29s   192.168.xx.xxx   virtual-kubelet-cn-hangzhou-i   <none>           <none>

    可以看到4个Pod分布在2个可用区。