每個人都知道,保持應用程式最新以及優化安全性和性能是一種很好的做法。 Kubernetes和Docker可以更輕松地執行這些更新,因為您可以使用更新建構新容器并相對輕松地部署它。
就像您的應用程式一樣,Kubernetes不斷獲得新功能和安全更新,是以底層節點和Kubernetes基礎架構也需要保持最新。
在本期Kubernetes最佳實踐中,讓我們來看看
Google Kubernetes Engine
如何讓您的Kubernetes叢集輕松更新! 叢集的兩個部分:Master和Node
在更新群集時,需要更新兩個部分:Mater和Node。 需要首先更新Master,Node随後。 讓我們看看如何使用
Kubernetes Engine
更新它們。
零停機更新Master
Kubernetes Engine
會在釋出點釋出時會自動更新Master,但通常不會自動更新到新版本(例如,1.7到1.8)。 準備好更新到新版本後,隻需單擊
Kubernetes Engine
控制台中的更新主按鈕即可。
但是,您可能已經注意到該對話框顯示以下内容:
“更改主版本可能會導緻幾分鐘的控制平面停機。 在此期間,您将無法編輯此群集。”
當主伺服器關閉進行更新時,
deployments
,
services
将繼續按預期工作。 但是,任何需要
Kubernetes API
的東西都會停止工作。 這意味着
kubectl
将停止工作,那些使用
Kubernetes API
擷取有關群集資訊的應用程式将停止工作,您基本上無法在叢集更新時對群集進行任何更改。
那麼如何更新Master而不會導緻停機呢?
具有Kubernetes Engine區域叢集的高可用Masters
雖然标準的
zonal Kubernetes Engine
叢集隻有一個Master支援它們,但您可以建立
regional
叢集,提供多區域,高可用性的Master(注意:
Kubernetes Engine區域叢集最近普遍可用)。
建立群集時,請務必選擇
regional
選項:
就是這樣! Kubernetes引擎自動在三個
zone
中建立Node和Master,Master位于負載平衡的IP位址後面,是以Kubernetes API将在更新期間繼續工作。
零停機更新Node
更新節點時,您可以使用幾種不同的政策。 我想關注兩個:
- 滾動更新
- 使用節點池遷移
更新Kubernetes Node的最簡單方法是使用滾動更新。 這是Kubernetes Engine用于更新Node的預設更新機制。
滾動更新以下列方式工作。 一個接一個,一個釋放,一個鎖存,直到該Node上不再運作Pod。 然後删除該Node,并使用更新的Kubernetes版本建立新Node。 該Node啟動并運作後,将更新下一個Node。 這一直持續到所有Node都更新為止。
您可以通過在節點池(Node Pool)上啟用自動節點更新,讓Kubernetes Engine完全為您管理此過程。
如果您不選擇此選項,
Kubernetes Engine
儀表闆會在更新可用時提醒您:
隻需單擊該連結,然後按照提示開始滾動更新。
警告:確定您的Pod由
ReplicaSet
Deployment
StatefulSet
或類似的東西管理。 獨立Pod不會被重新排程!
雖然在
Kubernetes Engine
上執行滾動更新很簡單,但它有一些缺點。
一個缺點是您在群集中獲得的節點容量少一個。 通過擴充節點池以添加額外容量,然後在更新完成後将其縮小,可以輕松解決此問題。
滾動更新的完全自動化特性使其易于操作,但您對該過程的控制較少。 如果出現問題,還需要時間復原到舊版本,因為您必須停止滾動更新然後撤消它。
使用節點池(Node Pool)遷移
您可以建立新節點池,等待所有節點運作,然後一次在一個節點上遷移工作負載,而不是像滾動更新那樣更新“活躍的”節點池。
我們假設我們的Kubernetes叢集現在有三個VM。 您可以使用以下指令檢視節點:
kubectl get nodes
NAME STATUS AGE
gke-cluster-1-default-pool-7d6b79ce-0s6z Ready 3h
gke-cluster-1-default-pool-7d6b79ce-9kkm Ready 3h
gke-cluster-1-default-pool-7d6b79ce-j6ch Ready 3h
建立新的節點池
要建立名為
pool-two
的新節點池,請運作以下指令:
gcloud container node-pools create pool-two
注意:請記住此自定義指令,以便新節點池與舊池相同。 如果需要,還可以使用
Kubernetes Engine GUI
建立新節點池。
現在,如果您檢查節點,您會注意到有三個節點具有新池名稱:
$ kubectl get nodes
NAME STATUS AGE
gke-cluster-1-pool-two-9ca78aa9–5gmk Ready 1m
gke-cluster-1-pool-two-9ca78aa9–5w6w Ready 1m
gke-cluster-1-pool-two-9ca78aa9-v88c Ready 1m
gke-cluster-1-default-pool-7d6b79ce-0s6z Ready 3h
gke-cluster-1-default-pool-7d6b79ce-9kkm Ready 3h
gke-cluster-1-default-pool-7d6b79ce-j6ch Ready 3h
但是,Pod仍然在舊節點上! 讓我們來遷移Pod到新節點上。
釋放舊節點池
現在我們需要将工作負載遷移到新節點池。 讓我們以滾動的方式一次遷移一個節點。
首先,
cordon
(隔離)每個舊節點。 這将阻止新的Pod安排到它們上面。
kubectl cordon <node_name>
一旦所有舊節點都被隔離,就隻能将Pod排程到新節點上。 這意味着您可以開始從舊節點中删除Pod,Kubernetes會自動在新節點上排程它們。
ReplicaSet
Deployment
StatefulSet
運作以下指令以釋放每個節點。 這将删除該節點上的所有Pod。
kubectl drain <node_name> --force
釋放節點後,確定新的Pod已啟動并運作,然後再轉到下一個節點。
如果您在遷移過程中遇到任何問題,請取消舊池的保護,然後隔離并釋放新池。 Pod會被重新排程回舊池。
删除舊節點池
一旦所有Pod安全地重新排程,就可以删除舊池了。
将
default-pool
替換為要删除的池。
gcloud container node-pools delete default-pool
您剛剛成功更新了所有節點!
結論
通過使用
Kubernetes Engine
,您隻需點選幾下即可使Kubernetes叢集保持最新狀态。
如果您沒有使用像
Kubernetes Engine
這樣的托管服務,您仍然可以将滾動更新或節點池方法用在您自己的叢集更新上。 不同之處在于您需要手動将新節點添加到叢集中,并自行執行主更新,這可能很棘手。
我強烈建議使用
Kubernetes Engine
regional
叢集來實作高可用Master和自動節點更新,以獲得無煩惱的更新體驗。 如果您需要對節點更新進行額外控制,則使用節點池可以為您提供該控制,而不會放棄
Kubernetes Engine
為您提供的托管Kubernetes平台的優勢。
到這裡,我們要結束關于Kubernetes最佳實踐的系列文章的第一季了。 如果您對希望我解決的其他主題有所了解,可以在
Twitter上找到我。
本文轉自DockOne-
Kubernetes最佳實踐S01E07:零停機更新Kubernetes叢集