Node節點禁止調度(平滑維護)方式- cordon,drain,delete


 

cordon、drain和delete三個命令都會使node停止被調度,后期創建的pod不會繼續被調度到該節點上,但操作的暴力程度卻不一樣。
 
一、cordon 停止調度 (不可調度,臨時從K8S集群隔離)
  • 影響最小,只會將node標識為SchedulingDisabled不可調度狀態。
  • 之后K8S再創建的pod資源,不會被調度到該節點。
  • 舊有的pod不會受到影響,仍正常對外提供服務。
  • 禁止調度命令"kubectl cordon node_name"。
  • 恢復調度命令"kubectl uncordon node_name"。(恢復到K8S集群中,變回可調度狀態)
 
二、drain 驅逐節點 (先不可調度,然后排干)
  • 首先,驅逐Node上的pod資源到其他節點重新創建。
  • 接着,將節點調為SchedulingDisabled不可調度狀態。
  • 禁止調度命令"kubectl drain node_name --force --ignore-daemonsets --delete-local-data"
  • 恢復調度命令"kubectl uncordon node_name"。(恢復到K8S集群中,變回可調度狀態)
  • drain方式是安全驅逐pod,會等到pod容器應用程序優雅停止后再刪除該pod。
  • drain驅逐流程:先在Node節點刪除pod,然后再在其他Node節點創建該pod。所以為了確保drain驅逐pod過程中不中斷服務(即做到"無感知"地平滑驅逐),必須保證要驅逐的pod副本數大於1,並且采用了"反親和策略"將這些pod調度到不同的Node節點上了!也就是說,在"多個pod副本+反親和策略"的場景下,drain驅逐過程對容器服務是沒有影響的。
 
需要注意:
  • 對節點執行維護操作之前(例如:內核升級,硬件維護等),您可以使用 kubectl drain 安全驅逐節點上面所有的 pod。
  • drain安全驅逐方式將會允許 pod 里面的容器遵循指定的 PodDisruptionBudgets 執行優雅中止。也就是說,drain安全驅逐可以做到:優雅地終止pod里的容器進程。
  • kubectl drain 返回成功表明所有的 pod (除了排除的那些)已經被安全驅逐(遵循期望優雅的中止期,並且沒有違反任何應用程序級別的中斷預算)。
  • 然后,通過對物理機斷電或者在雲平台上刪除節點所在的虛擬機,都能安全的將節點移除。
 
一般線上K8S的PDB(PodDisruptionBudgets)配置的也是符合Pod驅逐的理想情況的,即maxUnavailable設置為0,maxSurge設置為1:
 replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 1           
      maxUnavailable: 0
    type: RollingUpdate

 

默認情況下,kubectl drain 會忽略那些不能殺死的系統類型的 pod。drain命令中需要添加三個參數:--force、--ignore-daemonsets、--delete-local-data
  • --force 當一些pod不是經 ReplicationController, ReplicaSet, Job, DaemonSet 或者 StatefulSet 管理的時候就需要用--force來強制執行 (例如:kube-proxy)
  • --ignore-daemonsets 無視DaemonSet管理下的Pod。即--ignore-daemonsets往往需要指定的,這是因為deamonset會忽略unschedulable標簽(使用kubectl drain時會自動給節點打上不可調度標簽),因此deamonset控制器控制的pod被刪除后可能馬上又在此節點上啟動起來,這樣就會成為死循環.因此這里忽略daemonset。
  • --delete-local-data 如果有mount local volumn的pod,會強制殺掉該pod。
 
drain禁止調度的操作步驟:
確定要排空的節點的名稱
# kubectl get nodes
 
查看pod
# kubectl get po 

命令node節點開始釋放所有pod,並且不接收新的pod進程
# kubectl drain [node-name] --force --ignore-daemonsets --delete-local-data 

此時可以對該node節點進行平滑維護,后續需要恢復到k8s集群中:
# kubectl uncordon [node-name]

  

三、delete 刪除節點
  • 首先,驅逐Node節點上的pod資源到其他節點重新創建。
  • 驅逐流程:先在Node節點刪除pod,然后再在其他Node節點上創建這些pod。
  • node節點刪除,master失去對其控制,該節點從k8s集群摘除。
  • delete是一種暴力刪除node的方式。在驅逐pod時是強制干掉容器進程,做不到優雅終止Pod。相比較而言,顯然drain更安全。
 
恢復調度(即重新加入到K8S集群中)
  • delete刪除后,后續如果需重新加入K8S集群。則需要重啟node節點的kubelet服務,重啟后,基於node的自注冊功能,該節點才能重新加入到K8S集群,並且恢復使用(即恢復可調度的身份)。
  • 另外:如果kubelet服務重啟后,node節點系統時間跟其他節點不一致,則導致該節點證書會失效!kubelet注冊后,還需要手動approve簽發TLS認證操作了。如下示例:
k8s-vm02節點重啟后,系統時間變了,跟其他node節點系統時間不一致,導致該節點的集群證書失效!
[root@k8s-vm01 ingress]# kubectl exec -ti test-finhub-app-56df548879-ghlb2 -n wiseco -- /bin/bash
Error from server: error dialing backend: x509: certificate is valid for k8s-vm01, not k8s-vm02

[root@k8s-vm01 ingress]# kubectl get csr 
NAME        AGE     REQUESTOR              CONDITION
csr-7zt2w   50m     system:node:k8s-vm02   Pending
csr-8sw6k   36m     system:node:k8s-vm02   Pending
csr-9jv7z   21m     system:node:k8s-vm02   Pending

需要手動approve簽發TLS認證
[root@k8s-vm01 ingress]# kubectl certificate approve csr-7zt2w
[root@k8s-vm01 ingress]# kubectl certificate approve csr-8sw6k
[root@k8s-vm01 ingress]# kubectl certificate approve csr-9jv7z 

  

四、Node節點平滑維護

通常情況下,如果要對K8S集群中的一台Node節點進行平滑維護,如升級或調整配置。正確的操作:
  • cordon臨時從K8S集群隔離出來,標識為SchedulingDisabled不可調度狀態。
  • drain排干該節點上的pod資源到其他node節點上。
  • 對該節點展開平滑維護操作,如升級或調整配置。
  • uncordon恢復,重新回到K8S集群,變回可調度狀態。
 
同時注意:為了確保drain驅逐pod的時候,容器應用服務不中斷,必須滿足:
  • 要驅逐的pod副本數量必須大於1
  • 要配置"反親和策略",確保被驅逐的pod被調度到不同的Node節點上
  • deployment采用滾動更新,設置maxUnavailable為0,maxSurge為1


免責聲明!

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



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