本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
將工作負載分散到節點和可用區域
在可用區域和節點等故障網域
使用 Pod 拓撲分散限制條件
Kubernetes Pod 拓撲分散限制
-
根據應用程式需求,將 Pod 分散或集中於不同的故障網域。例如,您可以分發 Pod 以實現彈性,也可以集中 Pod 以實現網路效能。
-
結合不同的條件,例如跨可用區域分佈和跨節點分佈。
-
如果無法滿足條件,請指定偏好的動作:
-
使用
whenUnsatisfiable: DoNotSchedule
搭配maxSkew
和 的組合minDomains
來建立排程器的硬性需求。 -
使用
whenUnsatisfiable: ScheduleAnyway
減少maxSkew
。
-
如果故障區域無法使用,則該區域中的 Pod 會變得運作狀態不佳。Kubernetes 會重新排程 Pod,同時盡可能遵守分散限制條件。
Pod 拓撲分散限制條件
下列程式碼顯示使用 Pod 拓撲跨可用區域或跨節點分散限制的範例:
... spec: selector: matchLabels: app: <your-app-label> replicas: 3 template: metadata: labels: <your-app-label> spec: serviceAccountName: <ServiceAccountName> ... topologySpreadConstraints: - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones whenUnsatisfiable: ScheduleAnyway - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes whenUnsatisfiable: ScheduleAnyway
預設的叢集整體拓撲分散限制條件
Kubernetes 現成提供一組預設的拓撲分散限制
defaultConstraints: - maxSkew: 3 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway - maxSkew: 5 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway
注意
需要不同類型的拓撲限制的應用程式可以覆寫叢集層級政策。
預設限制條件會設定較高的 maxSkew
,這不適用於具有少量 Pod 的部署。截至目前為止, KubeSchedulerConfiguration
無法在 Amazon EKS 中變更
拓撲分散限制的 Gatekeeper 政策
強制執行拓撲分散限制的另一個選項是使用 Gatekeeper
下列程式碼範例顯示使用Gatekeeper OPA
政策進行部署。您可以根據您的需求修改政策。例如,僅將政策套用到具有標籤 的部署HA=true
,或使用不同的政策控制器撰寫類似的政策。
第一個範例顯示與 ConstraintTemplate
搭配使用k8stopologyspreadrequired_template.yml
:
apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8stopologyspreadrequired spec: crd: spec: names: kind: K8sTopologySpreadRequired validation: openAPIV3Schema: type: object properties: message: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8stopologyspreadrequired get_message(parameters, _default) =3D msg { not parameters.message msg :=_default } get_message(parameters, _default) =3D msg { msg := parameters.message } violation[{"msg": msg}] { input.review.kind.kind ="Deployment" not input.review.object.spec.template.spec.topologySpreadConstraint def_msg :"Pod Topology Spread Constraints are required for Deployments" msg :get_message(input.parameters, def_msg) }
下列程式碼顯示 constraints
YAML 資訊清單 k8stopologyspreadrequired_constraint.yml
:
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sTopologySpreadRequired metadata: name: require-topologyspread-for-deployments spec: match: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] namespaces: ## Without theses two lines will apply to the whole cluster - "example"
何時使用拓撲分散限制條件
考慮在下列案例中使用拓撲分散限制條件:
-
任何水平擴展的應用程式 (例如,無狀態 Web 服務)
-
具有主動-主動或主動-被動複本的應用程式 (例如,NoSQL 資料庫或快取)
-
具有待命複本的應用程式 (例如,控制器)
可用於水平擴展案例的系統元件,例如,包括下列項目:
-
Cluster Autoscaler
和 Karpenter (使用 replicaCount > 1
和leader-elect = true
)
Pod 親和性與反親和性
在某些情況下,確保節點上執行的特定類型不超過一個 Pod 是有益的。例如,若要避免在相同節點上排程多個網路密集型 Pod,您可以使用反親和性規則搭配 標籤Ingress
或 Network-heavy
。使用 時anti-affinity
,您也可以使用下列的組合:
-
網路最佳化節點上的標記
-
網路密集型 Pod 上的對應公差
-
節點親和性或節點選擇器,以確保網路密集型 Pod 使用網路最佳化執行個體
使用網路密集型 Pod 做為範例。您可能有不同的需求,例如 GPU、記憶體或本機儲存。如需其他使用範例和組態選項,請參閱 Kubernetes 文件
重新平衡 Pod
本節討論在 Kubernetes 叢集中重新平衡 Pod 的兩種方法。第一個 使用適用於 Kubernetes 的 Descheduler。Descheduler 透過強制執行策略來移除違反拓撲分散限制或反親和性規則的 Pod,協助維護 Pod 分佈。第二個方法使用 Karpenter 整合和 bin-packing 功能。合併透過將工作負載合併到較少、更有效率的封裝節點上,持續評估和最佳化資源用量。
如果您不使用 Karpenter,建議使用 Descheduler。如果您同時使用 Karpenter 和 Cluster Autoscaler,則可以將 Descheduler 與 Cluster Autoscaler 用於節點群組。
無群組節點的排程器
移除 Pod 時,無法保證拓撲限制仍滿足。例如,縮減部署規模可能會導致 Pod 分佈不平衡。不過,由於 Kubernetes 僅在排程階段使用 Pod 拓撲分散限制,因此 Pod 在故障網域中會保持不平衡。
若要在這類情況下維持平衡的 Pod 分佈,您可以使用 Descheduler for Kubernetes
Karpenter 整合和 bin-packing 功能
對於使用 Karpenter 的工作負載,您可以使用整合和 bin-packing 功能來最佳化資源使用率,並降低 Kubernetes 叢集中的成本。Karpenter 會持續評估 Pod 置放和節點使用率,並盡可能嘗試將工作負載合併到較少、更有效率的封裝節點。此程序涉及分析資源需求、考慮 Pod 親和性規則等限制條件,以及在節點之間移動 Pod 以改善整體叢集效率。下列程式碼提供範例:
apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h
對於 consolidationPolicy
,您可以使用 WhenUnderutilized
或 WhenEmpty
:
-
當
consolidationPolicy
設定為 時WhenUnderutilized
,Karpenter 會將所有節點視為合併。當 Karpenter 發現節點為空或未使用時,Karpenter 會嘗試移除或取代節點以降低成本。 -
當
consolidationPolicy
設為 時WhenEmpty
,Karpenter 會考慮僅整合不包含工作負載 Pod 的節點。
Karpenter 整合決策並非僅根據您在監控工具中可能看到的 CPU 或記憶體使用率百分比。反之,Karpenter 會根據 Pod 資源請求和潛在的成本最佳化,使用更複雜的演算法。如需詳細資訊,請參閱 Karpenter