K8s之Node親和性調(diào)度

前言

前面介紹了定向調(diào)度轨奄,雖然很方便孟害,但是也存在一些問題,不夠靈活并且是硬限制挪拟,如果Node節(jié)點(diǎn)不存在挨务,那么該P(yáng)od就運(yùn)行不了,所以使用場景還是有所限制玉组。

針對于上面問題谎柄,k8s就給我們提供了親和性調(diào)度,它在NodeSelector上做了一些擴(kuò)展惯雳,可以通過配置優(yōu)先選擇符合條件的Node節(jié)點(diǎn)朝巫,如果沒有也可以調(diào)度到其它Node節(jié)點(diǎn)上,取代了定向調(diào)度的硬限制吨凑。隨著親和性調(diào)度越來越能夠體現(xiàn)NodeSelector的功能捍歪,最終NodeSelector應(yīng)該會(huì)被廢棄

親和性調(diào)度有兩種分別是 節(jié)點(diǎn)親和性 與 Pod親和性户辱。本文主要介紹節(jié)點(diǎn)親和性,Pod親和性后面更新

NodeAffinity

NodeAffinity表示Node親和性調(diào)度糙臼,用于替換NodeSelector的全新調(diào)度策略

目前nodeAffinity有兩種配置項(xiàng)

requiredDuringSchedulingIgnoredDuringExecution

必須滿足指定的規(guī)則才能將Pod調(diào)度到節(jié)點(diǎn)庐镐,屬于硬限制,調(diào)度完成之后就不再檢查條件是否滿足变逃,與NodeSelector非常像只是語法不同必逆,所以說NodeAffinity可以替代NodeSelector

通過 kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution 可以查看配置項(xiàng),具體如下

requiredDuringSchedulingIgnoredDuringExecution
  nodeSelectorTerms  #<[]Object> -required- 節(jié)點(diǎn)選擇列表
  - matchFields   # <[]Object> 按節(jié)點(diǎn)字段列出的節(jié)點(diǎn)選擇器要求列表  
  - matchExpressions   #<[]Object> 按節(jié)點(diǎn)標(biāo)簽列出的節(jié)點(diǎn)選擇器要求列表(推薦)
    - key    # 標(biāo)簽名
      operator # 操作符 包括 In揽乱、NotIn名眉、Exists、DoesNotExist凰棉、Gt损拢、Lt
      values # 標(biāo)簽值

操作符代表的含義如下

In # label的值必須在某個(gè)節(jié)點(diǎn)列表中
NotIn # 與In相反
Exists # 某個(gè)label存在
DoesNotExist # 某個(gè)label不存在
Gt # label的值大于某個(gè)值
Lt # label的值小于某個(gè)值

后面講的Pod親和性具有互斥功能,Node親和性雖然語法上沒有互斥功能撒犀,但是通過 NotIn和DoesNotExist可以實(shí)現(xiàn)節(jié)點(diǎn)互斥的功能

通過kubectl label命令給node01打上北京機(jī)房的標(biāo)簽福压,給node02打上上海機(jī)房的標(biāo)簽

kubectl label nodes node01 area=bj
kubectl label nodes node02 area=shanghai

# 查看標(biāo)簽是否設(shè)置成功
kubectl get nodes --show-labels

編寫 nginx-nodeAffinity-required.yaml 內(nèi)容如下

apiVersion: v1
kind: Pod
metadata:
  name: nginx-node-affinity-required
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: area
            operator: In
            values: ['bj','changsha']

啟動(dòng)Pod,由于設(shè)置values: ['bj','changsha']或舞,所以只有node01滿足要求荆姆,觀察Pod所在節(jié)點(diǎn)

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-required.yaml
pod/nginx-node-affinity-required created

# 查看Pod詳情,落在node01節(jié)點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-required   1/1     Running   0          23s   10.244.1.71   node01   <none>           <none>

修改yaml為values: ['shanghai','changsha']映凳,此時(shí)只有node02滿足要求胆筒,啟動(dòng)Pod觀察Pod所在節(jié)點(diǎn)

# 刪除之前Pod
[root@master affinity]# kubectl delete -f nginx-nodeAffinity-required.yaml 
pod "nginx-node-affinity-required" deleted

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-required.yaml
pod/nginx-node-affinity-required created

# 查看Pod詳情,落在node02節(jié)點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-required   1/1     Running   0          8s    10.244.2.24   node02   <none>           <none>

修改yaml為values: ['hangzhou','changsha']诈豌,此時(shí)沒有節(jié)點(diǎn)滿足要求仆救,前面提到requiredDuringSchedulingIgnoredDuringExecution屬于硬限制,所以Pod應(yīng)該運(yùn)行不起來队询,啟動(dòng)Pod,觀察Pod狀態(tài)

# 刪除之前Pod
[root@master affinity]# kubectl delete -f nginx-nodeAffinity-required.yaml 
pod "nginx-node-affinity-required" deleted

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-required.yaml
pod/nginx-node-affinity-required created

# 查看Pod詳情派桩,狀態(tài)為Pending并沒有運(yùn)行成功
[root@master affinity]# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-required   0/1     Pending   0          14s   <none>   <none>   <none>           <none>

# 查看啟動(dòng)過程事件,拋出異常
[root@master affinity]# kubectl describe  pod nginx-node-affinity-required|grep -A 100 Event
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  44s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.
preferredDuringSchedulingIgnoredDuringExecution

優(yōu)先滿足指定規(guī)則蚌斩,調(diào)度器會(huì)嘗試調(diào)度Pod到指定Node铆惑,如果沒有此節(jié)點(diǎn),也不會(huì)強(qiáng)制要求送膳,是一個(gè)軟限制员魏。如果有多個(gè)匹配規(guī)則,可以設(shè)置權(quán)重(weight)來定義執(zhí)行的先后順序叠聋。

通過 kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution 可以查看配置項(xiàng)撕阎,具體如下

preferredDuringSchedulingIgnoredDuringExecution
- weight # 權(quán)重,范圍1-100碌补。
  preference # 一個(gè)節(jié)點(diǎn)選擇器項(xiàng)虏束,與相應(yīng)的權(quán)重相關(guān)聯(lián)
    matchFields #  <[]Object> 按節(jié)點(diǎn)字段列出的節(jié)點(diǎn)選擇器要求列表
    matchExpressions  # <[]Object> 按節(jié)點(diǎn)標(biāo)簽列出的節(jié)點(diǎn)選擇器要求列表(推薦)
      key # 標(biāo)簽
      operator # 操作符
      values # <[]string> 標(biāo)簽值

編寫 nginx-nodeAffinity-preferred.yaml 內(nèi)容如下,設(shè)置兩個(gè)匹配規(guī)則棉饶,以權(quán)重定義執(zhí)行順序

apiVersion: v1
kind: Pod
metadata:
  name: nginx-node-affinity-preferred
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: area
            operator: In
            values: ['bj']
      - weight: 2
        preference:
          matchExpressions:
          - key: area
            operator: In
            values: ['shanghai']

啟動(dòng)Pod,由于設(shè)置有兩個(gè)匹配規(guī)則镇匀,并且shanghai的優(yōu)先級高于bj照藻,所以應(yīng)該要落在node02節(jié)點(diǎn),觀察Pod所在節(jié)點(diǎn)

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-preferred.yaml
pod/nginx-node-affinity-preferred created

# 查看Pod詳情汗侵,落在node02節(jié)點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-preferred   1/1     Running   0          12s   10.244.2.25   node02   <none>           <none>

修改yaml將bj的權(quán)重設(shè)為3幸缕,再次啟動(dòng)Pod,觀察Pod所在節(jié)點(diǎn)

# 刪除之前Pod
[root@master affinity]# kubectl delete -f nginx-nodeAffinity-preferred.yaml
pod "nginx-node-affinity-preferred" deleted

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-preferred.yaml
pod/nginx-node-affinity-preferred created

# 查看Pod詳情晰韵,落在node01節(jié)點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-preferred   1/1     Running   0          8s    10.244.1.72   node01   <none>           <none>

修改yaml如下发乔,條件均不滿足

apiVersion: v1
kind: Pod
metadata:
  name: nginx-node-affinity-preferred
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: area
            operator: In
            values: ['changsha']
      - weight: 2
        preference:
          matchExpressions:
          - key: area
            operator: In
            values: ['hangzhou']

啟動(dòng)Pod,上面提到雪猪,這種調(diào)度為軟限制栏尚,如果沒有找到符合條件的Node會(huì)退而求其次,選擇一個(gè)資源充足的Pod進(jìn)行調(diào)度

# 刪除之前Pod
[root@master affinity]# kubectl delete -f nginx-nodeAffinity-preferred.yaml
pod "nginx-node-affinity-preferred" deleted

# 啟動(dòng)
[root@master affinity]# kubectl create -f nginx-nodeAffinity-preferred.yaml
pod/nginx-node-affinity-preferred created

# 調(diào)度到了node01幾點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-node-affinity-preferred   1/1     Running   0          4s    10.244.1.74   node01   <none>           <none>

問題

由于nodeSelector還未被廢棄浪蹂,那么同時(shí)設(shè)置nodeSelector與nodeAffinity抵栈,該如何調(diào)度

從上面給出的親和性配置項(xiàng)可以知道nodeSelectorTerms為一個(gè)數(shù)組類型,可以設(shè)置多個(gè)matchExpressions坤次,那么有多個(gè)matchExpressions該如何匹配

matchExpressions也是一個(gè)數(shù)組,可以設(shè)置多組key-value操作斥赋,這又該如何匹配

同時(shí)定義nodeSelector與nodeAffinity

編寫 affinity-nodeselector.yaml 內(nèi)容如下

apiVersion: v1
kind: Pod
metadata:
  name: affinity-nodeselector
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: area
            operator: In
            values: ['bj']
  nodeSelector:
    area: shanghai

啟動(dòng)Pod缰猴,由于兩者都是硬限制,限制的條件不同應(yīng)該無法調(diào)度疤剑。

# 啟動(dòng)Pod
[root@master affinity]# kubectl create -f affinity-nodeselector.yaml 
pod/affinity-nodeselector created

# 查看Pod狀態(tài)滑绒,未啟動(dòng)成功
[root@master affinity]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
affinity-nodeselector   0/1     Pending   0          9s

# 查看啟動(dòng)事件,看到了似曾相識的報(bào)錯(cuò)
[root@master affinity]# kubectl describe pod affinity-nodeselector | grep -A 100 Events
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  34s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.

修改nodeSelector隘膘,將條件也設(shè)置為bj,啟動(dòng)成功

[root@master affinity]# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
affinity-nodeselector   1/1     Running   0          7s    10.244.1.75   node01   <none>           <none>
nodeAffinity指定多個(gè)matchExpressions如何執(zhí)行

編寫 multiple-nodeselectorterms.yaml 內(nèi)容如下

apiVersion: v1
kind: Pod
metadata:
  name: multiple-nodeselectorterms
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: area
            operator: In
            values: ['changsha']
        - matchExpressions:
          - key: area
            operator: In
            values: ['shanghai']

啟動(dòng)Pod疑故,如果可以啟動(dòng)成功并且在node02節(jié)點(diǎn),表示只要滿足一個(gè)條件即可弯菊,如果啟動(dòng)不成功表示都要滿足

# 啟動(dòng)
[root@master affinity]# kubectl create -f multiple-nodeselectorterms.yaml                
pod/multiple-nodeselectorterms created

# 觀察Pod詳情纵势,啟動(dòng)成功,并且Pod落在node02節(jié)點(diǎn)
[root@master affinity]# kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
multiple-nodeselectorterms   1/1     Running   0          19s   10.244.2.26   node02   <none>           <none>
matchExpressions有多個(gè)匹配項(xiàng)

編寫 multiple-matchexpressions.yaml 內(nèi)容如下

apiVersion: v1
kind: Pod
metadata:
  name: multiple-matchexpressions
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: area
            operator: In
            values: ['changsha']
          - key: area
            operator: In
            values: ['shanghai']

啟動(dòng)Pod管钳,如果可以啟動(dòng)成功并且在node02節(jié)點(diǎn)钦铁,表示只要滿足一個(gè)條件即可,如果啟動(dòng)不成功表示都要滿足

# 啟動(dòng)
[root@master affinity]# kubectl create -f multiple-matchexpressions.yaml
pod/multiple-matchexpressions created

# 觀察Pod才漆,啟動(dòng)失敗
[root@master affinity]# kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
multiple-matchexpressions   0/1     Pending   0          11s   <none>   <none>   <none>           <none>

# 查看啟動(dòng)事件牛曹,還是熟悉的報(bào)錯(cuò)
[root@master affinity]# kubectl describe pod multiple-matchexpressions | grep -A 100 Events                     
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  48s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.
總結(jié)

如果同時(shí)定義了nodeSelector與nodeAffinity,兩個(gè)條件必須滿足醇滥,才能調(diào)度到指定Pod上

如果有多個(gè) matchExpressions 黎比,那么只要滿足一個(gè)即可

如果一個(gè)matchExpressions 下有多個(gè)匹配項(xiàng)超营,那么需要全部滿足

節(jié)點(diǎn)親和性就介紹到這里,后面介紹Pod親和性調(diào)度與互斥調(diào)度阅虫。


歡迎關(guān)注演闭,學(xué)習(xí)不迷路!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末书妻,一起剝皮案震驚了整個(gè)濱河市船响,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌躲履,老刑警劉巖见间,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異工猜,居然都是意外死亡米诉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門篷帅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來史侣,“玉大人,你說我怎么就攤上這事魏身【鳎” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵箭昵,是天一觀的道長税朴。 經(jīng)常有香客問我,道長家制,這世上最難降的妖魔是什么正林? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮颤殴,結(jié)果婚禮上觅廓,老公的妹妹穿的比我還像新娘。我一直安慰自己涵但,他們只是感情好杈绸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贤笆,像睡著了一般蝇棉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芥永,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天篡殷,我揣著相機(jī)與錄音,去河邊找鬼埋涧。 笑死板辽,一個(gè)胖子當(dāng)著我的面吹牛奇瘦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劲弦,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼耳标,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了邑跪?” 一聲冷哼從身側(cè)響起次坡,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎画畅,沒想到半個(gè)月后砸琅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡轴踱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年症脂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淫僻。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诱篷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雳灵,到底是詐尸還是另有隱情棕所,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布悯辙,位于F島的核電站橙凳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏笑撞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一钓觉、第九天 我趴在偏房一處隱蔽的房頂上張望茴肥。 院中可真熱鬧,春花似錦荡灾、人聲如沸瓤狐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽础锐。三九已至,卻和暖如春荧缘,著一層夾襖步出監(jiān)牢的瞬間皆警,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工截粗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留信姓,地道東北人鸵隧。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像意推,于是被迫代替她去往敵國和親豆瘫。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容