k8s集群調(diào)度詳解(kube-scheduler)
了解kube-scheduler
- 由之前博客可知kube-scheduler是k8s中master的核心組件之一
- scheduler:負(fù)責(zé)調(diào)度資源。把pod調(diào)度到node節(jié)點(diǎn)。他有兩種策略:
- 預(yù)算策略:人為部署,指定node節(jié)點(diǎn)去部署新建的pod
- 優(yōu)先策略:通過算法選擇一個(gè)負(fù)載最小,資源最充沛的資源去部署。
k8s中List-watch
k8s集群當(dāng)中,通過list-watch的機(jī)制進(jìn)行每個(gè)組的寫作,保持?jǐn)?shù)據(jù)同步。這種設(shè)計(jì)可以實(shí)現(xiàn)每個(gè)組件之間的解耦(解耦:減少每個(gè)組件之間的關(guān)聯(lián)性)。
kubectl來配置文件,向APIServer發(fā)送命令----apiserver把命令發(fā)送到各個(gè)組件。
kubectl run nginx --image=nginx:1.22-------apiserver------controller manager------scheduler-------kubelet.。
創(chuàng)建成功之后,kubectl get pod kubectl describe pod nginx-------保存到etcd當(dāng)中
以上過程是list-watch會(huì)在每一步把監(jiān)聽的消息(APIserver:6443)-------controller manager,scheduler,kubelet,etcd都會(huì)監(jiān)聽apiserver:6443
工作流程圖

注意:
- 在創(chuàng)建 Pod 的工作就已經(jīng)完成了后,為什么 kubelet 還要一直監(jiān)聽呢?
- 原因很簡單,假設(shè)這個(gè)時(shí)候 kubectl 發(fā)命令,要擴(kuò)充 Pod 副本數(shù)量,那么上面的流程又會(huì)觸發(fā)一遍,kubelet 會(huì)根據(jù)最新的 Pod 的部署情況調(diào)整 Node 的資源。
- 又或者 Pod 副本數(shù)量沒有發(fā)生變化,但是其中的鏡像文件升級(jí)了,kubelet 也會(huì)自動(dòng)獲取最新的鏡像文件并且加載。
調(diào)度的過程和策略
scheduler是k8s集群的調(diào)取器,把pod分配到集群的節(jié)點(diǎn)。
以下幾個(gè)問題需要考慮:
1.公平:每個(gè)節(jié)點(diǎn)都能夠分配資源。
2.資源高效利用:集群當(dāng)中的資源可以被最大化利用
3.效率:調(diào)度的性能要搞好。能夠盡快的完成大批量的pod的調(diào)度工作。
4.靈活:允許用戶根據(jù)自己的需求,控制和改變調(diào)度的邏輯。
- scheduler是一個(gè)單獨(dú)運(yùn)行的程序,啟動(dòng)之后就會(huì)一直監(jiān)聽APIserver,獲取報(bào)文中的字段:spec.modeName
- 創(chuàng)建pod時(shí)候,為每個(gè)pod創(chuàng)建一個(gè)binding,表示該往哪個(gè)節(jié)點(diǎn)上部署。
- 創(chuàng)建pod到節(jié)點(diǎn)時(shí),有兩個(gè)策略:先執(zhí)行預(yù)算策略,再執(zhí)行優(yōu)先策略。這兩步都必須成功,否則立刻返回報(bào)錯(cuò)。
- 也就是說,部署的node,必須滿足這兩個(gè)策略。
預(yù)算策略
predicate自帶一些算法來選擇node節(jié)點(diǎn)(scheduler自帶的算法策略。不需人工干預(yù))
- 1.podfitsresoureces:Pod的適應(yīng)資源,檢測(cè)節(jié)點(diǎn)上剩余測(cè)資源是否滿足pod請(qǐng)求的資源主要是cpu和內(nèi)存。
- 2.podfitshost:pod適應(yīng)主機(jī),如果pod指定了node的name。nginx1 pod---> node01,檢測(cè)主機(jī)名是否存在,存在要和pod指定的名稱匹配,這才能調(diào)度過去。
- 3.podselectormatches:pod選擇器匹配,創(chuàng)建pod的時(shí)候可以根據(jù)node的標(biāo)簽來進(jìn)行匹配。查找指定的node節(jié)點(diǎn)上標(biāo)簽是否存在,存在的標(biāo)簽是否匹配。
- 4.nodiskconflict:無磁盤沖突,確保已掛載的卷與pod的卷不發(fā)生沖突,除非目錄是只讀。
只有上述策略完成,才回到優(yōu)先策略。如果預(yù)算策略都不滿足,pod將始終處于pending狀態(tài),不斷地重試調(diào)度,直到有節(jié)點(diǎn)滿足條件為止。
如果node1,node2,node3經(jīng)過預(yù)算策略,上述三個(gè)節(jié)點(diǎn)都滿足條件----》優(yōu)先策略
優(yōu)先策略
leastreaquestedpriority
最低請(qǐng)求優(yōu)先級(jí),通過算法計(jì)算節(jié)點(diǎn)上的cpu和內(nèi)存使用率,確定節(jié)點(diǎn)的權(quán)重。
使用率越低的節(jié)點(diǎn)相應(yīng)的權(quán)重就越高。調(diào)度時(shí)會(huì)更傾向于使用率低的節(jié)點(diǎn)。實(shí)現(xiàn)資源合理的利用。
balancersourceallocation
平衡資源分配,考慮cpu和內(nèi)存的使用率,給節(jié)點(diǎn)賦予權(quán)重。權(quán)重算的是cpu和內(nèi)存使用率接近。使用率越接近,權(quán)重越高。
和上面的leastreaquestedpriority最低請(qǐng)求優(yōu)先級(jí)一起使用。
舉個(gè)例子,有node1,node2兩個(gè)節(jié)點(diǎn),資源分別是:
- node1 cpu和內(nèi)存使用率: 20:60
- node2 cpu和內(nèi)存使用率: 50:50
- node2再被調(diào)度時(shí)會(huì)被優(yōu)先
imagelocalitypriority
節(jié)點(diǎn)上是否已經(jīng)有了要部署的鏡像。鏡像的總數(shù)成正比,滿足的鏡像數(shù)越多,權(quán)重越高。
以上這些策略scheduler自帶的算法。
通過預(yù)算選擇出可以部署的節(jié)點(diǎn),再通過優(yōu)先選擇出來最好的節(jié)點(diǎn),以上都是自帶的算法。k8s集群自己來選擇。
總的來說:
- 預(yù)選策略 :通過調(diào)度算法過濾掉不滿足條件的Node節(jié)點(diǎn)
- 優(yōu)選策略 :通過優(yōu)先級(jí)選項(xiàng)給滿足調(diào)度條件的Node節(jié)點(diǎn)進(jìn)行優(yōu)先級(jí)權(quán)重排序,最終選擇優(yōu)先級(jí)最高的Node節(jié)點(diǎn)來調(diào)度Pod
如何指定節(jié)點(diǎn)部署
指定節(jié)點(diǎn)配置需要在spec模塊中參數(shù)設(shè)置:
nodeName:node02
首先,我們?yōu)榱朔乐箍s進(jìn)錯(cuò)誤,用生成的yaml文件修改:


apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx2
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.22
name: nginx
nodeName: node02如果指定了節(jié)點(diǎn),在參數(shù)中設(shè)置了nodeName,指定了節(jié)點(diǎn)的名稱,會(huì)跳過scheduler調(diào)度策略。這個(gè)規(guī)則是強(qiáng)制匹配
如何指定標(biāo)簽部署
我們可以通過以下命令查看node的標(biāo)簽
kubectl get nodes --show-labels

我們可以在命令行給node添加標(biāo)簽
kubectl label nodes node02 test3=c

已經(jīng)部署的服務(wù)器的標(biāo)簽

已經(jīng)部署的服務(wù)器的標(biāo)簽

節(jié)點(diǎn)資源不夠會(huì)進(jìn)入pending

指定節(jié)點(diǎn)標(biāo)簽部署pod,是要經(jīng)過scheduler的算法,如果節(jié)點(diǎn)不滿足條件,pod會(huì)進(jìn)入penging狀態(tài),直到節(jié)點(diǎn)條件滿足為止。
k8s集群的親和性
軟策略和硬策略
node節(jié)點(diǎn)親和性:
preferredDuringSchedulingIgnoredDuringExecution軟策略:
- 選擇node節(jié)點(diǎn)時(shí),我聲明了我最好能部署在node01,軟策略會(huì)盡量滿足這個(gè)條件。
- 不一定會(huì)完全部署在node01節(jié)點(diǎn)上。
requiredDuringSchedulingIgnoredDuringExecution硬策略:
- 選擇pod時(shí),聲明了node01,我是硬策略,必須滿足硬策略的條件。
- 必須部署在node01,強(qiáng)制性要求
pod的親和性
preferredDuringSchedulingIgnoredDuringExecution軟策略
要求調(diào)度器將pod調(diào)度到其他pod的親和性匹配的節(jié)點(diǎn)上??梢允?,也可以不是,盡量滿足
- pod nginx1 node01
- pod nginx2 node02 希望和nginx1部署在一個(gè)節(jié)點(diǎn),盡量滿足
requiredDuringSchedulingIgnoredDuringExecution硬策略
- pod nginx1 node01
- pod nginx2 node02 必須要和nginx的親和性匹配,只能往node01。
鍵值的運(yùn)算關(guān)系
標(biāo)簽:都是根據(jù)標(biāo)簽開選擇親和性。
In:在
選擇的標(biāo)簽值在node節(jié)點(diǎn)上存在。
Notin:不在
選擇label的值不在node節(jié)點(diǎn)上
- Gt:大于,大于選擇的標(biāo)簽值
- Lt:小于,小于選擇標(biāo)簽值。
- Exists:存在,選擇標(biāo)簽對(duì)象,值不考慮。
- DoesNotExit:選擇不具有指定表
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx2
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
test01: a
containers:
- image: nginx:1.22
name: nginx
affinity:
#選擇親和性部署方式
nodeAffintity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
選擇了親和性nodeSelectorsTerms你要選擇哪個(gè)nodez作為node為硬策略,匹配的節(jié)點(diǎn)標(biāo)簽
- matchExpressions:
定義一個(gè)符合我要選擇的node節(jié)點(diǎn)的信息
- key: test3
operator: In(NotIn)
指定鍵值對(duì)的算法
values:
- c
wq
刪除標(biāo)簽
kubectl label nodes node01 test2-

- key: memory
operator: Gt
values:
- "612"
wq
kubectl label nodes node02 memory=1000- Gt:大于,大于選擇的標(biāo)簽值
- Lt:小于,小于選擇標(biāo)簽值。
只能比較整數(shù)值
親和性策略根據(jù)標(biāo)簽來選擇。
- Exists:存在,選擇標(biāo)簽對(duì)象,值不考慮。
- DoesNotExit:選擇不具有指定表
- key: memory
operator: Exists
values:
- "612"
wq
kubectl apply -f test1.yaml
會(huì)報(bào)錯(cuò),因?yàn)椴荒苡兄?
所以:
- key: memory
operator: Exists
指定鍵值對(duì)的算法為Exists or DoesNotExists不能使用values字段。軟策略
affinity:
#選擇親和性部署方式
nodeAffintity:
preferredDuringSchedulingIgnoredDuringExecution:
-weight: 1
選擇軟策略之后要加上權(quán)重
preference:
選擇節(jié)點(diǎn)的傾向,盡量滿足要求而不是一定。
選擇了親和性nodeSelectorsTerms你要選擇哪個(gè)nodez作為node為硬策略,匹配的節(jié)點(diǎn)標(biāo)簽
- matchExpressions:
定義一個(gè)符合我要選擇的node節(jié)點(diǎn)的信息
- key: memory
operator: DoesNotExist
wq多個(gè)軟策略通過什么匹配?
affinity:
#選擇親和性部署方式
nodeAffintity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
選擇軟策略之后要加上權(quán)重
preference:
選擇節(jié)點(diǎn)的傾向,盡量滿足要求而不是一定。
選擇了親和性nodeSelectorsTerms你要選擇哪個(gè)nodez作為node為硬策略,匹配的節(jié)點(diǎn)標(biāo)簽
- matchExpressions:
定義一個(gè)符合我要選擇的node節(jié)點(diǎn)的信息
- key: memory
operator: DoesNotExist
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
preference:
matchExpressions:
- key: memory
operator: In
values:
- "500"
多個(gè)軟策略以權(quán)重高的為標(biāo)的
軟硬策略結(jié)合的話結(jié)果是什么?

affinity:
nodeAffintity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
- matchExpressions:
- key: memory
operator: Exists
values:
- "1000"
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: memory
operator: In
values:
- "500"
wq
kubectl apply -f test1.yaml多個(gè)軟策略看權(quán)重,權(quán)重高,執(zhí)行指定的軟策略。
硬策略:先滿足硬策略,硬策略一個(gè)都不滿足才會(huì)執(zhí)行軟策略。
你在部署的時(shí)候選擇一個(gè)什么樣的策略
node親和性:性能不一致,我盡量把pod往性能高的多部署,軟策略
節(jié)點(diǎn)故障或者節(jié)點(diǎn)維護(hù),只能選擇硬策略,把節(jié)點(diǎn)故障剔除。
舉例子:
4/8G 4/8G 2/4G
node1 node2 node3
性能不一致的時(shí)候最好使用軟策略
如果其中一個(gè)node 掛了,可以使用硬策略來指定部署。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
k8s kubectl啟動(dòng)成功,但執(zhí)行命令時(shí)報(bào)錯(cuò)解決:The connection to&
用戶使用kubectl時(shí)出現(xiàn)連接拒絕錯(cuò)誤,排查發(fā)現(xiàn)配置文件名非admin.conf,修改后問題解決,提示需使用kubernetes-admin配置文件以確保正確性2025-08-08
k8s:pod has unbound PersistentVolumeClaims問題及
部署redis-ha時(shí),Pod因PVC未綁定報(bào)錯(cuò),原因在于value.yaml中storageClassName為空,且未啟用DefaultDefaultStorageClass,解決方法是手動(dòng)指定PVC的StorageClassName為現(xiàn)有存儲(chǔ)類,確保PV分配成功2025-07-07
K8S如何利用Prometheus監(jiān)控pod的實(shí)時(shí)數(shù)據(jù)指標(biāo)
這篇文章主要給大家介紹了關(guān)于K8S如何利用Prometheus監(jiān)控pod的實(shí)時(shí)數(shù)據(jù)指標(biāo)的相關(guān)資料,Prometheus是一個(gè)開源的服務(wù)監(jiān)控系統(tǒng)和時(shí)序數(shù)據(jù)庫,其提供了通用的數(shù)據(jù)模型和快捷數(shù)據(jù)采集、存儲(chǔ)和查詢接口,需要的朋友可以參考下2024-01-01
K8S中某個(gè)容器突然出現(xiàn)內(nèi)存和CPU占用過高的問題及解決方案
當(dāng)K8S容器出現(xiàn)資源過載時(shí),可通過kubectl監(jiān)控定位問題,調(diào)整資源限制,優(yōu)化應(yīng)用代碼,拆分多應(yīng)用容器,利用監(jiān)控工具排查,實(shí)施水平擴(kuò)展或遷移負(fù)載,確保集群穩(wěn)定運(yùn)行2025-07-07
詳解kubelet?創(chuàng)建pod流程代碼圖解及日志說明
這篇文章主要為大家介紹了詳解kubelet?創(chuàng)建pod流程代碼圖解及日志說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
詳解Rainbond內(nèi)置ServiceMesh微服務(wù)架構(gòu)
這篇文章主要為大家介紹了詳解Rainbond內(nèi)置ServiceMesh微服務(wù)架構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
最新青龍面板2.10.2搭建+XDD-PLUS的保姆級(jí)教程
這篇文章主要介紹了最新青龍面板2.10.2搭建+XDD-PLUS的保姆級(jí)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
關(guān)于Rancher部署并導(dǎo)入K8S集群的問題
這篇文章主要介紹了關(guān)于Rancher部署并導(dǎo)入K8S集群的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
Podman開機(jī)自啟容器實(shí)現(xiàn)過程及與Docker對(duì)比
這篇文章主要為大家介紹了Podman開機(jī)自啟容器實(shí)現(xiàn)過程,通過示例代碼的形式進(jìn)行演繹過程,有需要的朋友可以參考下,希望可以有所幫助2021-09-09

