k8s資源控制(污點和容忍)


一: 污點

1.1 污點的作用

節點親和性,是Pod的一種屬性(偏好或硬性要求) ,它使Pod被吸引到一類特定的節點。Taint則相反,它使節點能夠排斥一類特定的PodTaint和Toleration相互配合,可以用來避免Pod被分配到不合適的節點上。每個節點上都可以應用一個或多個taint

,這表示對於那些不能容忍這些taint的Pod,是不會被該節點接受的。如果將toleration應用於Pod上,則表示這些Pod

可以(但不一定)被調度到具有匹配taint的節點上。

使用kubectl taint命令可以給某個Node節點設置污點, Node被設置上污點之后就和Pod之間存在了一種相斥的關系,可以讓Node拒絕Pod的調度執行,甚至將Node已經存在的Pod驅逐出去。

/



1.2 污點的組成

污點的組成格式如下:key-value:effect

每個污點有一個key和value作為污點的標簽,其中value可以為空, effect描述污點的作用。

當前taint effect支持如下三個選項:

  • NoSchedule:表示k8s將不會將Pod調度到具有該污點的Node上
  • PreferNoschedule:表示k8s將盡量避免將Pod調度到具有該污點的Node上
  • NoExecute:表示k8s將不會將Pod調度到具有該污點的Node上,同時會將Node上已經存在的Pod驅逐出去
[root@master ~]# kubectl  describe  nodes  master  | grep -i 'taints'
Taints:             node-role.kubernetes.io/master:NoSchedule

image-20211109162935856



1.3 設置,查看,去除污點

#為node01節點設置污點 key1=value1:NoSchedule.  NoSchedule便是pod不調度到這個節點
[root@master ~]# kubectl  taint  nodes node01 key1=value1:NoSchedule
node/node01 tainted

#通過describe 查看節點詳細信息查看污點,並不區分大小寫過濾 ‘key'
[root@master ~]# kubectl  describe node node01 | grep -i 'key1'
Taints:             key1=value1:NoSchedule
[root@master ~]# 
#刪除node01的污點key1:NoSchedule
[root@master ~]# kubectl  taint  node node01 key1:NoSchedule-
node/node01 untainted
[root@master ~]# kubectl  describe node node01 | grep -i 'key1'

image-20211109163243209



1.4 示例

[root@master demo]# kubectl  get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
myapp01   1/1     Running   0          29s   10.244.1.143   node01   <none>           <none>
myapp02   1/1     Running   0          17s   10.244.2.110   node02   <none>           <none>
myapp03   1/1     Running   0          9s    10.244.1.144   node01   <none>           <none>
[root@master demo]# 

#設置node01節點,不允許將pod調度到上面,同時還會驅逐該節點上的pod
[root@master demo]# kubectl  taint  node node01 check=mycheck:NoExecute
node/node01 tainted

#node01節點上的pod被驅逐
[root@master demo]# kubectl  get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
myapp02   1/1     Running   0          84s   10.244.2.110   node02   <none>           <none>

注意:如果是Deployment或者StateFulSet資源類型,為了未出副本數量,則會在其他的node上創建新的pod

image-20211109164139786



二:容忍 

2.1 容忍的作用

容忍(Tolerations)

設置了污點的Node將根據taint的effect : Noschedule, PreferNoschedule, NoExecute和Pod之間產生互斥的關系, Pod將在一定程度上不會被調度到Node上。但我們可以在Pod上設置容忍(Tolerations) ,意思是設置了容忍的Pod

將可以容忍污點的存在,可以被調度到存在污點的Node上。



2.2 示例

2.2.1 將兩個節點都設置污點

#將node02也打上污點NoExecute。node01和node02都有此污點
[root@master demo]# kubectl  taint  node node02 check=mycheck:NoExecute
node/node02 tainted

[root@master demo]# vim pod3.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1

[root@master demo]# kubectl  apply  -f pod3.yaml 
pod/myapp01 created

#此時,兩個節點都設置了NoExecute,所以,pod無法調度
root@master demo]# kubectl  get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
myapp01   0/1     Pending   0          23s   <none>   <none>   <none>           <none>

image-20211109164845854


2.2.2 在pod上配置容忍

[root@master demo]# vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  tolerations:
  - key: "check"
    operator: "Equal"
    value: "mycheck"
    effect: "NoExecute"
    tolerationSeconds: 3600


#其中的 key、vaule、effect 都要與 Node 上設置的 taint 保持一致
#operator 的值為 Exists 將會忽略 value 值,即存在即可
#tolerationSeconds 用於描述當 Pod 需要被驅逐時可以在 Pod 上繼續保留運行的時間
#如果不設置tolerationSeconds,則pod將不限時
#在配置了pod的容忍后,pod的狀態變為了running
[root@master demo]# kubectl  get pods  -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
myapp01   1/1     Running   0          6m18s   10.244.2.111   node02   <none>           <none>

image-20211109165937638



2.3 注意事項

#當不指定 key 值時,表示容忍所有的污點 key
  tolerations:
  - operator: "Exists"
  
#當不指定 effect 值時,表示容忍所有的污點作用
  tolerations:
  - key: "key"
    operator: "Exists"

#有多個 Master 存在時,防止資源浪費,可以如下設置
kubectl taint nodes Master-Name node-role.kubernetes.io/master=:PreferNoSchedule

2.4 node更新時對pod的操作

#如果某個 Node 更新升級系統組件,為了防止業務長時間中斷,可以先在該 Node 設置 NoExecute 污點,把該 Node 上的 Pod 都驅逐出去
kubectl taint nodes node01 check=mycheck:NoExecute

#此時如果別的 Node 資源不夠用,可臨時給 Master 設置 PreferNoSchedule 污點,讓 Pod 可在 Master 上臨時創建
kubectl taint nodes master node-role.kubernetes.io/master=:PreferNoSchedule

#待所有 Node 的更新操作都完成后,再去除污點
kubectl taint nodes node01 check=mycheck:NoExecute-



三: Pod啟動階段

3.1 Pod過程的步驟

Pod 創建完之后,一直到持久運行起來,中間有很多步驟,也就有很多出錯的可能,因此會有很多不同的狀態。
一般來說,pod 這個過程包含以下幾個步驟:

  1. 調度到某台 node 上。kubernetes 根據一定的優先級算法選擇一台 node 節點將其作為 Pod 運行的 node
  2. 拉取鏡像
  3. 掛載存儲配置等
  4. 運行起來。如果有健康檢查,會根據檢查的結果來設置其狀態。



3.2 Pod啟動的5種狀態

phase 的可能狀態有:
●Pending:表示APIServer創建了Pod資源對象並已經存入了etcd中,但是它並未被調度完成(比如還沒有調度到某台node上),或者仍然處於從倉庫下載鏡像的過程中。

●Running:Pod已經被調度到某節點之上,並且Pod中所有容器都已經被kubelet創建。至少有一個容器正在運行,或者正處於啟動或者重啟狀態(也就是說Running狀態下的Pod不一定能被正常訪問)。

●Succeeded:有些pod不是長久運行的,比如job、cronjob,一段時間后Pod中的所有容器都被成功終止,並且不會再重啟。需要反饋任務執行的結果。

●Failed:Pod中的所有容器都已終止了,並且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止,比如 command 寫的有問題。

●Unknown:因為某些原因無法取得 Pod 的狀態,通常是因為與 Pod 所在主機通信失敗。



四: 故障排除步驟

  1. 查看Pod事件

    • kubectl describe TYPE NAME_PREFIX
  2. 查看Pod日志(Failed狀態下)

    • kubectl logs <POD_NAME> [-c Container_NAME]
  3. 進入Pod(狀態為running,但是服務沒有提供)

    • kubectl exec –it <POD_NAME> bash
  4. 查看集群信息

    • kubectl get nodes
  5. 發現集群狀態正常

    • kubectl cluster-info
  6. 查看kubelet日志發現

    • journalctl -xefu kubelet



五:對節點執行維護操作

kubectl get nodes

//將 Node 標記為不可調度的狀態,這樣就不會讓新創建的 Pod 在此 Node 上運行
kubectl cordon <NODE_NAME> 		 #該node將會變為SchedulingDisabled狀態

//kubectl drain 可以讓 Node 節點開始釋放所有 pod,並且不接收新的 pod 進程。drain 本意排水,意思是將出問題的 Node 下的 Pod 轉移到其它 Node 下運行
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-local-data --force

--ignore-daemonsets:無視 DaemonSet 管理下的 Pod。
--delete-local-data:如果有 mount local volume 的 pod,會強制殺掉該 pod。
--force:強制釋放不是控制器管理的 Pod,例如 kube-proxy。

注:執行 drain 命令,會自動做了兩件事情:
(1)設定此 node 為不可調度狀態(cordon)
(2)evict(驅逐)了 Pod

//kubectl uncordon 將 Node 標記為可調度的狀態
kubectl uncordon <NODE_NAME>

如果node的標記為 cordon ,則經過scheduler調度的pod,無法調度到那個節點。
而使用nodeName 進行指定,則跳過了scheduler 調度過程,因此不會受到cordon的影響 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM