介紹
優(yōu)先級調(diào)度其實沒有那么常用,但是既然K8s提供出來了诱渤,我們還是了解一下丐巫,在1.8版本之前,當集群資源不足時又有新的Pod創(chuàng)建請求勺美,那么這個Pod會一直處于Pending狀態(tài)递胧,就算是這個Pod非常的重要,非部署不可赡茸,那也沒辦法缎脾,你只能刪除一些Pod釋放一些資源才能被調(diào)度成功。
為了解決該問題占卧,在1.8版本就引入了優(yōu)先級搶占調(diào)度策略遗菠,如果新調(diào)度的優(yōu)先級非常高,那么集群會嘗試釋放優(yōu)先級低的Pod以保證新的Pod可以正常調(diào)度华蜒,這種方式稱為搶占式調(diào)度辙纬,1.11版本升級為Beta版本,1.14版本之后成為正式版本
調(diào)度策略
調(diào)度策略有兩種一種是驅(qū)逐( Eviction )一種是搶占( Preemtion )叭喜,兩種方式的場景不同贺拣,效果也不同
Eviction 是kubelet進程的行為,當該Node上的資源不足時,kubelet就會執(zhí)行驅(qū)逐動作譬涡,配合優(yōu)先級闪幽,將優(yōu)先級低的Pod驅(qū)逐,如果優(yōu)先級都一樣涡匀,那么實際使用的資源量超過申請量最大倍數(shù)的高耗能 Pod 會被首先驅(qū)逐
Preemption 是 Scheduler 執(zhí)行調(diào)度的行為沟使,當有新的Pod創(chuàng)建,但是因為資源不夠無法正常調(diào)度渊跋,調(diào)度器便會驅(qū)逐部分優(yōu)先級較低的Pod來滿足新Pod的需求
創(chuàng)建權(quán)重
權(quán)重是區(qū)分優(yōu)先級的關(guān)鍵因素
yaml定義
通過yaml方式定義一個PriorityClass,它不屬于任何命名空間
app-priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: app-priority
value: 100 # 優(yōu)先級為100着倾,數(shù)字越大拾酝,優(yōu)先級越高
globalDefault: false
description: " app test priority."
屬性分析
PriorityClass不受命名空間約束
value越大優(yōu)先級越高,但是不要超過10億卡者,超過10億的通常是不該被驅(qū)逐的Pod蒿囤,一般K8s內(nèi)部使用
查看系統(tǒng)自帶的優(yōu)先級
[root@master ~]# kubectl get PriorityClass
NAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000 false 52d
system-node-critical 2000001000 false 52d
查看kube-apiserver-master使用的優(yōu)先級
[root@master ~]# kubectl describe -pod kube-apiserver-master -n kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
沒有設置優(yōu)先級的Pod默認優(yōu)先級為0
globalDefault 給沒有設置優(yōu)先級的Pod使用,整個系統(tǒng)只能設置一個globalDefault=true的PriorityClass
description 描述什么時候應該使用該優(yōu)先級
創(chuàng)建
創(chuàng)建優(yōu)先級app-priority
# 創(chuàng)建優(yōu)先級
[root@master priority]# kubectl create -f app-priority.yaml
priorityclass.scheduling.k8s.io/app-priority created
# 查看創(chuàng)建是否成功
[root@master priority]# kubectl get PriorityClass
NAME VALUE GLOBAL-DEFAULT AGE
app-priority 100 false 8s
system-cluster-critical 2000000000 false 52d
system-node-critical 2000001000 false 52d
使用優(yōu)先級
這里不模擬資源不足的場景崇决,我們結(jié)合前面講到的親和性調(diào)度與污點來模擬效果
給node02設置上一個污點材诽,使得Pod不能調(diào)度進來,給node01運行一個帶有標簽env=pro的Pod恒傻,再創(chuàng)建一個新的Pod使用了優(yōu)先級app-priority脸侥,并且通過反親和性設置不能調(diào)度到帶有標簽env=pro的Pod所在Node,那么新Pod將沒有節(jié)點可調(diào)度盈厘,但是由于它的優(yōu)先級高睁枕,那么會不會丟車保帥,將node01上的Pod驅(qū)逐呢沸手?
下面來驗證一下
創(chuàng)建帶有標簽env=pro的Pod外遇,yaml配置如下
target-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: target-pod
labels:
env: pro
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent # 本地有不拉取鏡像
nodeName: node01 # 將target放到node01
創(chuàng)建帶有優(yōu)先級的Pod,yaml如下
priority-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: priority-pod
labels:
env: pro
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent # 本地有不拉取鏡像
affinity:
podAntiAffinity: # 使用Pod反親和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
- labelSelector:
matchExpressions:
- key: env
operator: In
values: ["pro"]
topologyKey: kubernetes.io/hostname
priorityClassName: app-priority
給node02創(chuàng)建污點契吉,模擬不可用
創(chuàng)建target-pod跳仿,觀察是否運行正常
啟動priority-pod,此時立刻查看Pod詳情捐晶,看target-pod是否正在被驅(qū)逐
# 給node02創(chuàng)建污點菲语,模擬不可用
[root@master priority]# kubectl taint node node02 app=true:NoExecute
node/node02 tainted
# 啟動traget-pod
[root@master priority]# kubectl create -f target-pod.yaml
pod/target-pod created
[root@master priority]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
target-pod 1/1 Running 0 11s 10.244.1.97 node01 <none> <none>
# 啟動priority-pod并且立刻查看Pod詳情,target-pod正在被驅(qū)逐
[root@master priority]# kubectl create -f priority-pod.yaml && kubectl get pod -o wide
pod/priority-pod created
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
priority-pod 0/1 Pending 0 0s <none> <none> node01 <none>
target-pod 1/1 Terminating 0 15s 10.244.1.99 node01 <none> <none>
# 再次查看Pod詳情租悄,priority-pod運行成功谨究,target-pod被驅(qū)逐
[root@master priority]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
priority-pod 1/1 Running 0 8s 10.244.1.100 node01 <none> <none>
需要注意的是,新的Pod并不會立刻就被調(diào)度到Node節(jié)點泣棋, 調(diào)度器只會將搶占者的 spec.nominatedNodeName 字段胶哲,設置為被搶占的 Node 的名字 ,等待下一輪周期才決定要不要調(diào)度到搶占的Node節(jié)點潭辈,原因是被驅(qū)逐的Pod是通過 DELETE API 來刪除被搶占的 Pod鸯屿,一般的應用都有優(yōu)雅停機時長澈吨,在這段時間里可調(diào)度性可能會發(fā)生變化,也許都不需要搶占了寄摆,所以這樣設置還是比較合理谅辣,但是如果這段時間有更高級別的Pod來搶, 那么調(diào)度器就會清空原搶占者的 spec.nominatedNodeName 字段婶恼,保證優(yōu)先級更高的Pod進行調(diào)度桑阶,當K8s有多個調(diào)度器,這種方式可能會陷入死循環(huán)勾邦,所以優(yōu)先級調(diào)度其實不太常用蚣录。
優(yōu)先級調(diào)度就介紹到這里,后面介紹Pod控制器
歡迎關(guān)注眷篇,學習不迷路萎河!