Kubernetes學習之路(二十二)之Pod資源調度

Pod資源調度

API Server在接受客戶端提交Pod對象建立請求後,而後是經過調度器(kube-schedule)從集羣中選擇一個可用的最佳節點來建立並運行Pod。而這一個建立Pod對象,在調度的過程中有3個階段:節點預選、節點優選、節點選定,從而篩選出最佳的節點。如圖:node

  • 節點預選:基於一系列的預選規則對每一個節點進行檢查,將那些不符合條件的節點過濾,從而完成節點的預選
  • 節點優選:對預選出的節點進行優先級排序,以便選出最合適運行Pod對象的節點
  • 節點選定:從優先級排序結果中挑選出優先級最高的節點運行Pod,當這類節點多於1個時,則進行隨機選擇

當咱們有需求要將某些Pod資源運行在特定的節點上時,咱們能夠經過組合節點標籤,以及Pod標籤或標籤選擇器來匹配特定的預選策略並完成調度,如MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints等預選策略,這些策略經常使用於爲用戶提供自定義Pod親和性或反親和性、節點親和性以及基於污點及容忍度的調度機制。數據庫

一、經常使用的預選策略

預選策略實際上就是節點過濾器,例如節點標籤必須可以匹配到Pod資源的標籤選擇器(MatchNodeSelector實現的規則),以及Pod容器的資源請求量不能大於節點上剩餘的可分配資源(PodFitsResource規則)等等。執行預選操做,調度器會逐一根據規則進行篩選,若是預選沒能選定一個合適的節點,此時Pod會一直處於Pending狀態,直到有一個可用節點完成調度。其經常使用的預選策略以下:vim

  • CheckNodeCondition:檢查是否能夠在節點報告磁盤、網絡不可用或未準備好的狀況下將Pod對象調度其上。
  • HostName:若是Pod對象擁有spec.hostname屬性,則檢查節點名稱字符串是否和該屬性值匹配。
  • PodFitsHostPorts:若是Pod對象定義了ports.hostPort屬性,則檢查Pod指定的端口是否已經被節點上的其餘容器或服務佔用。
  • MatchNodeSelector:若是Pod對象定義了spec.nodeSelector屬性,則檢查節點標籤是否和該屬性匹配。
  • NoDiskConflict:檢查Pod對象請求的存儲卷在該節點上可用。
  • PodFitsResources:檢查節點上的資源(CPU、內存)可用性是否知足Pod對象的運行需求。
  • PodToleratesNodeTaints:若是Pod對象中定義了spec.tolerations屬性,則須要檢查該屬性值是否能夠接納節點定義的污點(taints)。
  • PodToleratesNodeNoExecuteTaints:若是Pod對象定義了spec.tolerations屬性,檢查該屬性是否接納節點的NoExecute類型的污點。
  • CheckNodeLabelPresence:僅檢查節點上指定的全部標籤的存在性,要檢查的標籤以及其能否存在取決於用戶的定義。
  • CheckServiceAffinity:根據當前Pod對象所屬的Service已有其餘Pod對象所運行的節點調度,目前是將相同的Service的Pod對象放在同一個或同一類節點上。
  • MaxEBSVolumeCount:檢查節點上是否已掛載EBS存儲卷數量是否超過了設置的最大值,默認值:39
  • MaxGCEPDVolumeCount:檢查節點上已掛載的GCE PD存儲卷是否超過了設置的最大值,默認值:16
  • MaxAzureDiskVolumeCount:檢查節點上已掛載的Azure Disk存儲卷數量是否超過了設置的最大值,默認值:16
  • CheckVolumeBinding:檢查節點上已綁定和未綁定的PVC是否知足Pod對象的存儲卷需求。
  • NoVolumeZoneConflct:在給定了區域限制的前提下,檢查在該節點上部署Pod對象是否存在存儲卷衝突。
  • CheckNodeMemoryPressure:在給定了節點已經上報了存在內存資源壓力過大的狀態,則須要檢查該Pod是否能夠調度到該節點上。
  • CheckNodePIDPressure:若是給定的節點已經報告了存在PID資源壓力過大的狀態,則須要檢查該Pod是否能夠調度到該節點上。
  • CheckNodeDiskPressure:若是給定的節點存在磁盤資源壓力過大,則檢查該Pod對象是否能夠調度到該節點上。
  • MatchInterPodAffinity:檢查給定的節點可否能夠知足Pod對象的親和性和反親和性條件,用來實現Pod親和性調度或反親和性調度。

在上面的這些預選策略裏面,CheckNodeLabelPressure和CheckServiceAffinity能夠在預選過程當中結合用戶自定義調度邏輯,這些策略叫作可配置策略。其餘不接受參數進行自定義配置的稱爲靜態策略。後端

二、優選函數

預選策略篩選出一個節點列表就會進入優選階段,在這個過程調度器會向每一個經過預選的節點傳遞一系列的優選函數來計算其優先級分值,優先級分值介於0-10之間,其中0表示不適用,10表示最適合託管該Pod對象。api

另外,調度器還支持給每一個優選函數指定一個簡單的值,表示權重,進行節點優先級分值計算時,它首先將每一個優選函數的計算得分乘以權重,而後再將全部優選函數的得分相加,從而得出節點的最終優先級分值。權重可讓管理員定義優選函數傾向性的能力,其計算優先級的得分公式以下:tomcat

finalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) + ......

下圖是關於優選函數的列表圖:安全

三、節點親和調度

節點親和性是用來肯定Pod對象調度到哪個節點的規則,這些規則基於節點上的自定義標籤和Pod對象上指定的標籤選擇器進行定義。網絡

定義節點親和性規則有2種:硬親和性(require)和軟親和性(preferred)app

  • 硬親和性:實現的是強制性規則,是Pod調度時必須知足的規則,不然Pod對象的狀態會一直是Pending
  • 軟親和性:實現的是一種柔性調度限制,在Pod調度時能夠儘可能知足其規則,在沒法知足規則時,能夠調度到一個不匹配規則的節點之上。

定義節點親和規則的兩個要點:一是節點配置是否合乎需求的標籤,而是Pod對象定義合理的標籤選擇器,這樣纔可以基於標籤選擇出指望的目標節點。

須要注意的是preferredDuringSchedulingIgnoredDuringExecutionrequiredDuringSchedulingIgnoredDuringExecution名字中後半段字符串IgnoredDuringExecution表示的是,在Pod資源基於節點親和性規則調度到某個節點以後,若是節點的標籤發生了改變,調度器不會講Pod對象從該節點上移除,由於該規則僅對新建的Pod對象有效。

3.一、節點硬親和性

下面的配置清單中定義的Pod對象,使用節點硬親和性和規則定義將當前Pod調度到標籤爲zone=foo的節點上:

apiVersion: v1
kind: Pod
metadata:
  name: with-require-nodeaffinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: zone,operator: In,values: ["foo"]}
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1

#建立Pod對象
[root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml 
pod/with-require-nodeaffinity created

#因爲集羣中並無節點含有節點標籤爲zone=foo,因此建立的Pod一直處於Pending狀態
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity
NAME                        READY     STATUS    RESTARTS   AGE
with-require-nodeaffinity   0/1       Pending   0          35s

#查看Pending具體的緣由
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
......
Events:
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  3s (x21 over 1m)  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.

#給node01節點打上zone=foo的標籤,能夠看到成功調度到node01節點上
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
Events:
  Type     Reason            Age                From                 Message
  ----     ------            ----               ----                 -------
  Warning  FailedScheduling  58s (x25 over 2m)  default-scheduler    0/3 nodes are available: 3 node(s) didn't match node selector.
  Normal   Pulled            4s                 kubelet, k8s-node01  Container image "ikubernetes/myapp:v1" already present on machine
  Normal   Created           4s                 kubelet, k8s-node01  Created container
  Normal   Started           4s                 kubelet, k8s-node01  Started container

[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity -o wide
NAME                        READY     STATUS    RESTARTS   AGE       IP            NODE
with-require-nodeaffinity   1/1       Running   0          6m        10.244.1.12   k8s-node01

在定義節點親和性時,requiredDuringSchedulingIgnoredDuringExecution字段的值是一個對象列表,用於定義節點硬親和性,它能夠由一個或多個nodeSelectorTerms定義的對象組成,此時值須要知足其中一個nodeSelectorTerms便可。

nodeSelectorTerms用來定義節點選擇器的條目,它的值也是一個對象列表,由1個或多個matchExpressions對象定義的匹配規則組成,多個規則是邏輯與的關係,這就表示某個節點的標籤必需要知足同一個nodeSelectorTerms下全部的matchExpression對象定義的規則纔可以成功調度。以下:

#以下配置清單,必須存在知足標籤zone=foo和ssd=true的節點纔可以調度成功
apiVersion: v1
kind: Pod
metadata:
  name: with-require-nodeaffinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: zone, operator: In, values: ["foo"]}
          - {key: ssd, operator: Exists, values: []}    #增長一個規則
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1

[root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml 
pod/with-require-nodeaffinity created
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity  
NAME                        READY     STATUS    RESTARTS   AGE
with-require-nodeaffinity   0/1       Pending   0          16s
[root@k8s-master ~]# kubectl label node k8s-node01 ssd=true
node/k8s-node01 labeled

[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity  
NAME                        READY     STATUS    RESTARTS   AGE
with-require-nodeaffinity   1/1       Running   0          2m

在預選策略中,還能夠經過節點資源的可用性去限制可以成功調度,以下配置清單:要求的資源爲6核心CPU和20G內存,節點是沒法知足該容器的資源需求,所以也會調度失敗,Pod資源會處於Pending狀態。

apiVersion: v1
kind: Pod
metadata:
  name: with-require-nodeaffinity
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    resources:
      requests:
        cpu: 6
        memory: 20Gi

3.二、節點軟親和性

看下面一個配置清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy-with-node-affinity
spec:
  replicas: 5
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
      spec:
        affinity:
          nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 60
              preference:
                matchExpressions:
                - {key: zone, operator: In, values: ["foo"]}
            - weight: 30
              preference:
                matchExpressions:
                - {key: ssd, operator: Exists, values: []}
        containers:
        - name: myapp
          image: ikubernetes/myapp:v1
          
#首先先給node02和master都打上標籤,master標籤爲zone=foo,node02標籤爲ssd=true,這裏node01是沒有對應標籤的
[root@k8s-master ~]# kubectl label node k8s-node02 ssd=true
node/k8s-node02 labeled
[root@k8s-master ~]# kubectl label node k8s-master zone=foo
node/k8s-master labeled

#進行建立
[root@k8s-master ~]# kubectl apply -f deploy-with-preferred-nodeAffinity.yaml 
deployment.apps/myapp-deploy-with-node-affinity2 created

#能夠看到5個Pod分別分佈在不一樣的節點上,node01上沒有對應的標籤也會調度上進行建立Pod,體現軟親和性
[root@k8s-master ~]# kubectl get pods -o wide |grep deploy-with
myapp-deploy-with-node-affinity2-75b8f65f87-2gqjv   1/1       Running    0          11s       10.244.2.4     k8s-node02
myapp-deploy-with-node-affinity2-75b8f65f87-7l2sg   1/1       Running    0          11s       10.244.0.4     k8s-master
myapp-deploy-with-node-affinity2-75b8f65f87-cdrxx   1/1       Running    0          11s       10.244.2.3     k8s-node02
myapp-deploy-with-node-affinity2-75b8f65f87-j77f6   1/1       Running    0          11s       10.244.1.36    k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-wt6tq   1/1       Running    0          11s       10.244.0.3     k8s-master

#若是咱們給node01打上zone=foo,ssd=true的標籤,再去建立時,你會發現全部的Pod都調度在這個節點上。由於節點的軟親和性,會盡力知足Pod中定義的規則,以下:
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
[root@k8s-master ~]# kubectl label node k8s-node01 ssd=true
[root@k8s-master ~]# kubectl get pods -o wide |grep deploy-with
myapp-deploy-with-node-affinity2-75b8f65f87-4lwsw   0/1       ContainerCreating   0          3s        <none>         k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-dxbxf   1/1       Running             0          3s        10.244.1.31    k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-lnhgm   0/1       ContainerCreating   0          3s        <none>         k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-snxbc   0/1       ContainerCreating   0          3s        <none>         k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-zx8ck   1/1       Running             0          3s        10.244.1.33    k8s-node01

上面的實驗結果顯示,當2個標籤沒有都存在一個node節點上時,Pod對象會被分散在集羣中的三個節點上進行建立並運行,之因此如此,是由於使用了 節點軟親和性的預選方式,全部的節點都可以經過MatchNodeSelector預選策略的篩選。當咱們將2個標籤都集合在node01上時,全部Pod對象都會運行在node01之上。

四、Pod資源親和調度

在出於高效通訊的需求,有時須要將一些Pod調度到相近甚至是同一區域位置(好比同一節點、機房、區域)等等,好比業務的前端Pod和後端Pod,此時這些Pod對象之間的關係能夠叫作親和性。

同時出於安全性的考慮,也會把一些Pod之間進行隔離,此時這些Pod對象之間的關係叫作反親和性(anti-affinity)。

調度器把第一個Pod放到任意位置,而後和該Pod有親和或反親和關係的Pod根據該動態完成位置編排,這就是Pod親和性和反親和性調度的做用。Pod的親和性定義也存在硬親和性和軟親和性的區別,其約束的意義和節點親和性相似。

Pod的親和性調度要求各相關的Pod對象運行在同一位置,而反親和性則要求它們不能運行在同一位置。這裏的位置實際上取決於節點的位置拓撲,拓撲的方式不一樣,Pod是否在同一位置的斷定結果也會有所不一樣。

若是基於各個節點的kubernetes.io/hostname標籤做爲評判標準,那麼會根據節點的hostname去斷定是否在同一位置區域。

4.一、Pod硬親和度

Pod強制約束的親和性調度也是使用requiredDuringSchedulingIgnoredDuringExecution進行定義的。Pod親和性是用來描述一個Pod對象和現有的Pod對象運行的位置存在某種依賴關係,因此若是要測試Pod親和性約束,須要存在一個被依賴的Pod對象,下面建立一個帶有app=tomcat的Deployment資源部署一個Pod對象:

[root@k8s-master ~]# kubectl run tomcat -l app=tomcat --image=tomcat:alpine
deployment.apps/tomcat created
[root@k8s-master ~]# kubectl get pods -l app=tomcat -o wide
NAME                      READY     STATUS    RESTARTS   AGE       IP            NODE
tomcat-75fd5cc757-w9qdb   1/1       Running   0          5m        10.244.1.37   k8s-node01

從上面咱們能夠看到新建立的tomcatpod對象被調度在k8s-node01上,再寫一個配置清單定義一個Pod對象,經過labelSelector定義的標籤選擇器挑選對應的Pod對象。

[root@k8s-master ~]# vim required-podAffinity-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity-1
spec:
  affinity:
    podAffninity:
      requiredDuringSchedulingIngnoreDuringExecution:
      - labelSelector:
          matchExpression:
          - {key: app , operator: In , values: ["tomcat"]}
        topologyKey: kubernetes.io/hostname
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1

kubernetes.io/hostname標籤是Kubernetes集羣節點的內建標籤,它的值爲當前節點的主機名,對於各個節點來講都是不一樣的。因此新建的Pod對象要被部署到和tomcat所在的同一個節點上。

[root@k8s-master ~]# kubectl apply -f required-podAffinity-pod1.yaml 
pod/with-pod-affinity-1 created

[root@k8s-master ~]# kubectl get pods -o wide
NAME                      READY     STATUS    RESTARTS   AGE         IP              NODE
with-pod-affinity-1       1/1       Running    0          31s       10.244.1.38    k8s-node01
tomcat-75fd5cc757-w9qdb   1/1       Running    0          5m        10.244.1.37    k8s-node01

基於單一節點的Pod親和性相對來講使用的狀況會比較少,一般使用的是基於同一地區、區域、機架等拓撲位置約束。好比部署應用程序(myapp)和數據庫(db)服務相關的Pod時,這兩種Pod應該部署在同一區域上,能夠加速通訊的速度。

4.二、Pod軟親和度

同理,有硬親和度即有軟親和度,Pod也支持使用preferredDuringSchedulingIgnoredDuringExecuttion屬性進行定義Pod的軟親和性,調度器會盡力知足親和約束的調度,在知足不了約束條件時,也容許將該Pod調度到其餘節點上運行。好比下面這一配置清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-preferred-pod-affinity
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
         - weight: 80
           podAffinityTerm:
             labelSelector:
               matchExpressions:
               - {key: app, operator: In , values: ["cache"]}
             topologyKey: zone
         - weight: 20
           podAffinityTerm:
             labelSelector:
               matchExpressions:
               - {key: app, operator: In, values: ["db"]}
             topologyKey: zone
       containers:
       - name: myapp
         image: ikubernetes/mapp:v1

上述的清單配置當中,pod的軟親和調度須要將Pod調度到標籤爲app=cache並在區域zone當中,或者調度到app=db標籤節點上的,可是咱們的節點上並無相似的標籤,因此調度器會根據軟親和調度進行隨機調度到k8s-node01節點之上。以下:

[root@k8s-master ~]# kubectl apply -f deploy-with-preferred-podAffinity.yaml 
deployment.apps/myapp-with-preferred-pod-affinity created
[root@k8s-master ~]# kubectl get pods -o wide |grep myapp-with-preferred-pod-affinity  
myapp-with-preferred-pod-affinity-5c44649f58-cwgcd   1/1       Running    0          1m        10.244.1.40    k8s-node01
myapp-with-preferred-pod-affinity-5c44649f58-hdk8q   1/1       Running    0          1m        10.244.1.42    k8s-node01
myapp-with-preferred-pod-affinity-5c44649f58-kg7cx   1/1       Running    0          1m        10.244.1.41    k8s-node01

4.三、Pod反親和度

podAffinity定義了Pod對象的親和約束,而Pod對象的反親和調度則是用podAntiAffinty屬性進行定義,下面的配置清單中定義了由同一Deployment建立可是彼此基於節點位置互斥的Pod對象:

[root@k8s-master ~]# cat deploy-with-required-podAntiAffinity.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-with-pod-anti-affinity
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - {key: app,operator: In,values: ["myapp"]}
            topologyKey: kubernetes.io/hostname
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1

[root@k8s-master ~]# kubectl apply -f deploy-with-required-podAntiAffinity.yaml 
deployment.apps/myapp-with-pod-anti-affinity created
[root@k8s-master ~]# kubectl get pods -l app=myapp
NAME                                            READY     STATUS    RESTARTS   AGE
myapp-with-pod-anti-affinity-79c7b6c596-77hrz   1/1       Running   0          8s
myapp-with-pod-anti-affinity-79c7b6c596-fhxmv   0/1       Pending   0          8s
myapp-with-pod-anti-affinity-79c7b6c596-l9ckr   1/1       Running   0          8s
myapp-with-pod-anti-affinity-79c7b6c596-vfv2s   1/1       Running   0          8s

因爲在配置清單中定義了強制性反親和性,因此建立的4個Pod副本必須 運行在不一樣的節點當中呢,可是集羣中只存在3個節點,所以,確定會有一個Pod對象處於Pending的狀態。

五、污點和容忍度

污點(taints)是定義在節點上的一組鍵值型屬性數據,用來讓節點拒絕將Pod調度到該節點上,除非該Pod對象具備容納節點污點的容忍度。而容忍度(tolerations)是定義在Pod對象上的鍵值型數據,用來配置讓Pod對象能夠容忍節點的污點。

前面的節點選擇器和節點親和性的調度方式都是經過在Pod對象上添加標籤選擇器來完成對特定類型節點標籤的匹配,實現的是Pod選擇節點的方式。而污點和容忍度則是經過對節點添加污點信息來控制Pod對象的調度結果,讓節點擁有了控制哪一種Pod對象能夠調度到該節點上的 一種方式。

Kubernetes使用PodToleratesNodeTaints預選策略和TaintTolerationPriority優選函數來完成這種調度方式。

5.一、定義污點和容忍度

污點的定義是在節點的nodeSpec,而容忍度的定義是在Pod中的podSpec,都屬於鍵值型數據,兩種方式都支持一個effect標記,語法格式爲key=value: effect,其中key和value的用戶和格式和資源註解相似,而effect是用來定義對Pod對象的排斥等級,主要包含如下3種類型:

  • NoSchedule:不能容忍此污點的新Pod對象不能調度到該節點上,屬於強制約束,節點現存的Pod對象不受影響。
  • PreferNoSchedule:NoSchedule屬於柔性約束,即不能容忍此污點的Pod對象儘可能不要調度到該節點,不過無其餘節點能夠調度時也能夠容許接受調度。
  • NoExecute:不能容忍該污點的新Pod對象不能調度該節點上,強制約束,節點現存的Pod對象由於節點污點變更或Pod容忍度的變更致使沒法匹配規則,Pod對象就會被從該節點上去除。

在Pod對象上定義容忍度時,其支持2中操做符:EqualExists

  • Equal:等值比較,表示容忍度和污點必須在key、value、effect三者之上徹底匹配。
  • Exists:存在性判斷,表示兩者的key和effect必須徹底匹配,而容忍度中的value字段使用空值。

在使用kubeadm部署的集羣中,master節點上將會自動添加污點信息,阻止不能容忍該污點的Pod對象調度到該節點上,以下:

[root@k8s-master ~]# kubectl describe node k8s-master
Name:               k8s-master
Roles:              master
......
Taints:             node- role. kubernetes. io/ master: NoSchedule
......

而一些系統級別的應用在建立時,就會添加相應的容忍度來確保被建立時能夠調度到master節點上,如flannel插件:

[root@k8s-master ~]# kubectl describe pods kube-flannel-ds-amd64-2p8wm -n kube-system
......
Tolerations:     node-role.kubernetes.io/master:NoSchedule
                 node.kubernetes.io/disk-pressure:NoSchedule
                 node.kubernetes.io/memory-pressure:NoSchedule
                 node.kubernetes.io/not-ready:NoExecute
                 node.kubernetes.io/unreachable:NoExecute
......

5.二、管理節點的污點

使用命令行向節點添加污點

語法:kubectl taint nodes <nodename> <key>=<value>:<effect>......

#定義k8s-node01上的污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type=production:NoSchedule
node/k8s-node01 tainted

#查看節點污點信息
[root@k8s-master ~]# kubectl get nodes k8s-node01 -o go-template={{.spec.taints}}
[map[effect:NoSchedule key:node-type value:production]]

此時,node01節點上已經存在的Pod對象不受影響,僅對新建Pod對象有影響,須要注意的是,若是是同一個鍵值數據,可是最後的標識不一樣,也是屬於不一樣的污點信息,好比再給node01上添加一個污點的標識爲:PreferNoSchedule

[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type=production:PreferNoSchedule
node/k8s-node01 tainted

[root@k8s-master ~]# kubectl get nodes k8s-node01 -o go-template={{.spec.taints}}
[map[value:production effect:PreferNoSchedule key:node-type] map[key:node-type value:production effect:NoSchedule]]

刪除污點

語法:kubectl taint nodes <node-name> <key>[: <effect>]-

#刪除node01上的node-type標識爲NoSchedule的污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type:NoSchedule-
node/k8s-node01 untainted

#刪除指定鍵名的全部污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type-
node/k8s-node01 untainted

#補丁方式刪除節點上的所有污點信息
[root@k8s-master ~]# kubectl patch nodes k8s-node01 -p '{"spec":{"taints":[]}}'

5.三、Pod對象的容忍度

Pod對象的容忍度能夠經過spec.tolerations字段進行添加,同一的也有兩種操做符:EqualExists方式。Equal等值方式以下:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "Noexecute"
  tolerationSeconds: 3600

Exists方式以下:

tolerations: 
- key: "key1" 
  operator: "Exists" 
  effect: "NoExecute" 
  tolerationSeconds: 3600
相關文章
相關標籤/搜索