Pod 拓扑分布约束及Pod亲和与反亲和调度
ACS 兼容 Kubernetes 原生的 Pod 拓扑分布约束及 Pod 亲和与反亲和调度能力,通过配置 Pod 亲和与 Pod 反亲和控制 Pod 之间的部署关系;也可以使用 Pod 拓扑分布约束控制 Pod 部署到不同的拓扑域,也一样可以实现高可用。因为 ACS 通过虚拟节点与 Kubernetes 实现无缝对接,ACS 限制了 Pod 拓扑分布约束(Pod Topology Spread Constraints)、Pod 间亲和与 Pod 间反亲和(Inter Pod Affinity/Anti-Affinity)部分能力。本文档详细介绍在 ACS 中如何使用这些调度能力。
Pod 拓扑分布约束
使用 Pod 拓扑分布约束(Pod Topology Spread Constraints)可以实现可用区维度的高可用性。
ACS 当前支持 Pod 拓扑分布约束的 topologyKey:
topologyKey | 描述 |
topology.kubernetes.io/zone | Zone 对应阿里云的一个可用区。 |
kubernetes.io/hostname | 按照节点维度打散 |
如果设置的 topologyKey 不在支持的列表中,ACS 在调度时将会忽略这些 topologyKey。
这里举个例子演示如何使用拓扑分布约束。
创建 Namespace,用于演示。
kubectl create ns test
创建一个 Deployment,创建 4 个 Pod,并要求按照可用区强制打散。
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: spread-demo namespace: test labels: app: spread-demo spec: replicas: 4 selector: matchLabels: app: spread-demo template: metadata: labels: app: spread-demo spec: containers: - name: spread-demo image: busybox:latest command: - "sleep" - "360000" topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: spread-demo EOF
查看 Pod 的分布情况。可以看到 4 个 Pod 分布在 2 个可用区。
kubectl -n test get pod -L topology.kubernetes.io/zone NAME READY STATUS RESTARTS AGE ZONE spread-demo-7b7c7d8c6b-8b8gc 1/1 Running 0 46s cn-beijing-i spread-demo-7b7c7d8c6b-c74m4 1/1 Running 0 46s cn-beijing-i spread-demo-7b7c7d8c6b-fkmsl 1/1 Running 0 46s cn-beijing-k spread-demo-7b7c7d8c6b-l7hv4 1/1 Running 0 46s cn-beijing-k
说明Pod 具体分布在哪些可用区取决于当前 ACS 集群通过 vSwitch 关联的可用区。
也可以通过设置 Node Affinity 明确选择要在哪些可用区中部署,此时 Pod 拓扑分布约束会按照指定的可用区进行打散。
Pod 拓扑分布约束存在一些局限性:当工作负载例如 Deployment/StatefulSet 缩容时并不按照拓扑分布约束删除 Pod,也就意味着删除 Pod 后可能会出现分布不均衡的情况。
Pod 亲和与反亲和
使用 Pod 间亲和与 Pod 间反亲和(Inter Pod Affinity/Anti-Affinity)控制 Pod 之间是否部署在同一个可用区或者使其分散在不同的可用区中。
ACS 当前支持 Pod 亲和与反亲和的 topologyKey:
topologyKey | 描述 |
topology.kubernetes.io/zone | Zone 对应阿里云的一个可用区。 |
如果设置的 topologyKey 不在支持的列表中,ACS 在调度时将会忽略这些 topologyKey。
这里举个例子演示如何使用 Pod 间反亲和。
创建 Namespace,用于演示。
kubectl create ns test
创建一个 Deployment,创建 4 个 Pod,并要求按照可用区反亲和。
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: anti-affinity-demo namespace: test labels: app: anti-affinity-demo spec: replicas: 4 selector: matchLabels: app: anti-affinity-demo template: metadata: labels: app: anti-affinity-demo spec: containers: - name: anti-affinity-demo image: busybox:latest command: - "sleep" - "360000" affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - anti-affinity-demo topologyKey: "topology.kubernetes.io/zone" EOF
查看 Pod 的分布情况。可以看到 2 个 Pod 分布在 2 个可用区,另外 2 个 Pod 因为 Pod 间反亲和无法调度。
kubectl -n test get pod -L topology.kubernetes.io/zone NAME READY STATUS RESTARTS AGE ZONE anti-affinity-demo-86f49c9469-jhvpv 1/1 Running 0 2m56s cn-beijing-k anti-affinity-demo-86f49c9469-w9tkq 0/1 Running 0 2m56s cn-beijing-i anti-affinity-demo-86f49c9469-7mk55 0/1 Pending 0 2m56s anti-affinity-demo-86f49c9469-dwscz 0/1 Pending 0 2m56s