摘要:的調度機制組件調度器會將調度到資源滿足要求并且評分最高的上。這個特性的設計初衷是為了替代,并擴展更強大的調度策略。和完全相同,以進行強制的約束。軟規則除了,,還有一條軟規則配置后,沒有相關污點策略的會盡量避免調度到該上。
k8s的調度機制 scheduler組件
k8s調度器會將pod調度到資源滿足要求并且評分最高的node上。我們可以使用多種規則比如:1.設置cpu、內存的使用要求;2.增加node的label,并通過pod.Spec.NodeSelector進行強匹配;3.直接設置pod的nodeName,跳過調度直接下發。
k8s 1.2加入了一個實驗性的功能:affinity。意為親和性。這個特性的設計初衷是為了替代nodeSelector,并擴展更強大的調度策略。
調度器的工作機制是這樣的:
一、預備工作
1、緩存所有的node節點,記錄他們的規格:cpu、內存、磁盤空間、gpu顯卡數等;
2、緩存所有運行中的pod,按照pod所在的node進行區分,統計每個node上的pod request了多少資源。request是pod的QoS配置,可以參考之前的文章。
3、list & watch pod資源,當檢查到有新的Pending狀態的pod出現,就將它加入到調度隊列中。
4、調度器的worker組件從隊列中取出pod進行調度。
二、調度過程
1、先將當前所有的node放入隊列;
2、執行predicates算法,對隊列中的node進行篩選。這里算法檢查了一些pod運行的必要條件,包括port不沖突、cpu和內存資源QoS(如果有的話)必須滿足、掛載volume(如果有的話)類型必須匹配、nodeSelector規則必須匹配、硬性的affinity規則(下文會提到)必須匹配、node的狀態(condition)必須正常,taint_toleration硬規則(下文會提到)等等。
2、執行priorities算法,對隊列中剩余的node進行評分,這里有許多評分項,各個項目有各自的權重:整體cpu,內存資源的平衡性、node上是否有存在要求的鏡像、同rs的pod是否有調度、node affinity的軟規則、taint_toleration軟規則(下文會提到)等等。
3、最終評分最高的node會被選出。即代碼中suggestedHost, err := sched.schedule(pod)一句(plugin/pkg/scheduler/scheduler.go)的返回值。
4、調度器執行assume方法,該方法在pod調度到node之前,就以“該pod運行在目標node上” 為場景更新調度器緩存中的node 信息,也即預備工作中的1、2兩點。這么做是為了讓pod在真正調度到node上時,調度器也可以同時做后續其他pod的調度工作。
5、調度器執行bind方法,該方法創建一個Binding資源,apiserver檢查到創建該資源時,會主動更新pod的nodeName字段。完成調度。
舉例:
apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: disktype: ssd
上面這個pod會且僅會被調度到帶有disktype: ssd這個label的node上。這是一種強規則,沒有妥協,必須遵守。
affinity 和 anti-affinity有親和性規則,那么反親和性規則肯定也要有。
親和性規則實現了更豐富的規則表達方式。并且包含了nodeSelector的硬規則和另一種軟規則。
軟規則是一種優先規則,如果沒有符合這個優先規則的節點,它仍然會被進行調度。
node親和性node親和性和nodeSelector類似,通過label進行可調度node的過濾,現在有兩種node親和性:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution:
requiredDuringSchedulingIgnoredDuringExecution強規則。和nodeSelector完全相同,以label進行強制的約束。需要指出的是:目前,如果一個node在運行時label發生了變化,變化后和其上運行的pod的requiredDuringSchedulingIgnoredDuringExecution 不再匹配,這個node上的pod也不會被驅逐,這個功能會在以后被改進,屆時會增加一種類型RequiredDuringSchedulingRequiredDuringExecution 。
preferredDuringSchedulingIgnoredDuringExecution軟規則。舉例來說:我們要將某個容器盡可能地調度到可用域X中,但如果不存在這個可用域或者可用域無法再運行pod,調度器也允許這個pod被調度到其他可用域。
以下是一個包含了強規則和軟規則的案例:
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/e2e-az-name operator: In values: - e2e-az1 - e2e-az2 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: another-node-label-key operator: In values: - another-node-label-value containers: - name: with-node-affinity image: gcr.io/google_containers/pause:2.0
該案例表明,這個pod只允許被調度到帶有kubernetes.io/e2e-az-name=e2e-az1或e2e-az2的label的node上,也即只允許被調度到e2e-az1或者e2e-az2兩個可用域中;另外,pod要盡量調度到包含another-node-label-key的值為another-node-label-value的node上。
matchExpressions結構記錄各種表達式,一個表達式包含key,operator,values,分別表示關鍵字、關鍵字匹配關系、關鍵字匹配值。匹配關系包括:In,NotIn,Exists,DoesNotExist,Gt,Lt。NotIn和DoesNotExist是node anti-affinity的一種表現。
如果一個pod的描述信息中同時包含了nodeSelector和nodeAffinity,那么調度時兩個規則都要滿足。
如果一個nodeAffinity中包含了多條nodeSelectorTerms, 調度器只需要滿足其中一條; 如果一個 nodeSelectorTerms中記錄了多條matchExpressions,那么調度器要滿足所有的matchExpressions
inter-pod affinity 和 anti-affinity這兩個特性都包含在1.4版本中,上面的親和性是node親和性,這個就是pod親和性,簡而言之,要把pod調度到某個node上,這個node上已有的pod能滿足、或盡量滿足某些條件。這個特性用pod.spec.affinity.podAffinity和pod.spec.affinity.podAntiAffinity來表示。
pod親和性的規則可以這么表示:
這個pod應該(或者不應該)運行在節點X上,X上必須已經運行了一個或多個滿足規則Y的pod。規則Y的表達方式類似于一個labelSelector并關聯了一個namespace列表:namespaces(若沒有則表示“allnamespaces”),X可能是node或一個az,我們通過字段topologyKey來規劃X,即所有的X都要滿足topologyKey相同,一般topologyKey是一個label的key。
為什么要有namespace列表?因為和node不同,pod是有分namespace的,因此pod的label也是有分namespace的。在這種情況下,規則Y必須要指明自己這個規則要適用于哪些namespace。比如node上運行的是hy這個namespace下的pod,即便pod的label和規則Y的nodeSelector都相同,我們也視為不符合規則。
和node親和性一樣,pod親和性也包含兩個(硬規則和軟規則):
requiredDuringSchedulingIgnoredDuringExecution: 硬規則。
preferredDuringSchedulingIgnoredDuringExecution:
舉個例子:
apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: failure-domain.beta.kubernetes.io/zone podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: kubernetes.io/hostname containers: - name: with-pod-affinity image: gcr.io/google_containers/pause:2.0
上面的pod模板使用了podAffinity的硬規則和podAntiAffinity的軟規則。
podAffinity規則中topologyKey是zone,也就是可用域,說明這條規則可以規劃處調度到的域,首先,node上必須至少有一個running狀態的pod包含key為security,value為S1的label。只要滿足這個條件,那么這個node和其同一個域(擁有相同的failure-domain.beta.kubernetes.io/zone 為key,且值相同的label)的node均會被調度。
podAntiAffinity規則中topologyKey是hostname,表明該規則約定了某種node盡量不會被調度到,這種node上已經運行了包含key為security,value為S2的label的pod。
假如現在有node a,b,c,其中a和b擁有相同的zone,且b上運行了一個pod,這個pod有一個label,key為security,value為S1。那么我們創建如上的一個親和性規則的3副本時,三個副本都會被調度到a或者b上。假如b上同時運行了一個pod,這個pod有一個label,key為security,value為S2,那么所有的副本都會調度到node a上。
taint tolerationnode 可以被打上污點標記,并配置污點容忍策略。而pod的描述信息中如果包含了相同的污點容忍策略,就可以被調度到這個node上,反之則不可、或盡量不允許。
硬性規則給node a 打上污點 name=huang, 策略為不可調度:
kubectl taint nodes a name=huang:NoSchedule
若我創建的pod中包含如下描述:
tolerations: - key: "name" operator: "Equal" value: "huang" effect: "NoSchedule"
則這個pod可以容忍有這類污點的node,即可以調度到node a,當然,也可以用如下的描述:
tolerations: - key: "name" operator: "Exist" effect: "NoSchedule"
類似的硬性規則體現在effect字段中,還有NoExecute,它比NoSchedule更嚴格,不止pod不能調度上去,node上原有的pod如果不能容忍污點,就會被驅逐(eviction),配合字段tolerationSeconds可以規定這些會被驅逐的pod能在node上呆多久。
軟規則除了NoExecute,NoSchedule,還有一條軟規則:PreferNoSchedule.配置effect=PreferNoSchedule后,沒有相關污點策略的pod會盡量避免調度到該node上。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32617.html
摘要:其次,青云的負載均衡器能感知到容器網絡,而傳統的方案在內部還需要再做一層虛擬網絡,層的負載均衡器無法感知容器網絡。 前言 容器技術目前的市場現狀是一家獨大、百花齊放。 關于容器技術,看看青云QingCloud 王淵命(老王)是如何看待它的,本文來自他在青云QingCloud 深圳站實踐課堂的演講。全文 2780字,閱讀時長約為 11 分鐘。 容器是什么 容器的概念外延比較廣,討論的時候...
摘要:本文中,我們將描述系統的架構開發演進過程,以及背后的驅動原因。應用管理層提供基本的部署和路由,包括自愈能力彈性擴容服務發現負載均衡和流量路由。 帶你了解Kubernetes架構的設計意圖、Kubernetes系統的架構開發演進過程,以及背后的驅動原因。 showImg(https://segmentfault.com/img/remote/1460000016446636?w=1280...
摘要:下面通過該文章來簡述的基礎信息并詳述的生命周期。聲明周期鉤子函數為容器提供了兩種生命周期鉤子于容器創建完成之后立即運行的鉤子程序。向容器指定發起請求,響應碼為或者是為成功,否則失敗。 簡述 Kubernetes 是一種用于在一組主機上運行和協同容器化應用程序的系統,提供應用部署、規劃、更新維護的機制。應用運行在 kubernetes 集群之上,實現服務的擴容、縮容,執行滾動更新以及在不...
摘要:作為一個開源的分布式數據庫產品,具有多副本強一致性的同時能夠根據業務需求非常方便的進行彈性伸縮,并且擴縮容期間對上層業務無感知。另外本身維護了數據多副本,這點和分布式文件系統的多副本是有重復的。 作者:鄧栓來源:細說云計算 作為一款定位在 Cloud-native 的數據庫,現如今 TiDB 在云整合上已取得了階段性的進展。日前 Cloud TiDB 產品在 UCloud 平臺正式開啟...
摘要:摘要的生態地位已經確立,可擴展性將是其發力的主戰場。該功能由于只是替代了做了些更名的工作,所以在已經是穩定的狀態了。異構計算作為非常重要的新戰場,非常重視。而異構計算需要強大的計算力和高性能網絡,需要提供一種統一的方式與等高性能硬件集成。 摘要: Kubernetes的生態地位已經確立,可擴展性將是其發力的主戰場。異構計算作為非常重要的新戰場,Kubernetes非常重視。而異構計算需...
閱讀 2751·2021-11-22 13:54
閱讀 2688·2021-10-14 09:42
閱讀 3987·2021-09-28 09:47
閱讀 2162·2021-09-03 10:28
閱讀 1203·2021-07-26 23:38
閱讀 2557·2019-08-30 15:54
閱讀 2639·2019-08-29 16:35
閱讀 1426·2019-08-29 15:42