目标:一个应用两个副本,需要分布在两个区域(比如两个机房),实现业务最大程度容灾。

1、实现方法一:pod反亲和性 和topologyKey

反亲和:简单理解就是新的pod不能和具有xxx=xxx标签的pod调度到同一位置

节点标签,设置了两组不同的标签,zone,一组是master01 node01,假设在shenzhen ;一组是node02 node03,假设在guangzhou 后面需要用到

图片.png

实现原理,需要用到pod反亲和,这样两个pod不会调度到同一节点,同时需要用到topologyKey(同一位置)

最终yaml如下: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-affinity-test labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: zone containers: - name: nginx image: nginx:latest resources: limits: cpu: 100m
memory: 256Mi
requests: cpu: 100m
memory: 128Mi command: - sleep - "360000000"

图片.png

yaml截图如下: 图片.png

把master01和node01打污点后,如果topologyKey: "kubernetes.io/hostname",那么表示这两个pod不能调度到同一位置,即同一个节点,就会调度到node02 和node03

图片.png

当topologyKey: zone 表示不能在同一位置(节点标签key为zone的节点),因为node02和node03节点 都有zone的标签(属于同一位置)。那么两个pod将只能运行一个,另一个无法调度。 图片.png

综上所述:topologyKey: zone可以实现两个pod分布在两个zone区域上,但无法扩容。

2、实现方式二:拓扑分布约束(Topology Spread Constraints)

你可以使用 拓扑分布约束(Topology Spread Constraints) 来控制 Pods 在集群内故障域 之间的分布,例如区域(Region)、可用区(Zone)、节点和其他用户自定义拓扑域。 这样做有助于实现高可用并提升资源利用率。

拓扑分布约束 https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints/ 在 v1.18 之前的 Kubernetes 版本中,如果要使用 Pod 拓扑扩展约束,你必须在 API 服务器 和调度器 中启用 EvenPodsSpread 特性门控 具体实现yaml如下: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-topology-test labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: nginx containers: - name: nginx image: nginx:latest resources: limits: cpu: 100m
memory: 256Mi
requests: cpu: 100m
memory: 128Mi command: - sleep - "360000000" yaml截图如下: 图片.png

这种方式创建的pod分布在两个zone区域。 其中maxSkew:给定拓扑类型中任意两个拓扑域中 匹配的 pod 之间的最大允许差值。 topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值, 则调度器会将这两个节点视为处于同一拓扑域中。调度器试图在每个拓扑域中放置数量 均衡的 Pod。 whenUnsatisfiable: 指示如果 Pod 不满足分布约束时如何处理: DoNotSchedule(默认)告诉调度器不要调度。 ScheduleAnyway 告诉调度器仍然继续调度,只是根据如何能将偏差最小化来对 节点进行排序。 实际测试扩容副本时,满足该约束条件。 已知局限性 Deployment 缩容操作可能导致 Pod 分布不平衡。---实际测试确实存在 具有污点的节点上的 Pods 也会被统计