Kubernetes調(diào)度管理優(yōu)先級和搶占機(jī)制詳解
基本介紹
在日常工作中,每個(gè)機(jī)場都有調(diào)度室,用來管理飛機(jī)應(yīng)該從哪里降落,停在什么地方。在Kubernetes也有這樣的調(diào)度器,主要作用就是將Pod安排到合適的節(jié)點(diǎn)上。
Kubernetes中的調(diào)度器是kube-scheduler,工作流程如下:
- 在集群中所有Node中,根據(jù)調(diào)度算法挑選出可以運(yùn)行該P(yáng)od的所有Node;
- 在上一步的基礎(chǔ)上,再根據(jù)調(diào)度算法給篩選出的Node進(jìn)行打分,篩選出分?jǐn)?shù)最高的Node進(jìn)行調(diào)度;
- 將Pod的spec.nodeName填上調(diào)度結(jié)果的Node名字;
其原理圖如下:
由上圖可知,Kubernetes的調(diào)度器核心是兩個(gè)相互獨(dú)立的控制循環(huán)。
1、Informer Path其主要作用是啟動(dòng)一個(gè)Informer來監(jiān)聽Etcd中Pod,Node,Service等與調(diào)度器相關(guān)的API對象的變化。當(dāng)一個(gè)Pod被創(chuàng)建出來后,就被通過Informer Handler將待調(diào)度的Pod放入調(diào)度隊(duì)列中,默認(rèn)情況下,Kubernetes的調(diào)度策略是一個(gè)優(yōu)先級隊(duì)列,并且當(dāng)集群信息發(fā)生變化的時(shí)候,調(diào)度器還會對調(diào)度隊(duì)列里的內(nèi)容進(jìn)行一些特殊操作。而且Kubernetes的默認(rèn)調(diào)度器還負(fù)責(zé)對調(diào)度器緩存(scheduler cache)進(jìn)行更新,以執(zhí)行調(diào)度算法的執(zhí)行效率。
2、Scheduler Path其主要邏輯是不斷從隊(duì)列中出一個(gè)Pod,然后調(diào)用Predicates進(jìn)行過濾,然后得到一組Node(也就是可運(yùn)行Pod的所有Node信息,這些信息都是來自scheduler cache),接下來調(diào)用Priorities對篩選出的Node進(jìn)行打分,然后分?jǐn)?shù)最高的Node會作為本次調(diào)度選擇的對象。調(diào)度完成后,調(diào)度器需要將Pod的spec.nodeName的值修改為調(diào)度的Node名字,這個(gè)步驟稱為Bind。
但是在Bind階段,Kubernetes默認(rèn)調(diào)度器只會更新scheduler cache中的信息,這種基于樂觀假設(shè)的API對象更新方式被稱為Assume。在Assume之后,調(diào)度器才會向API Server發(fā)起更新Pod的請求,來真正完成Bind操作。如果本次Bind失敗,等到scheduler cache更新之后又會恢復(fù)正常。
正是由于有Assume的原因,當(dāng)一個(gè)Pod完成調(diào)度需要在某個(gè)Node節(jié)點(diǎn)運(yùn)行之前,kubelet還會進(jìn)行一步Admit操作來驗(yàn)證該P(yáng)od是否能夠運(yùn)行在該Node上,作為kubelet的二次驗(yàn)證。
常用的預(yù)算策略有:
- CheckNodeCondition
- GeneralPredication:
HostName, PodFitsHostPort, MatchNodeSelector, PodFitsResources
- NoDiskConflict
優(yōu)先級和搶占機(jī)制
正常情況下,當(dāng)一個(gè)Pod調(diào)度失敗后,它會被擱置起來,直到Pod被更新,或者集群狀態(tài)發(fā)生變化,調(diào)度器才會對這個(gè)Pod進(jìn)行重新調(diào)度。但是有的時(shí)候我們不希望一個(gè)高優(yōu)先級的Pod在調(diào)度失敗就被擱置,而是會把某個(gè)Node上的一些低優(yōu)先級的Pod刪除,來保證高優(yōu)先級的Pod可以調(diào)度成功。
Kubernetes中優(yōu)先級是通過ProrityClass來定義,如下:
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: high-priority value: 1000000 globalDefault: false description: "This priority class should be used for high priority service pods only."
其中的value就是優(yōu)先級數(shù)值,數(shù)值越大,優(yōu)先級越高。優(yōu)先級是一個(gè)32bit的整數(shù),最大值不超過10億,超過10億的值是被Kubernetes保留下來作為系統(tǒng)Pod使用的,就是為了保證系統(tǒng)Pod不會被搶占。另外如果globalDefault的值設(shè)置為 true的話表明這個(gè)PriorityClass的值會成為系統(tǒng)默認(rèn)值,如果是false就表示只有在申明這個(gè)PriorityClass的Pod才會擁有這個(gè)優(yōu)先級,而對于其他沒有申明的,其優(yōu)先級為0。
如下定義Pod并定義優(yōu)先級:
apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent priorityClassName: high-priority
上面的PriotiryClassName就是定義我們的PriorityClass,當(dāng)這個(gè)Pod提交給Kubernetes之后,Kubernetes的PriorityAdmissionController會自動(dòng)將這個(gè)Pod的spec.priority字段設(shè)置為我們定義的值。而當(dāng)這個(gè)Pod擁有這個(gè)優(yōu)先級之后,高優(yōu)先級的Pod就可能比低優(yōu)先級的Pod先出隊(duì),從而盡早完成調(diào)度。
而當(dāng)一個(gè)高優(yōu)先級的Pod調(diào)度失敗后,其搶占機(jī)制就會被觸發(fā),這時(shí)候調(diào)度器就會試圖從當(dāng)前的集群中尋找一個(gè)節(jié)點(diǎn),使得這個(gè)節(jié)點(diǎn)上的一個(gè)或多個(gè)低優(yōu)先級的Pod被刪除,然后這個(gè)高優(yōu)先級的Pod就可以被調(diào)度到這個(gè)節(jié)點(diǎn)上。當(dāng)搶占發(fā)生時(shí),這個(gè)高優(yōu)先級Pod并不會立即調(diào)度到即將搶占的節(jié)點(diǎn)上,調(diào)度器只會將這個(gè)Pod的spec.nominatedNodeName的值設(shè)置為被搶占節(jié)點(diǎn)的Node名字,然后這個(gè)Pod會重新進(jìn)入下一個(gè)調(diào)度周期,然后會在這個(gè)周期內(nèi)決定這個(gè)Pod被調(diào)度到哪個(gè)節(jié)點(diǎn)上。在這個(gè)重新調(diào)度期間,如果有一個(gè)更高的優(yōu)先級Pod也要搶占這個(gè)節(jié)點(diǎn),那么調(diào)度器就會清空原Pod的nominatedNodeName的值,而更高優(yōu)先級的Pod將會搶占這個(gè)值。
**實(shí)現(xiàn)原理:**Kubernetes用兩個(gè)隊(duì)列來實(shí)現(xiàn)搶占算法:ActiveQ和unschedulableQ。
- ActiveQ:凡是在ActiveQ里的Pod,都是下一個(gè)周期需要調(diào)度的對象,所以當(dāng)Kubernetes創(chuàng)建一個(gè)新的Pod,這個(gè)Pod就會被放入ActiveQ里;
- unschedulableQ:專門用來存放調(diào)度失敗的Pod;
那么如果一個(gè)Pod調(diào)度失敗,調(diào)度器就會將其放入unschedulableQ里,然后調(diào)度器會檢查這個(gè)調(diào)度失敗的原因,分析并確認(rèn)是否可以通過搶占來解決此次調(diào)度問題,如果確定搶占可以發(fā)生,那么調(diào)度器就會把自己緩存的所有信息都重新復(fù)制一份,然后使用這個(gè)副本來模擬搶占過程。如果模擬通過,調(diào)度器就會真正開始搶占操作了:
- 調(diào)度器會檢查犧牲者列表,清空這些Pod所攜帶的nominatedNodeName字段;
- 調(diào)度器會把搶占者的nominatedNodeName的字段設(shè)置為被搶占的Node名字;
- 調(diào)度器會開啟Goroutine,同步的刪除犧牲者;
接下來調(diào)度器就會通過正常的調(diào)度流程,把搶占者調(diào)度成功。在這個(gè)過程中,調(diào)度器會對這個(gè)Node,進(jìn)行兩次Predicates算法:
- 假設(shè)上述搶占者已經(jīng)運(yùn)行在這個(gè)節(jié)點(diǎn)上,然后運(yùn)行Predicates算法;
- 調(diào)度器正常執(zhí)行Predicates算法;
只有上述者兩個(gè)都通過的情況下,這個(gè)Node和Pod才會被 綁定。
高級調(diào)度
上面介紹的是Kubernetres默認(rèn)的調(diào)度策略,有時(shí)候默認(rèn)的調(diào)度策略不能滿足我們的需求,比如想把Pod調(diào)度到指定的節(jié)點(diǎn),或者不讓某些節(jié)點(diǎn)調(diào)度Pod。這時(shí)候就要用到更高級的調(diào)度策略,主要有如下幾種:
- nodeSelector
- nodeName
- nodeAffinity
- podAffinity
- podAntiAffinity
- 污點(diǎn)調(diào)度
nodeSelector
nodeSelector也可以叫做節(jié)點(diǎn)選擇器,其原理是通過在節(jié)點(diǎn)上定義label標(biāo)簽,然后Pod中指定選擇這些標(biāo)簽,讓Pod能夠調(diào)度到指定的節(jié)點(diǎn)上。
比如給kk-node01指定env=uat標(biāo)簽,命令如下:
$ kubectl label nodes kk-node01 env=uat
現(xiàn)在在Pod的YAML清單中配置nodeSelector,如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodeselector spec: containers: - name: myapp image: ikubernetes/myapp:v1 nodeSelector: env: uat
這樣,該P(yáng)od就會調(diào)度到kk-node01節(jié)點(diǎn)上,如果該P(yáng)od指定為env=prod,則調(diào)度不到kk-node01節(jié)點(diǎn)。
nodeName
nodeName也是節(jié)點(diǎn)選擇器,和nodeSelector不同之處在于nodeName是直接指定節(jié)點(diǎn)名,這屬于強(qiáng)調(diào)度,定義方式如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodename spec: containers: - name: myapp image: ikubernetes/myapp:v1 nodeName: kk-node01 # 節(jié)點(diǎn)名字
nodeAffinity
nodeAffinity叫做節(jié)點(diǎn)親和性調(diào)度,其調(diào)度方式比nodeSelector和nodeName更強(qiáng)大。
目前,nodeAffinity支持兩種調(diào)度策略:
- preferredDuringSchedulingIgnoredDuringExecution
- requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution表示如果有Node匹配,則優(yōu)先調(diào)度到該Node,如果沒有,可以根據(jù)配置調(diào)度到其他節(jié)點(diǎn)。requiredDuringSchedulingIgnoredDuringExecution則表示必須滿足條件的節(jié)點(diǎn)才允許調(diào)度。
定義preferredDuringSchedulingIgnoredDuringExecution的例子如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-preferred spec: containers: - name: myapp image: ikubernetes/myapp:v1 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: disktype operator: In values: ["ssd", "harddisk"] weight: 60
requiredDuringSchedulingIgnoredDuringExecution的例子如下:
apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-required spec: containers: - name: myapp image: ikubernetes/myapp:v1 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: ["ssd", "harddisk"]
其中,operator支持In,NotIn, Exists, DoesNotExist. Gt, and Lt。
podAffinity
上面介紹的nodeSelector,nodeName,nodeAffinity都是針對節(jié)點(diǎn)的,下面介紹的podAffinity和podAntiAffinity則是針對Pod。
podAffinity表示Pod親和性調(diào)度,意識就是把Pod調(diào)度到與它比較緊密的Pod上,如下:
apiVersion: v1 kind: Pod metadata: name: fronted labels: app: myapp row: fronted spec: containers: - name: myapp image: ikubernetes/myapp:v1 --- apiVersion: v1 kind: Pod metadata: name: backend labels: app: db row: backend spec: containers: - name: db image: busybox imagePullPolicy: IfNotPresent command: - "/bin/sh" - "-c" - "sleep 3600" affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: ["myapp"] topologyKey: kubernetes.io/hostname
這表示把后端pod和前端pod調(diào)度在一起。
podAffinity也有preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution,也就是硬親和和軟親和,其使用情況和nodeAffinity一樣。
podAntiAffinity
上面介紹了pod的親和性,這里介紹的podAntiAffinity則是Pod的反親和性,也就是說不將這類Pod調(diào)度到一起。在日常工作中,這種親和性使用頻率還比較高。微服務(wù)很少有單Pod,基本都是多個(gè)Pod,為了提高應(yīng)用的高可用,不會將同應(yīng)用的多個(gè)Pod調(diào)度到同一臺機(jī)器上,這時(shí)候就要用到podAntiAffinity,如下:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - name: nginx image: nginx
污點(diǎn)調(diào)度
在Kubernetes中,有些節(jié)點(diǎn)自帶污點(diǎn) ,比如Master節(jié)點(diǎn),這類節(jié)點(diǎn),如果Pod沒有配置容忍污點(diǎn),則這些Pod不會調(diào)度到這類節(jié)點(diǎn)上。
在實(shí)際中,污點(diǎn)調(diào)度也是非常有用的,有些場景某些節(jié)點(diǎn)只允許某些項(xiàng)目組的Pod允許,比如大數(shù)據(jù)項(xiàng)目是一些高IO項(xiàng)目,不想和其他普通項(xiàng)目混合在一起,而其他項(xiàng)目如果使用標(biāo)簽選擇器配置部署又比較麻煩,這時(shí)候就可以使用污點(diǎn)選擇器。
我們可以通過kubectl explain node.spec.taints
來查看污點(diǎn)相關(guān)的配置信息:
$ kubectl explain node.spec.taints KIND: Node VERSION: v1 RESOURCE: taints <[]Object> DESCRIPTION: If specified, the node's taints. The node this Taint is attached to has the "effect" on any pod that does not tolerate the Taint. FIELDS: effect <string> -required- Required. The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule and NoExecute. Possible enum values: - `"NoExecute"` Evict any already-running pods that do not tolerate the taint. Currently enforced by NodeController. - `"NoSchedule"` Do not allow new pods to schedule onto the node unless they tolerate the taint, but allow all pods submitted to Kubelet without going through the scheduler to start, and allow all already-running pods to continue running. Enforced by the scheduler. - `"PreferNoSchedule"` Like TaintEffectNoSchedule, but the scheduler tries not to schedule new pods onto the node, rather than prohibiting new pods from scheduling onto the node entirely. Enforced by the scheduler. key <string> -required- Required. The taint key to be applied to a node. timeAdded <string> TimeAdded represents the time at which the taint was added. It is only written for NoExecute taints. value <string> The taint value corresponding to the taint key.
其中effect定義對Pod的排斥效果:
- NoSchdule:僅影響調(diào)度過程,對現(xiàn)存在的Pod不產(chǎn)生影響;
- NoExecute:不僅影響調(diào)度,而且還影響現(xiàn)存Pod,不容忍的Pod對象將被驅(qū)逐;
- PreferNoSchedule:軟排斥,不是完全禁止Pod調(diào)度;
如果要給節(jié)點(diǎn)添加污點(diǎn),則如下:
$ kubectl taint nodes kk-node01 node-type=dev:NoSchedule
給節(jié)點(diǎn) kk-node01增加一個(gè)污點(diǎn),它的鍵名是 node-type,鍵值是 dev,效果是 NoSchedule。這表示只有擁有和這個(gè)污點(diǎn)相匹配的容忍度的 Pod 才能夠被分配到 kk-node01這個(gè)節(jié)點(diǎn)。
如果要?jiǎng)h除污點(diǎn),則使用如下命令:
$ kubectl taint nodes kk-node01 node-type=dev:NoSchedule-
如果要配置容忍污點(diǎn),則如下:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 imagePullPolicy: IfNotPresent ports: - containerPort: 80 tolerations: - key: "node-type" operator: Equal value: dev effect: NoSchedule tolerationSeconds: 20
operator支持Equal
和Exists
,默認(rèn)是Equal
。
如果是Equal,表示污點(diǎn)的鍵值需要一致,如果使用Exists,則表示只要存在該鍵的污點(diǎn),比如:
tolerations: - key: "key1" operator: "Exists" effect: "NoSchedule"
該配置表示只要匹配容忍度,并且key1的健存在即可調(diào)度。
如果一個(gè)容忍度的 key 為空且 operator 為 Exists, 表示這個(gè)容忍度與任意的 key、value 和 effect 都匹配,即這個(gè)容忍度能容忍任何污點(diǎn)。如果 effect 為空,則可以與所有鍵名 key1 的效果相匹配。
你可以給一個(gè)節(jié)點(diǎn)添加多個(gè)污點(diǎn),也可以給一個(gè) Pod 添加多個(gè)容忍度設(shè)置。Kubernetes 處理多個(gè)污點(diǎn)和容忍度的過程就像一個(gè)過濾器:從一個(gè)節(jié)點(diǎn)的所有污點(diǎn)開始遍歷, 過濾掉那些 Pod 中存在與之相匹配的容忍度的污點(diǎn)。余下未被過濾的污點(diǎn)的 effect 值決定了 Pod 是否會被分配到該節(jié)點(diǎn),特別是以下情況:
- 如果未被忽略的污點(diǎn)中存在至少一個(gè) effect 值為 NoSchedule 的污點(diǎn), 則 Kubernetes 不會將 Pod 調(diào)度到該節(jié)點(diǎn)。
- 如果未被忽略的污點(diǎn)中不存在 effect 值為 NoSchedule 的污點(diǎn), 但是存在 effect 值為 PreferNoSchedule 的污點(diǎn), 則 Kubernetes 會 嘗試 不將 Pod 調(diào)度到該節(jié)點(diǎn)。
- 如果未被忽略的污點(diǎn)中存在至少一個(gè) effect 值為 NoExecute 的污點(diǎn), 則 Kubernetes 不會將 Pod 調(diào)度到該節(jié)點(diǎn)(如果 Pod 還未在節(jié)點(diǎn)上運(yùn)行), 或者將 Pod 從該節(jié)點(diǎn)驅(qū)逐(如果 Pod 已經(jīng)在節(jié)點(diǎn)上運(yùn)行)。
例如,假設(shè)你給一個(gè)節(jié)點(diǎn)添加了如下污點(diǎn)
$ kubectl taint nodes node1 key1=value1:NoSchedule $ kubectl taint nodes node1 key1=value1:NoExecute $ kubectl taint nodes node1 key2=value2:NoSchedule
假定有一個(gè) Pod,它有兩個(gè)容忍度:
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute"
在這種情況下,上述 Pod 不會被調(diào)度到上述節(jié)點(diǎn),因?yàn)槠錄]有容忍度和第三個(gè)污點(diǎn)相匹配。但是如果在給節(jié)點(diǎn)添加上述污點(diǎn)之前,該 Pod 已經(jīng)在上述節(jié)點(diǎn)運(yùn)行, 那么它還可以繼續(xù)運(yùn)行在該節(jié)點(diǎn)上,因?yàn)榈谌齻€(gè)污點(diǎn)是三個(gè)污點(diǎn)中唯一不能被這個(gè) Pod 容忍的。
通常情況下,如果給一個(gè)節(jié)點(diǎn)添加了一個(gè) effect 值為 NoExecute 的污點(diǎn), 則任何不能忍受這個(gè)污點(diǎn)的 Pod 都會馬上被驅(qū)逐,任何可以忍受這個(gè)污點(diǎn)的 Pod 都不會被驅(qū)逐。但是,如果 Pod 存在一個(gè) effect 值為 NoExecute 的容忍度指定了可選屬性 tolerationSeconds 的值,則表示在給節(jié)點(diǎn)添加了上述污點(diǎn)之后, Pod 還能繼續(xù)在節(jié)點(diǎn)上運(yùn)行的時(shí)間。例如:
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600
這表示如果這個(gè) Pod 正在運(yùn)行,同時(shí)一個(gè)匹配的污點(diǎn)被添加到其所在的節(jié)點(diǎn), 那么 Pod 還將繼續(xù)在節(jié)點(diǎn)上運(yùn)行 3600 秒,然后被驅(qū)逐。如果在此之前上述污點(diǎn)被刪除了,則 Pod 不會被驅(qū)逐。
重新調(diào)度
在Kubernetes中,kube-scheduler負(fù)責(zé)將Pod調(diào)度到合適的Node上,但是Kubernetes是一個(gè)非常動(dòng)態(tài)的,高度彈性的環(huán)境,有時(shí)候會造成某一個(gè)或多個(gè)節(jié)點(diǎn)pod數(shù)分配不均,比如:
- 一些節(jié)點(diǎn)利用率低下或過度使用
- 添加刪除標(biāo)簽或添加刪除污點(diǎn),pod或Node親和性改變等造成原調(diào)度不再滿足
- 一些節(jié)點(diǎn)故障,其上運(yùn)行的Pod調(diào)度到其他節(jié)點(diǎn)
- 新節(jié)點(diǎn)加入集群
由于以上種種原因,可能導(dǎo)致多個(gè)Pod運(yùn)行到不太理想的節(jié)點(diǎn),而整個(gè)K8S集群也會處于一段時(shí)間不均衡的狀態(tài),這時(shí)候就需要重新平衡集群。Descheduler就是這樣一個(gè)項(xiàng)目。
Descheduler可以根據(jù)一些規(guī)則配置來重新平衡集群狀態(tài),目前支持的策略有:
- RemoveDuplicates
- LowNodeUtilization
- RemovePodsViolatingInterPodAntiAffinity
- RemovePodsViolatingNodeAffinity
- RemovePodsViolatingNodeTaints
- RemovePodsViolatingTopologySpreadConstraint
- RemovePodsHavingTooManyRestarts
- PodLifeTime
這些策略可以啟用,也可以關(guān)閉,默認(rèn)情況下,所有策略都是啟動(dòng)的。
另外,還有一些通用配置,如下:
- nodeSelector:限制要處理的節(jié)點(diǎn)
- evictLocalStoragePods: 驅(qū)除使用LocalStorage的Pods
- ignorePvcPods: 是否忽略配置PVC的Pods,默認(rèn)是False
- maxNoOfPodsToEvictPerNode:節(jié)點(diǎn)允許的最大驅(qū)逐Pods數(shù)
由于我集群版本是1.24.2,所以安裝descheduler v0.24版本。
(1)下載對應(yīng)的Helm chart,我這里選擇的是0.24版本
$ wget https://github.com/kubernetes-sigs/descheduler/releases/download/descheduler-helm-chart-0.24.0/descheduler-0.24.0.tgz
(2)如果可以科學(xué)上網(wǎng),直接使用以下命令部署即可。
$ helm install descheduler .
如果不能科學(xué)上網(wǎng),就替換鏡像,修改value.yaml
里的鏡像信息,如下:
image: repository: registry.cn-hangzhou.aliyuncs.com/coolops/descheduler # Overrides the image tag whose default is the chart version tag: "v0.24.0" pullPolicy: IfNotPresent
然后再執(zhí)行安裝命令。
安裝完成過后,會配置默認(rèn)的調(diào)度策略,如下:
apiVersion: v1 data: policy.yaml: | apiVersion: "descheduler/v1alpha1" kind: "DeschedulerPolicy" strategies: LowNodeUtilization: enabled: true params: nodeResourceUtilizationThresholds: targetThresholds: cpu: 50 memory: 50 pods: 50 thresholds: cpu: 20 memory: 20 pods: 20 RemoveDuplicates: enabled: true RemovePodsViolatingInterPodAntiAffinity: enabled: true RemovePodsViolatingNodeAffinity: enabled: true params: nodeAffinityType: - requiredDuringSchedulingIgnoredDuringExecution RemovePodsViolatingNodeTaints: enabled: true kind: ConfigMap metadata: annotations: meta.helm.sh/release-name: descheduler meta.helm.sh/release-namespace: default creationTimestamp: "2022-08-02T03:06:57Z" labels: app.kubernetes.io/instance: descheduler app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: descheduler app.kubernetes.io/version: 0.24.0 helm.sh/chart: descheduler-0.24.0 name: descheduler namespace: default resourceVersion: "894636" uid: 4ab2e628-9404-4e52-bd88-615f5e096d90
其中配置了:
- LowNodeUtilization:設(shè)置了cpu\內(nèi)存\pod水位,thresholds表示未充分利用,targetThresholds表示過度使用
- RemoveDuplicates:開啟同節(jié)點(diǎn)只有一個(gè)Pod運(yùn)行
- RemovePodsViolatingInterPodAntiAffinity:刪除違反親和性的Pod
- RemovePodsViolatingNodeAffinity:刪除不滿足Node親和性的Pod
- RemovePodsViolatingNodeTaints:刪除不被Node污點(diǎn)容忍的Pod
并且會創(chuàng)建一個(gè)CronJob,周期性的執(zhí)行調(diào)度均衡。
apiVersion: batch/v1 kind: CronJob metadata: annotations: meta.helm.sh/release-name: descheduler meta.helm.sh/release-namespace: default creationTimestamp: "2022-08-02T03:06:57Z" generation: 1 labels: app.kubernetes.io/instance: descheduler app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: descheduler app.kubernetes.io/version: 0.24.0 helm.sh/chart: descheduler-0.24.0 name: descheduler namespace: default resourceVersion: "898221" uid: e209e498-71cb-413f-97a9-372aea5442bc spec: concurrencyPolicy: Forbid failedJobsHistoryLimit: 1 jobTemplate: metadata: creationTimestamp: null spec: template: metadata: annotations: checksum/config: 5efec14c3638fa4028e25f3fa067758f13dcae442fe711439c7d0b2e9913d41e creationTimestamp: null labels: app.kubernetes.io/instance: descheduler app.kubernetes.io/name: descheduler name: descheduler spec: containers: - args: - --policy-config-file - /policy-dir/policy.yaml - --v - "3" command: - /bin/descheduler image: registry.cn-hangzhou.aliyuncs.com/coolops/descheduler:v0.24.0 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10258 scheme: HTTPS initialDelaySeconds: 3 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: descheduler resources: requests: cpu: 500m memory: 256Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL privileged: false readOnlyRootFilesystem: true runAsNonRoot: true terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /policy-dir name: policy-volume dnsPolicy: ClusterFirst priorityClassName: system-cluster-critical restartPolicy: Never schedulerName: default-scheduler securityContext: {} serviceAccount: descheduler serviceAccountName: descheduler terminationGracePeriodSeconds: 30 volumes: - configMap: defaultMode: 420 name: descheduler name: policy-volume schedule: '*/2 * * * *' successfulJobsHistoryLimit: 3 suspend: false status: lastScheduleTime: "2022-08-02T03:28:00Z" lastSuccessfulTime: "2022-08-02T03:28:03Z"
該Job會每2分鐘執(zhí)行一次均衡調(diào)度。
總結(jié)
Kubernetes的調(diào)度策略是非常復(fù)雜的,里面有許多復(fù)雜的算法,這里介紹的只是一些常用的調(diào)度策略,足夠滿足日常使用。如果想更深入的研究可以多看看官方文檔以及源碼。
以上就是Kubernetes調(diào)度管理優(yōu)先級和搶占機(jī)制詳解的詳細(xì)內(nèi)容,更多關(guān)于Kubernetes調(diào)度管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Rainbond的ServiceMesh架構(gòu)組件端口沖突處理解決
這篇文章主要大家介紹了Rainbond?ServiceMesh架構(gòu)組件端口沖突處理方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04詳解Rainbond內(nèi)置ServiceMesh微服務(wù)架構(gòu)
這篇文章主要為大家介紹了詳解Rainbond內(nèi)置ServiceMesh微服務(wù)架構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04使用k8tz解決pod內(nèi)的時(shí)區(qū)問題(坑的解決)
時(shí)區(qū)的不一致,會帶來很多困擾。即使代碼與時(shí)區(qū)無關(guān),但容器日志與系統(tǒng)日志時(shí)間相關(guān)聯(lián)排查問題也會讓人頭疼,這篇文章主要介紹了使用k8tz優(yōu)雅的解決pod內(nèi)的時(shí)區(qū)問題,需要的朋友可以參考下2022-10-10IoT?邊緣集群Kubernetes?Events告警通知進(jìn)一步配置詳解
這篇文章主要為大家介紹了IoT?邊緣集群Kubernetes?Events告警通知進(jìn)一步配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02