4.6. 使用 pod 拓扑分布限制控制 pod 放置
您可以使用 pod 拓扑分布约束,提供对 pod 在节点、区、区域或其他用户定义的拓扑域间的放置的精细控制。在故障域间分布 pod 有助于实现高可用性和效率更高的资源利用率。
4.6.1. 使用案例示例
- 作为管理员,我希望我的工作负载在两个到十五个 pod 之间自动缩放。我希望确保当只有两个 pod 时,它们没有在同一节点上放置,以避免出现单点故障。
- 作为管理员,我希望在多个基础架构区域间平均分配 pod,以降低延迟和网络成本。如果出现问题,我希望确保我的集群可以自我修复。
4.6.2. 重要注意事项
- OpenShift Dedicated 集群中的 Pod 由 工作负载控制器 管理,如部署、有状态集或守护进程集。这些控制器为一组 pod 定义所需状态,包括如何在集群的节点间分布和扩展。您应该对组中的所有 pod 设置相同的 pod 拓扑分布限制,以避免混淆。在使用工作负载控制器(如部署)时,pod 模板通常会为您处理它。
-
混合不同的 pod 拓扑分布限制可能会导致 OpenShift Dedicated 行为混淆和故障排除。您可以通过确保拓扑域中的所有节点一致标记来避免这种情况。OpenShift Dedicated 会自动填充已知的标签,如
kubernetes.io/hostname
。这有助于避免手动标记节点的需求。这些标签提供基本的拓扑信息,确保集群中具有一致的节点标签。 - 只有同一命名空间中的 pod 在因为约束而分散时才会被匹配和分组。
- 您可以指定多个 pod 拓扑分散约束,但您必须确保它们不会相互冲突。必须满足所有 pod 拓扑分布约束才能放置 pod。
4.6.3. 了解 skew 和 maxSkew
skew 指的是在不同拓扑域(如区或节点)之间与指定标签选择器匹配的 pod 数量的不同。
skew 是为每个域计算的,在那个域中 pod 数量与调度最小 pod 的 pod 数量之间绝对不同。设置 maxSkew
值会引导调度程序来维护均衡的 pod 发行版。
4.6.3.1. skew 计算示例
您有三个区域(A、B 和 C),您希望在这些区间平均分配 pod。如果区域 A 具有 5 个 pod,区域 B 具有 3 个 pod,并且区域 C 具有 2 个 pod,以查找 skew,您可以减去域中当前从每个区域中 pod 数量最低的 pod 数量。这意味着区域 A 的 skew 是 3,区域 B 的 skew 是 1,并且区域 C 的 skew 为 0。
4.6.3.2. maxSkew 参数
maxSkew
参数定义两个拓扑域之间的 pod 数量的最大允许差异或 skew。如果将 maxSkew
设置为 1
,则任何拓扑域中的 pod 数量不应与任何其他域的 1 不同。如果 skew 超过 maxSkew
,调度程序会尝试将新 pod 放置到减少 skew, 遵循限制的方式。
使用前面的示例 skew 计算,skew 值超过默认 maxSkew
值 1
。调度程序将新 pod 放置到区 B 和 zone C 中,以减少 skew 并实现更平衡的分发,确保没有拓扑域超过偏移 1。
4.6.4. pod 拓扑分布约束配置示例
您可以指定哪些 pod 要分组在一起,它们分散到哪些拓扑域以及可以接受的基点。
以下示例演示了 pod 拓扑分散约束配置。
根据区分发与指定标签匹配的 pod 示例
apiVersion: v1 kind: Pod metadata: name: my-pod labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 1 topologyKey: topology.kubernetes.io/zone 2 whenUnsatisfiable: DoNotSchedule 3 labelSelector: 4 matchLabels: region: us-east 5 matchLabelKeys: - my-pod-label 6 containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
- 1
- 两个拓扑域间的 pod 数量的最大差别。默认为
1
,您不能指定0
值。 - 2
- 节点标签的密钥。具有此键和相同值的节点被视为在同一拓扑中。
- 3
- 如果不满足分布式约束,如何处理 pod。默认为
DoNotSchedule
,它会告诉调度程序不要调度 pod。设置为ScheduleAnyway
,它仍然会调度 pod,但调度程序会优先考虑 skew 的根据情况以使集群不要出现不平衡的情况。 - 4
- 匹配此标签选择器的 Pod 在分发时被计算并识别为组,以满足约束要求。确保指定标签选择器,否则就无法匹配 pod。
- 5
- 如果您希望以后正确计数此 Pod 规格,请确保此
Pod
spec 也会设置其标签选择器来匹配这个标签选择器。 - 6
- 用于选择要计算分布的 pod 的 pod 标签键列表。
演示单个 pod 拓扑分布约束的示例
kind: Pod apiVersion: v1 metadata: name: my-pod labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
前面的示例定义了一个 pod 拓扑分布约束的 Pod
规格。它与标记为 region: us-east
的 pod 匹配:在区域间分布,指定 skew 1
,并在不满足这些要求时不调度 pod。
演示多个 pod 拓扑分布限制示例
kind: Pod apiVersion: v1 metadata: name: my-pod-2 labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 topologyKey: node whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east - maxSkew: 1 topologyKey: rack whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
上例定义了有两个 pod 拓扑分布约束的 Pod
规格。在标有 region: us-east
的 pod 上匹配:指定 skew 1
,并在不满足这些要求时不调度 pod。
第一个限制基于用户定义的标签 node
发布 pod,第二个约束根据用户定义的标签 rack
分发 pod。调度 pod 必须满足这两个限制。