一、調(diào)度、搶占和驅(qū)逐
在 Kubernetes 中,調(diào)度 (scheduling) 指的是確保 Pod 匹配到合適的節(jié)點, 以便 kubelet 能夠運行它們。 搶占 (Preemption) 指的是終止低優(yōu)先級的 Pod 以便高優(yōu)先級的 Pod 可以調(diào)度運行的過程。 驅(qū)逐 (Eviction) 是在資源匱乏的節(jié)點上,主動讓一個或多個 Pod 失效的過程。
調(diào)度
- Kubernetes 調(diào)度器
- 將 Pod 指派到節(jié)點
- Pod 開銷
- Pod 拓撲分布約束
- 污點和容忍度
- 動態(tài)資源分配
- 調(diào)度框架
- 調(diào)度器性能調(diào)試
- 擴展資源的資源裝箱
- Pod 調(diào)度就緒
- Pod 干擾?
Pod 干擾
Pod 干擾 是指節(jié)點上的 Pod 被自愿或非自愿終止的過程。
自愿干擾是由應用程序所有者或集群管理員有意啟動的。非自愿干擾是無意的, 可能由不可避免的問題觸發(fā),如節(jié)點耗盡資源或意外刪除。
- Pod 優(yōu)先級和搶占
- 節(jié)點壓力驅(qū)逐
- API 發(fā)起的驅(qū)逐
1、Kubernetes 調(diào)度器
在 Kubernetes 中,調(diào)度?是指將?Pod?放置到合適的節(jié)點上,以便對應節(jié)點上的?Kubelet?能夠運行這些 Pod。
?
調(diào)度概覽
調(diào)度器通過 Kubernetes 的監(jiān)測(Watch)機制來發(fā)現(xiàn)集群中新創(chuàng)建且尚未被調(diào)度到節(jié)點上的 Pod。 調(diào)度器會將所發(fā)現(xiàn)的每一個未調(diào)度的 Pod 調(diào)度到一個合適的節(jié)點上來運行。 調(diào)度器會依據(jù)下文的調(diào)度原則來做出調(diào)度選擇。
如果你想要理解 Pod 為什么會被調(diào)度到特定的節(jié)點上, 或者你想要嘗試實現(xiàn)一個自定義的調(diào)度器,這篇文章將幫助你了解調(diào)度。
kube-scheduler
kube-scheduler?是 Kubernetes 集群的默認調(diào)度器,并且是集群?控制面?的一部分。 如果你真得希望或者有這方面的需求,kube-scheduler 在設計上允許你自己編寫一個調(diào)度組件并替換原有的 kube-scheduler。
Kube-scheduler 選擇一個最佳節(jié)點來運行新創(chuàng)建的或尚未調(diào)度(unscheduled)的 Pod。 由于 Pod 中的容器和 Pod 本身可能有不同的要求,調(diào)度程序會過濾掉任何不滿足 Pod 特定調(diào)度需求的節(jié)點。 或者,API 允許你在創(chuàng)建 Pod 時為它指定一個節(jié)點,但這并不常見,并且僅在特殊情況下才會這樣做。
在一個集群中,滿足一個 Pod 調(diào)度請求的所有節(jié)點稱之為?可調(diào)度節(jié)點。 如果沒有任何一個節(jié)點能滿足 Pod 的資源請求, 那么這個 Pod 將一直停留在未調(diào)度狀態(tài)直到調(diào)度器能夠找到合適的 Node。
調(diào)度器先在集群中找到一個 Pod 的所有可調(diào)度節(jié)點,然后根據(jù)一系列函數(shù)對這些可調(diào)度節(jié)點打分, 選出其中得分最高的節(jié)點來運行 Pod。之后,調(diào)度器將這個調(diào)度決定通知給 kube-apiserver,這個過程叫做?綁定。
在做調(diào)度決定時需要考慮的因素包括:單獨和整體的資源請求、硬件/軟件/策略限制、 親和以及反親和要求、數(shù)據(jù)局部性、負載間的干擾等等。
kube-scheduler 中的節(jié)點選擇
kube-scheduler 給一個 Pod 做調(diào)度選擇時包含兩個步驟:
- 過濾
- 打分
過濾階段會將所有滿足 Pod 調(diào)度需求的節(jié)點選出來。 例如,PodFitsResources 過濾函數(shù)會檢查候選節(jié)點的可用資源能否滿足 Pod 的資源請求。 在過濾之后,得出一個節(jié)點列表,里面包含了所有可調(diào)度節(jié)點;通常情況下, 這個節(jié)點列表包含不止一個節(jié)點。如果這個列表是空的,代表這個 Pod 不可調(diào)度。
在打分階段,調(diào)度器會為 Pod 從所有可調(diào)度節(jié)點中選取一個最合適的節(jié)點。 根據(jù)當前啟用的打分規(guī)則,調(diào)度器會給每一個可調(diào)度節(jié)點進行打分。
最后,kube-scheduler 會將 Pod 調(diào)度到得分最高的節(jié)點上。 如果存在多個得分最高的節(jié)點,kube-scheduler 會從中隨機選取一個。
?
支持以下兩種方式配置調(diào)度器的過濾和打分行為:
- 調(diào)度策略?允許你配置過濾所用的?斷言(Predicates)?和打分所用的?優(yōu)先級(Priorities)。
- 調(diào)度配置?允許你配置實現(xiàn)不同調(diào)度階段的插件, 包括:QueueSort、Filter、Score、Bind、Reserve、Permit?等等。 你也可以配置 kube-scheduler 運行不同的配置文件。
?2、將 Pod 指派給節(jié)點
你可以約束一個?Pod?以便?限制?其只能在特定的節(jié)點上運行, 或優(yōu)先在特定的節(jié)點上運行。有幾種方法可以實現(xiàn)這點,推薦的方法都是用?標簽選擇算符來進行選擇。 通常這樣的約束不是必須的,因為調(diào)度器將自動進行合理的放置(比如,將 Pod 分散到節(jié)點上, 而不是將 Pod 放置在可用資源不足的節(jié)點上等等)。但在某些情況下,你可能需要進一步控制 Pod 被部署到哪個節(jié)點。例如,確保 Pod 最終落在連接了 SSD 的機器上, 或者將來自兩個不同的服務且有大量通信的 Pod 被放置在同一個可用區(qū)。
?你可以使用下列方法中的任何一種來選擇 Kubernetes 對特定 Pod 的調(diào)度:
- 與節(jié)點標簽匹配的?nodeSelector
- 親和性與反親和性
- nodeName?字段
- Pod 拓撲分布約束
節(jié)點標簽
與很多其他 Kubernetes 對象類似,節(jié)點也有標簽。 你可以手動地添加標簽。 Kubernetes 也會為集群中所有節(jié)點添加一些標準的標簽。 參見常用的標簽、注解和污點以了解常見的節(jié)點標簽。
說明:
這些標簽的取值是取決于云提供商的,并且是無法在可靠性上給出承諾的。 例如,kubernetes.io/hostname
?的取值在某些環(huán)境中可能與節(jié)點名稱相同, 而在其他環(huán)境中會取不同的值。
節(jié)點隔離/限制
通過為節(jié)點添加標簽,你可以準備讓 Pod 調(diào)度到特定節(jié)點或節(jié)點組上。 你可以使用這個功能來確保特定的 Pod 只能運行在具有一定隔離性、安全性或監(jiān)管屬性的節(jié)點上。
如果使用標簽來實現(xiàn)節(jié)點隔離,建議選擇節(jié)點上的?kubelet?無法修改的標簽鍵。 這可以防止受感染的節(jié)點在自身上設置這些標簽,進而影響調(diào)度器將工作負載調(diào)度到受感染的節(jié)點。
NodeRestriction?準入插件防止 kubelet 使用?node-restriction.kubernetes.io/?前綴設置或修改標簽。
要使用該標簽前綴進行節(jié)點隔離:
- ?確保你在使用節(jié)點鑒權機制并且已經(jīng)啟用了?NodeRestriction 準入插件。
- 將帶有?node-restriction.kubernetes.io/?前綴的標簽添加到 Node 對象, 然后在節(jié)點選擇算符中使用這些標簽。 例如,example.com.node-restriction.kubernetes.io/fips=true?或?example.com.node-restriction.kubernetes.io/pci-dss=true。
nodeSelector
nodeSelector?是節(jié)點選擇約束的最簡單推薦形式。你可以將?nodeSelector?字段添加到 Pod 的規(guī)約中設置你希望目標節(jié)點所具有的節(jié)點標簽。 Kubernetes 只會將 Pod 調(diào)度到擁有你所指定的每個標簽的節(jié)點上。
進一步的信息可參見將 Pod 指派給節(jié)點。
親和性與反親和性
nodeSelector
?提供了一種最簡單的方法來將 Pod 約束到具有特定標簽的節(jié)點上。 親和性和反親和性擴展了你可以定義的約束類型。使用親和性與反親和性的一些好處有:
- 親和性、反親和性語言的表達能力更強。
nodeSelector
?只能選擇擁有所有指定標簽的節(jié)點。 親和性、反親和性為你提供對選擇邏輯的更強控制能力。 - 你可以標明某規(guī)則是“軟需求”或者“偏好”,這樣調(diào)度器在無法找到匹配節(jié)點時仍然調(diào)度該 Pod。
- 你可以使用節(jié)點上(或其他拓撲域中)運行的其他 Pod 的標簽來實施調(diào)度約束, 而不是只能使用節(jié)點本身的標簽。這個能力讓你能夠定義規(guī)則允許哪些 Pod 可以被放置在一起。
親和性功能由兩種類型的親和性組成:
-
節(jié)點親和性功能類似于?
nodeSelector
?字段,但它的表達能力更強,并且允許你指定軟規(guī)則。 - Pod 間親和性/反親和性允許你根據(jù)其他 Pod 的標簽來約束 Pod。
節(jié)點親和性
節(jié)點親和性概念上類似于?nodeSelector
, 它使你可以根據(jù)節(jié)點上的標簽來約束 Pod 可以調(diào)度到哪些節(jié)點上。 節(jié)點親和性有兩種:
-
requiredDuringSchedulingIgnoredDuringExecution
: 調(diào)度器只有在規(guī)則被滿足的時候才能執(zhí)行調(diào)度。此功能類似于?nodeSelector
, 但其語法表達能力更強。 -
preferredDuringSchedulingIgnoredDuringExecution
: 調(diào)度器會嘗試尋找滿足對應規(guī)則的節(jié)點。如果找不到匹配的節(jié)點,調(diào)度器仍然會調(diào)度該 Pod。
說明:
在上述類型中,IgnoredDuringExecution
?意味著如果節(jié)點標簽在 Kubernetes 調(diào)度 Pod 后發(fā)生了變更,Pod 仍將繼續(xù)運行。
你可以使用 Pod 規(guī)約中的?.spec.affinity.nodeAffinity
?字段來設置節(jié)點親和性。 例如,考慮下面的 Pod 規(guī)約:
pods/pod-with-pod-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1
- antarctica-west1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: registry.k8s.io/pause:2.0
在這一示例中,所應用的規(guī)則如下:
- 節(jié)點必須包含一個鍵名為?
topology.kubernetes.io/zone
?的標簽, 并且該標簽的取值必須為?antarctica-east1
?或?antarctica-west1
。 - 節(jié)點最好具有一個鍵名為?
another-node-label-key
?且取值為?another-node-label-value
?的標簽。
你可以使用?operator
?字段來為 Kubernetes 設置在解釋規(guī)則時要使用的邏輯操作符。 你可以使用?In
、NotIn
、Exists
、DoesNotExist
、Gt
?和?Lt
?之一作為操作符。
NotIn 和 DoesNotExist 可用來實現(xiàn)節(jié)點反親和性行為。 你也可以使用節(jié)點污點 將 Pod 從特定節(jié)點上驅(qū)逐。
說明:
如果你同時指定了?nodeSelector
?和?nodeAffinity
,兩者?必須都要滿足, 才能將 Pod 調(diào)度到候選節(jié)點上。
如果你在與 nodeAffinity 類型關聯(lián)的 nodeSelectorTerms 中指定多個條件, 只要其中一個?nodeSelectorTerms
?滿足(各個條件按邏輯或操作組合)的話,Pod 就可以被調(diào)度到節(jié)點上。
如果你在與?nodeSelectorTerms
?中的條件相關聯(lián)的單個?matchExpressions
?字段中指定多個表達式, 則只有當所有表達式都滿足(各表達式按邏輯與操作組合)時,Pod 才能被調(diào)度到節(jié)點上。
?
節(jié)點親和性權重
你可以為?preferredDuringSchedulingIgnoredDuringExecution
?親和性類型的每個實例設置?weight
?字段,其取值范圍是 1 到 100。 當調(diào)度器找到能夠滿足 Pod 的其他調(diào)度請求的節(jié)點時,調(diào)度器會遍歷節(jié)點滿足的所有的偏好性規(guī)則, 并將對應表達式的?weight
?值加和。
最終的加和值會添加到該節(jié)點的其他優(yōu)先級函數(shù)的評分之上。 在調(diào)度器為 Pod 作出調(diào)度決定時,總分最高的節(jié)點的優(yōu)先級也最高。
例如,考慮下面的 Pod 規(guī)約:
pods/pod-with-affinity-anti-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: with-affinity-anti-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: label-1
operator: In
values:
- key-1
- weight: 50
preference:
matchExpressions:
- key: label-2
operator: In
values:
- key-2
containers:
- name: with-node-affinity
image: registry.k8s.io/pause:2.0
如果存在兩個候選節(jié)點,都滿足?preferredDuringSchedulingIgnoredDuringExecution
?規(guī)則, 其中一個節(jié)點具有標簽?label-1:key-1
,另一個節(jié)點具有標簽?label-2:key-2
, 調(diào)度器會考察各個節(jié)點的?weight
?取值,并將該權重值添加到節(jié)點的其他得分值之上,
說明:
如果你希望 Kubernetes 能夠成功地調(diào)度此例中的 Pod,你必須擁有打了?kubernetes.io/os=linux
?標簽的節(jié)點。
逐個調(diào)度方案中設置節(jié)點親和性
特性狀態(tài):?Kubernetes v1.20 [beta]
在配置多個調(diào)度方案時, 你可以將某個方案與節(jié)點親和性關聯(lián)起來,如果某個調(diào)度方案僅適用于某組特殊的節(jié)點時, 這樣做是很有用的。 要實現(xiàn)這點,可以在調(diào)度器配置中為?NodeAffinity?插件的?args?字段添加?addedAffinity。例如:
?
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
- schedulerName: foo-scheduler
pluginConfig:
- name: NodeAffinity
args:
addedAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: scheduler-profile
operator: In
values:
- foo
這里的?addedAffinity
?除遵從 Pod 規(guī)約中設置的節(jié)點親和性之外, 還適用于將?.spec.schedulerName
?設置為?foo-scheduler
。 換言之,為了匹配 Pod,節(jié)點需要滿足?addedAffinity
?和 Pod 的?.spec.NodeAffinity
。
由于?addedAffinity
?對最終用戶不可見,其行為可能對用戶而言是出乎意料的。 應該使用與調(diào)度方案名稱有明確關聯(lián)的節(jié)點標簽。
說明:
DaemonSet 控制器為 DaemonSet 創(chuàng)建 Pod, 但該控制器不理會調(diào)度方案。 DaemonSet 控制器創(chuàng)建 Pod 時,默認的 Kubernetes 調(diào)度器負責放置 Pod, 并遵從 DaemonSet 控制器中設置的?nodeAffinity?規(guī)則。
?
Pod 間親和性與反親和性
Pod 間親和性與反親和性使你可以基于已經(jīng)在節(jié)點上運行的?Pod?的標簽來約束 Pod 可以調(diào)度到的節(jié)點,而不是基于節(jié)點上的標簽。
Pod 間親和性與反親和性的規(guī)則格式為“如果 X 上已經(jīng)運行了一個或多個滿足規(guī)則 Y 的 Pod, 則這個 Pod 應該(或者在反親和性的情況下不應該)運行在 X 上”。 這里的 X 可以是節(jié)點、機架、云提供商可用區(qū)或地理區(qū)域或類似的拓撲域, Y 則是 Kubernetes 嘗試滿足的規(guī)則。
你通過標簽選擇算符?的形式來表達規(guī)則(Y),并可根據(jù)需要指定選關聯(lián)的名字空間列表。 Pod 在 Kubernetes 中是名字空間作用域的對象,因此 Pod 的標簽也隱式地具有名字空間屬性。 針對 Pod 標簽的所有標簽選擇算符都要指定名字空間,Kubernetes 會在指定的名字空間內(nèi)尋找標簽。
你會通過?topologyKey?來表達拓撲域(X)的概念,其取值是系統(tǒng)用來標示域的節(jié)點標簽鍵。 相關示例可參見常用標簽、注解和污點。
說明:
Pod 間親和性和反親和性都需要相當?shù)挠嬎懔?,因此會在大?guī)模集群中顯著降低調(diào)度速度。 我們不建議在包含數(shù)百個節(jié)點的集群中使用這類設置。
說明:
Pod 反親和性需要節(jié)點上存在一致性的標簽。換言之, 集群中每個節(jié)點都必須擁有與?topologyKey
?匹配的標簽。 如果某些或者所有節(jié)點上不存在所指定的?topologyKey
?標簽,調(diào)度行為可能與預期的不同。
Pod 間親和性與反親和性的類型
與節(jié)點親和性類似,Pod 的親和性與反親和性也有兩種類型:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
例如,你可以使用?requiredDuringSchedulingIgnoredDuringExecution
?親和性來告訴調(diào)度器, 將兩個服務的 Pod 放到同一個云提供商可用區(qū)內(nèi),因為它們彼此之間通信非常頻繁。 類似地,你可以使用?preferredDuringSchedulingIgnoredDuringExecution
?反親和性來將同一服務的多個 Pod 分布到多個云提供商可用區(qū)中。
要使用 Pod 間親和性,可以使用 Pod 規(guī)約中的?.affinity.podAffinity
?字段。 對于 Pod 間反親和性,可以使用 Pod 規(guī)約中的?.affinity.podAntiAffinity
?字段。
Pod 親和性示例
考慮下面的 Pod 規(guī)約:
?pods/pod-with-pod-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: registry.k8s.io/pause:2.0
本示例定義了一條 Pod 親和性規(guī)則和一條 Pod 反親和性規(guī)則。Pod 親和性規(guī)則配置為?requiredDuringSchedulingIgnoredDuringExecution
,而 Pod 反親和性配置為?preferredDuringSchedulingIgnoredDuringExecution
。
親和性規(guī)則表示,僅當節(jié)點和至少一個已運行且有?security=S1
?的標簽的 Pod 處于同一區(qū)域時,才可以將該 Pod 調(diào)度到節(jié)點上。 更確切的說,調(diào)度器必須將 Pod 調(diào)度到具有?topology.kubernetes.io/zone=V
?標簽的節(jié)點上,并且集群中至少有一個位于該可用區(qū)的節(jié)點上運行著帶有?security=S1
?標簽的 Pod。
反親和性規(guī)則表示,如果節(jié)點處于 Pod 所在的同一可用區(qū)且至少一個 Pod 具有?security=S2
?標簽,則該 Pod 不應被調(diào)度到該節(jié)點上。 更確切地說, 如果同一可用區(qū)中存在其他運行著帶有?security=S2
?標簽的 Pod 節(jié)點, 并且節(jié)點具有標簽?topology.kubernetes.io/zone=R
,Pod 不能被調(diào)度到該節(jié)點上。
查閱設計文檔?以進一步熟悉 Pod 親和性與反親和性的示例。
你可以針對 Pod 間親和性與反親和性為其?operator?字段使用?In、NotIn、Exists、?DoesNotExist?等值。
閱讀操作符了解有關這些操作的更多信息。
原則上,topologyKey
?可以是任何合法的標簽鍵。出于性能和安全原因,topologyKey
?有一些限制:
- 對于 Pod 親和性而言,在?
requiredDuringSchedulingIgnoredDuringExecution
?和?preferredDuringSchedulingIgnoredDuringExecution
?中,topologyKey
?不允許為空。 - 對于?
requiredDuringSchedulingIgnoredDuringExecution
?要求的 Pod 反親和性, 準入控制器?LimitPodHardAntiAffinityTopology
?要求?topologyKey
?只能是?kubernetes.io/hostname
。如果你希望使用其他定制拓撲邏輯, 你可以更改準入控制器或者禁用之。
除了?labelSelector
?和?topologyKey
,你也可以指定?labelSelector
?要匹配的名字空間列表,方法是在?labelSelector
?和?topologyKey
?所在層同一層次上設置?namespaces
。 如果?namespaces
?被忽略或者為空,則默認為 Pod 親和性/反親和性的定義所在的名字空間。
名字空間選擇算符
特性狀態(tài):?Kubernetes v1.24 [stable]
用戶也可以使用?namespaceSelector
?選擇匹配的名字空間,namespaceSelector
?是對名字空間集合進行標簽查詢的機制。 親和性條件會應用到?namespaceSelector
?所選擇的名字空間和?namespaces
?字段中所列舉的名字空間之上。 注意,空的?namespaceSelector
({}
)會匹配所有名字空間,而 null 或者空的?namespaces
?列表以及 null 值?namespaceSelector
?意味著“當前 Pod 的名字空間”。
更實際的用例
Pod 間親和性與反親和性在與更高級別的集合(例如 ReplicaSet、StatefulSet、 Deployment 等)一起使用時,它們可能更加有用。 這些規(guī)則使得你可以配置一組工作負載,使其位于所定義的同一拓撲中; 例如優(yōu)先將兩個相關的 Pod 置于相同的節(jié)點上。
以一個三節(jié)點的集群為例。你使用該集群運行一個帶有內(nèi)存緩存(例如 Redis)的 Web 應用程序。 在此例中,還假設 Web 應用程序和內(nèi)存緩存之間的延遲應盡可能低。 你可以使用 Pod 間的親和性和反親和性來盡可能地將該 Web 服務器與緩存并置。
在下面的 Redis 緩存 Deployment 示例中,副本上設置了標簽?app=store
。?podAntiAffinity
?規(guī)則告訴調(diào)度器避免將多個帶有?app=store
?標簽的副本部署到同一節(jié)點上。 因此,每個獨立節(jié)點上會創(chuàng)建一個緩存實例。
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
下例的 Deployment 為 Web 服務器創(chuàng)建帶有標簽?app=web-store
?的副本。 Pod 親和性規(guī)則告訴調(diào)度器將每個副本放到存在標簽為?app=store
?的 Pod 的節(jié)點上。 Pod 反親和性規(guī)則告訴調(diào)度器決不要在單個節(jié)點上放置多個?app=web-store
?服務器。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
selector:
matchLabels:
app: web-store
replicas: 3
template:
metadata:
labels:
app: web-store
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.16-alpine
創(chuàng)建前面兩個 Deployment 會產(chǎn)生如下的集群布局,每個 Web 服務器與一個緩存實例并置, 并分別運行在三個獨立的節(jié)點上。
node-1 | node-2 | node-3 |
---|---|---|
webserver-1 | webserver-2 | webserver-3 |
cache-1 | cache-2 | cache-3 |
總體效果是每個緩存實例都非??赡鼙辉谕粋€節(jié)點上運行的某個客戶端訪問。 這種方法旨在最大限度地減少偏差(負載不平衡)和延遲。
你可能還有使用 Pod 反親和性的一些其他原因。 參閱?ZooKeeper 教程?了解一個 StatefulSet 的示例,該 StatefulSet 配置了反親和性以實現(xiàn)高可用, 所使用的是與此例相同的技術。
nodeName
nodeName
?是比親和性或者?nodeSelector
?更為直接的形式。nodeName
?是 Pod 規(guī)約中的一個字段。如果?nodeName
?字段不為空,調(diào)度器會忽略該 Pod, 而指定節(jié)點上的 kubelet 會嘗試將 Pod 放到該節(jié)點上。 使用?nodeName
?規(guī)則的優(yōu)先級會高于使用?nodeSelector
?或親和性與非親和性的規(guī)則。
使用?nodeName
?來選擇節(jié)點的方式有一些局限性:
- 如果所指代的節(jié)點不存在,則 Pod 無法運行,而且在某些情況下可能會被自動刪除。
- 如果所指代的節(jié)點無法提供用來運行 Pod 所需的資源,Pod 會失敗, 而其失敗原因中會給出是否因為內(nèi)存或 CPU 不足而造成無法運行。
- 在云環(huán)境中的節(jié)點名稱并不總是可預測的,也不總是穩(wěn)定的。
說明:
nodeName 旨在供自定義調(diào)度程序或需要繞過任何已配置調(diào)度程序的高級場景使用。 如果已分配的 Node 負載過重,繞過調(diào)度程序可能會導致 Pod 失敗。 你可以使用節(jié)點親和性或 nodeselector 字段將 Pod 分配給特定 Node,而無需繞過調(diào)度程序。
下面是一個使用?nodeName
?字段的 Pod 規(guī)約示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: kube-01
上面的 Pod 只能運行在節(jié)點?kube-01
?之上。
Pod 拓撲分布約束
你可以使用?拓撲分布約束(Topology Spread Constraints)?來控制Pod在集群內(nèi)故障域之間的分布, 故障域的示例有區(qū)域(Region)、可用區(qū)(Zone)、節(jié)點和其他用戶自定義的拓撲域。 這樣做有助于提升性能、實現(xiàn)高可用或提升資源利用率。
操作符
下面是你可以在上述?nodeAffinity
?和?podAffinity
?的?operator
?字段中可以使用的所有邏輯運算符。
操作符 | 行為 |
---|---|
In |
標簽值存在于提供的字符串集中 |
NotIn |
標簽值不包含在提供的字符串集中 |
Exists |
對象上存在具有此鍵的標簽 |
DoesNotExist |
對象上不存在具有此鍵的標簽 |
以下操作符只能與?nodeAffinity
?一起使用。
操作符 | 行為 |
---|---|
Gt |
提供的值將被解析為整數(shù),并且該整數(shù)小于等于通過解析此選擇算符命名的標簽的值所得到的整數(shù) |
Lt |
提供的值將被解析為整數(shù),并且該整數(shù)大于等于通過解析此選擇算符命名的標簽的值所得到的整數(shù) |
說明:
Gt
?和?Lt
?操作符不能與非整數(shù)值一起使用。 如果給定的值未解析為整數(shù),則該 Pod 將無法被調(diào)度。 另外,Gt
?和?Lt
?不適用于?podAffinity
。文章來源:http://www.zghlxwxcb.cn/news/detail-519229.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-519229.html
到了這里,關于Kubernetes核心概念匯總—調(diào)度、搶占和驅(qū)逐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!