实现ECI Pod可用区打散以及亲和调度

更新时间:2025-04-21 06:02:11

高可用和高性能是分布式任务执行的关键要求。在ACK托管集群Pro中,您可以通过Kubernetes原生调度语义实现ECI Pod的跨可用区打散和亲和性部署,以满足高可用和高性能的要求。

背景信息

在某些情况下,您可能需要将Pod分散部署到多个不同的可用区,或者部署到某个指定可用区,以实现高可用或者高性能的需求。此时,您可以通过Kubernetes原生调度语义中的Pod拓扑分布约束(topologySpreadConstraints)、节点亲和性(nodeAffinity)和Pod亲和性(podAffinity)来实现。

重要

仅当Pod中带有nodeAffinitypodAffinitytopologySpreadConstraints字段或存在匹配的ResourcePolicy时才会启用可用区打散或亲和调度。

更多信息,请参见Kubernetes官方文档:

前提条件

  • 已有ACK托管集群Pro,并且满足以下要求:

  • 调度ECI Pod时,已在eci-profile中配置多个期望调度的目标可用区(即配置多个交换机)。

  • 已确保Pod中带有nodeAffinitypodAffinitytopologySpreadConstraints字段或存在匹配的ResourcePolicy。

    说明

    若您希望Pod能够调度到Arm架构的Virtual Node上,需要在Pod上添加对应污点的污点容忍。

注意事项

  • 目前仅支持设置topologyKeytopology.kubernetes.io/zone的用法。

  • 如果ECI Pod通过k8s.aliyun.com/eci-schedule-strategy: "VSwitchOrdered"Annotation声明了多可用区调度策略为按照交换机的指定顺序,当前功能将不生效。

  • 如果ECI Pod通过k8s.aliyun.com/eci-fail-strategy: "fail-fast"Annotation设置了Pod故障处理策略为fail-fast,当前功能将不生效。

实现ECI Pod可用区打散以及亲和调度

下文将在v1.22版本的ACK托管集群Pro中演示ECI Pod可用区打散以及亲和调度功能。

示例一:通过拓扑分布约束(Topology Spread Constraints)实现跨可用区打散

  1. 在工作负载声明中增加拓扑分布约束。

    PodSpec字段中或Deployment、Job等工作负载的PodTemplateSpec字段中,可以通过以下方式声明一个拓扑分布约束。

      topologySpreadConstraints:
        - maxSkew: <integer>
          minDomains: <integer> # 可选,从v1.25开始成为Beta。
          topologyKey: <string>
          whenUnsatisfiable: <string>
          labelSelector: <object>
          matchLabelKeys: <list> # 可选,从v1.27开始成为Beta。
          nodeAffinityPolicy: [Honor|Ignore] # 可选,从v1.26开始成为Beta。
          nodeTaintsPolicy: [Honor|Ignore] # 可选,从v1.26开始成为Beta。

    本示例将创建一个在多个可用区上均匀分布的Deployment。以下为该DeploymentYAML文件。

    展开查看YAML文件

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: with-pod-topology-spread
      labels:
        app: with-pod-topology-spread
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: with-pod-topology-spread
      template:
        metadata:
          labels:
            app: with-pod-topology-spread
        spec:
          affinity:
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 1
                preference:
                  matchExpressions:
                  - key: type
                    operator: NotIn
                    values:
                    - virtual-kubelet
          topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: DoNotSchedule
              labelSelector:
                matchLabels:
                  app: with-pod-topology-spread
          tolerations:
            - key: "virtual-kubelet.io/provider"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
          - name: with-pod-topology-spread
            image: registry.k8s.io/pause:2.0
            resources:
              requests:
                cpu: "1"
                memory: "256Mi"

    参数

    说明

    参数

    说明

    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: type
          operator: NotIn
          values:
          - virtual-kubelet

    表示Pod将优先被调度到ECS节点上。

    关于参数的详细信息,请参见节点亲和性

    topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: with-pod-topology-spread

    表示Pod必须在多个可用区上均匀部署。

    关于参数的详细信息,请参见topologySpreadConstraints字段

    tolerations:
      - key: "virtual-kubelet.io/provider"
        operator: "Exists"
        effect: "NoSchedule"

    调度器容忍了Virtual Node上的污点,使得Pod能够被调度到Virtual Node上。

    关于参数的详细信息,请参见容忍度

    说明

    若您希望Pod能够调度到Arm架构的Virtual Node上,需要在Pod上添加对应污点的污点容忍。

  2. 创建工作负载。

    将上述YAML保存为deployment.yaml,并执行以下命令部署Deployment。

    kubectl apply -f deployment.yaml
  3. 验证工作负载调度结果。

    • 查看生产出的Pod所在的节点。

      kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>"
    • 查看生产出的Pod在各个可用区中的数量。

      kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c

示例二:通过nodeAffinitypodAffinity实现可用区亲和

  1. 在工作负载申明中增加亲和性约束。

    本示例将创建在单个可用区上聚集分布的Deployment。以下为该DeploymentYAML文件。

    展开查看YAML文件

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: with-affinity
      labels:
        app: with-affinity
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: with-affinity
      template:
        metadata:
          labels:
            app: with-affinity
        spec:
          affinity:
            podAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - with-affinity
                topologyKey: topology.kubernetes.io/zone
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 1
                preference:
                  matchExpressions:
                  - key: type
                    operator: NotIn
                    values:
                    - virtual-kubelet
          tolerations:
            - key: "virtual-kubelet.io/provider"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
          - name: with-affinity
            image: registry.k8s.io/pause:2.0

    参数

    说明

    参数

    说明

    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - with-affinity
    		topologyKey: topology.kubernetes.io/zone

    表示Pod必须部署在单个可用区上。

    关于参数的详细信息,请参见节点亲和性

    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: type
            operator: NotIn
            values:
            - virtual-kubelet

    表示Pod将优先被调度到ECS节点上。

    关于参数的详细信息,请参见节点亲和性

    tolerations:
      - key: "virtual-kubelet.io/provider"
        operator: "Exists"
        effect: "NoSchedule"

    调度器容忍了Virtual Node上的污点,使得Pod能够被调度到Virtual Node上。

    关于参数的详细信息,请参见容忍度

    若您希望指定可用区进行部署,可以将示例中的podAffinity删去,在nodeAffinity添加如下约束。下方约束表明Pod必须在可用区cn-beijing-a上进行部署。

    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - cn-beijing-a
  2. 创建工作负载。

    将上面的代码保存为deployment.yaml,并执行以下命令部署Deployment。

    kubectl apply -f deployment.yaml
  3. 验证工作负载调度结果。

    • 通过以下命令查看生产出的Pod所在的节点。

      kubectl get po -lapp=with-affinity -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>"
    • 通过以下命令查看生产出的Pod在各个可用区中的数量。

      kubectl get po -lapp=with-affinity -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c

ECI严格拓扑打散功能介绍

在保持默认状态不变的情况下,当配置了强制打散约束时,Scheduler会将所有Pod均匀放置到所有可用区上,但并不考虑ECI Pod的生产结果。如下图所示,假设将打散功能的maxSkew设置为1。关于maxSkew,请参见maxSkew

image

此时若可用区BC中生产ECI Pod失败,则可用区A上会放置2ECI Pod,其他两个可用区没有ECI Pod,从而破坏打散功能的maxSkew约束。

当严格拓扑打散功能开启后,调度器将严格保证Pod的强制打散需求得到满足。Scheduler会在可用区A、B、C上各放置1Pod,剩下的Pod将处于Pending状态,等待现有Pod生产,如下图所示。

image

PodA1生产成功后,Pending状态的Pod将继续Pending,这是由于可用区B以及可用区C上的ECI Pod仍然可能生产失败,Pod放置于任意可用区仍然可能导致生产结束后破坏maxSkew约束。当PodB1生产成功后,Scheduler将会放置一个Pod在可用区C。如下图所示,其中绿色背景的Pod为生产完成的Pod。

image

若您不需要严格拓扑打散功能,请将拓扑打散约束中的调度条件whenUnsatisfiable设置为ScheduleAnyway。详细信息,请参见分布约束定义

  • 本页导读 (1)
  • 背景信息
  • 前提条件
  • 注意事项
  • 实现ECI Pod可用区打散以及亲和调度
  • 示例一:通过拓扑分布约束(Topology Spread Constraints)实现跨可用区打散
  • 示例二:通过nodeAffinity和podAffinity实现可用区亲和
  • ECI严格拓扑打散功能介绍
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等