W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
FEATURE STATE: Kubernetes v1.19 [stable]
你可以使用 拓撲分布約束(Topology Spread Constraints) 來控制 Pods 在集群內(nèi)故障域 之間的分布,例如區(qū)域(Region)、可用區(qū)(Zone)、節(jié)點和其他用戶自定義拓撲域。 這樣做有助于實現(xiàn)高可用并提升資源利用率。
拓撲分布約束依賴于節(jié)點標(biāo)簽來標(biāo)識每個節(jié)點所在的拓撲域。 例如,某節(jié)點可能具有標(biāo)簽:?node=node1,zone=us-east-1a,region=us-east-1
?
假設(shè)你擁有具有以下標(biāo)簽的一個 4 節(jié)點集群:
NAME STATUS ROLES AGE VERSION LABELS
node1 Ready <none> 4m26s v1.16.0 node=node1,zone=zoneA
node2 Ready <none> 3m58s v1.16.0 node=node2,zone=zoneA
node3 Ready <none> 3m17s v1.16.0 node=node3,zone=zoneB
node4 Ready <none> 2m43s v1.16.0 node=node4,zone=zoneB
那么,從邏輯上看集群如下:
你可以復(fù)用在大多數(shù)集群上自動創(chuàng)建和填充的常用標(biāo)簽, 而不是手動添加標(biāo)簽。
?pod.spec.topologySpreadConstraints
? 字段定義如下所示:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
你可以定義一個或多個 ?topologySpreadConstraint
? 來指示 kube-scheduler 如何根據(jù)與現(xiàn)有的 Pod 的關(guān)聯(lián)關(guān)系將每個傳入的 Pod 部署到集群中。字段包括:
whenUnsatisfiable
?的 取值,其語義會有不同。whenUnsatisfiable
?等于 "DoNotSchedule" 時,?maxSkew
?是目標(biāo)拓撲域 中匹配的 Pod 數(shù)與全局最小值之間可存在的差異。whenUnsatisfiable
?等于 "ScheduleAnyway" 時,調(diào)度器會更為偏向能夠降低 偏差值的拓撲域。DoNotSchedule
?(默認)告訴調(diào)度器不要調(diào)度。ScheduleAnyway
?告訴調(diào)度器仍然繼續(xù)調(diào)度,只是根據(jù)如何能將偏差最小化來對 節(jié)點進行排序。當(dāng) Pod 定義了不止一個 ?topologySpreadConstraint
?,這些約束之間是邏輯與的關(guān)系。 kube-scheduler 會為新的 Pod 尋找一個能夠滿足所有約束的節(jié)點。
你可以執(zhí)行 ?kubectl explain Pod.spec.topologySpreadConstraints
? 命令以 了解關(guān)于 topologySpreadConstraints 的更多信息。
假設(shè)你擁有一個 4 節(jié)點集群,其中標(biāo)記為 ?foo:bar
? 的 3 個 Pod 分別位于 node1、node2 和 node3 中:
如果希望新來的 Pod 均勻分布在現(xiàn)有的可用區(qū)域,則可以按如下設(shè)置其規(guī)約:
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
foo: bar
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
containers:
- name: pause
image: k8s.gcr.io/pause:3.1
?topologyKey: zone
? 意味著均勻分布將只應(yīng)用于存在標(biāo)簽鍵值對為 "zone:<any value>" 的節(jié)點。 ?whenUnsatisfiable: DoNotSchedule
? 告訴調(diào)度器如果新的 Pod 不滿足約束, 則讓它保持懸決狀態(tài)。
如果調(diào)度器將新的 Pod 放入 "zoneA",Pods 分布將變?yōu)?nbsp;[3, 1],因此實際的偏差 為 2(3 - 1)。這違反了 ?maxSkew: 1
? 的約定。此示例中,新 Pod 只能放置在 "zoneB" 上:
或者
你可以調(diào)整 Pod 規(guī)約以滿足各種要求:
maxSkew
?更改為更大的值,比如 "2",這樣新的 Pod 也可以放在 "zoneA" 上。topologyKey
?更改為 "node",以便將 Pod 均勻分布在節(jié)點上而不是區(qū)域中。 在上面的例子中,如果 ?maxSkew
?保持為 "1",那么傳入的 Pod 只能放在 "node4" 上。whenUnsatisfiable: DoNotSchedule
? 更改為 ?whenUnsatisfiable: ScheduleAnyway
?, 以確保新的 Pod 始終可以被調(diào)度(假設(shè)滿足其他的調(diào)度 API)。 但是,最好將其放置在匹配 Pod 數(shù)量較少的拓撲域中。 (請注意,這一優(yōu)先判定會與其他內(nèi)部調(diào)度優(yōu)先級(如資源使用率等)排序準(zhǔn)則一起進行標(biāo)準(zhǔn)化。)下面的例子建立在前面例子的基礎(chǔ)上。假設(shè)你擁有一個 4 節(jié)點集群,其中 3 個標(biāo)記為 ?foo:bar
? 的 Pod 分別位于 node1、node2 和 node3 上:
可以使用 2 個 TopologySpreadConstraint 來控制 Pod 在 區(qū)域和節(jié)點兩個維度上的分布:
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
foo: bar
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
- maxSkew: 1
topologyKey: node
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
containers:
- name: pause
image: k8s.gcr.io/pause:3.1
在這種情況下,為了匹配第一個約束,新的 Pod 只能放置在 "zoneB" 中;而在第二個約束中, 新的 Pod 只能放置在 "node4" 上。最后兩個約束的結(jié)果加在一起,唯一可行的選擇是放置 在 "node4" 上。
多個約束之間可能存在沖突。假設(shè)有一個跨越 2 個區(qū)域的 3 節(jié)點集群:
如果對集群應(yīng)用 "two-constraints.yaml",會發(fā)現(xiàn) "mypod" 處于 ?Pending
?狀態(tài)。 這是因為:為了滿足第一個約束,"mypod" 只能放在 "zoneB" 中,而第二個約束要求 "mypod" 只能放在 "node2" 上。Pod 調(diào)度無法滿足兩種約束。
為了克服這種情況,你可以增加 ?maxSkew
?或修改其中一個約束,讓其使用 ?whenUnsatisfiable: ScheduleAnyway
?。
如果 Pod 定義了 ?spec.nodeSelector
? 或 ?spec.affinity.nodeAffinity
?, 調(diào)度器將在偏差計算中跳過不匹配的節(jié)點。
假設(shè)你有一個跨越 zoneA 到 zoneC 的 5 節(jié)點集群:
而且你知道 "zoneC" 必須被排除在外。在這種情況下,可以按如下方式編寫 YAML, 以便將 "mypod" 放置在 "zoneB" 上,而不是 "zoneC" 上。同樣,?spec.nodeSelector
? 也要一樣處理。
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
foo: bar
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
foo: bar
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: NotIn
values:
- zoneC
containers:
- name: pause
image: k8s.gcr.io/pause:3.1
調(diào)度器不會預(yù)先知道集群擁有的所有區(qū)域和其他拓撲域。拓撲域由集群中存在的節(jié)點確定。 在自動伸縮的集群中,如果一個節(jié)點池(或節(jié)點組)的節(jié)點數(shù)量為零, 而用戶正期望其擴容時,可能會導(dǎo)致調(diào)度出現(xiàn)問題。 因為在這種情況下,調(diào)度器不會考慮這些拓撲域信息,因為它們是空的,沒有節(jié)點。
這里有一些值得注意的隱式約定:
為集群設(shè)置默認的拓撲分布約束也是可能的。默認拓撲分布約束在且僅在以下條件滿足 時才會應(yīng)用到 Pod 上:
.spec.topologySpreadConstraints
? 設(shè)置任何約束;你可以在 調(diào)度方案(Scheduling Profile) 中將默認約束作為 ?PodTopologySpread
?插件參數(shù)的一部分來設(shè)置。 約束的設(shè)置采用如前所述的 API,只是 ?labelSelector
?必須為空。 選擇算符是根據(jù) Pod 所屬的服務(wù)、副本控制器、ReplicaSet 或 StatefulSet 來設(shè)置的。
配置的示例可能看起來像下面這個樣子:
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
defaultingType: List
默認調(diào)度約束所生成的評分可能與 SelectorSpread 插件 所生成的評分有沖突。 建議你在為 ?
PodTopologySpread
?設(shè)置默認約束是禁用調(diào)度方案中的該插件。
FEATURE STATE: Kubernetes v1.20 [beta]
當(dāng)你使用了默認啟用的 ?DefaultPodTopologySpread
? 特性門控時,原來的 ?SelectorSpread
?插件會被禁用。 kube-scheduler 會使用下面的默認拓撲約束作為 ?PodTopologySpread
?插件的 配置:
defaultConstraints:
- maxSkew: 3
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: ScheduleAnyway
- maxSkew: 5
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway
此外,原來用于提供等同行為的 ?SelectorSpread
?插件也會被禁用。
對于分布約束中所指定的拓撲鍵而言,?PodTopologySpread
?插件不會為不包含這些主鍵的節(jié)點評分。 這可能導(dǎo)致在使用默認拓撲約束時,其行為與原來的 ?SelectorSpread
?插件的默認行為不同,
如果你的節(jié)點不會 同時 設(shè)置 ?kubernetes.io/hostname
? 和 ?topology.kubernetes.io/zone
? 標(biāo)簽,你應(yīng)該定義自己的約束而不是使用 Kubernetes 的默認約束。
如果你不想為集群使用默認的 Pod 分布約束,你可以通過設(shè)置 ?defaultingType
?參數(shù)為 ?List
?并將 ?PodTopologySpread
?插件配置中的 ?defaultConstraints
?參數(shù)置空來禁用默認 Pod 分布約束。
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints: []
defaultingType: List
在 Kubernetes 中,與“親和性”相關(guān)的指令控制 Pod 的調(diào)度方式(更密集或更分散)。
PodAffinity
?,你可以嘗試將任意數(shù)量的 Pod 集中到符合條件的拓撲域中。PodAntiAffinity
?,只能將一個 Pod 調(diào)度到某個拓撲域中。要實現(xiàn)更細粒度的控制,你可以設(shè)置拓撲分布約束來將 Pod 分布到不同的拓撲域下, 從而實現(xiàn)高可用性或節(jié)省成本。這也有助于工作負載的滾動更新和平穩(wěn)地擴展副本規(guī)模。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: