天天看點

Kubernetes最佳實踐S01E07:零停機更新Kubernetes叢集

每個人都知道,保持應用程式最新以及優化安全性和性能是一種很好的做法。 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

更新節點時,您可以使用幾種不同的政策。 我想關注兩個:

  1. 滾動更新
  2. 使用節點池遷移

更新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叢集

繼續閱讀