如何更安全的升級Kubernetes節(jié)點
您是否害怕將集群升級到更新的 Kubernetes 版本?有幾個原因可能會促使您升級。也許您想要執(zhí)行以下操作之一:
- 使用新的測試版 API
- 需要更新 Kubernetes 版本的最新特性
- 遵循使您的軟件保持最新的最佳實踐
無論是什么原因,都值得回顧一下您的升級過程,以確保您在升級期間最大限度地減少停機時間(和焦慮)。
需要升級的組件有哪些?
一個 Kubernetes 集群由一組節(jié)點和一個控制平面組成。工作節(jié)點托管運行容器化應(yīng)用程序的 pod??刂破矫婀芾砑褐械墓ぷ鞴?jié)點和 Pod。
Kubernetes 集群的組件(來自kubernetes.io)
要升級 Kubernetes 集群,您將按以下順序升級這兩個組件:
- 升級控制平面
- 升級工作節(jié)點
對于自托管和托管集群,升級控制平面非常簡單。這篇文章將重點關(guān)注最小化工作節(jié)點升級的停機時間。
升級工作節(jié)點
在工作節(jié)點上升級 Kubernetes 版本有兩種策略:
- 就地升級(也稱為滾動更新)
- 異地升級
對于就地升級,節(jié)點會被逐一排空并封鎖,這樣就不會在該節(jié)點上安排新的 Pod。然后刪除該節(jié)點并使用更新的 Kubernetes 版本重新創(chuàng)建該節(jié)點。新節(jié)點啟動并運行后,將更新下一個節(jié)點。該策略類似下面的可視化動畫:
動畫顯示了 Kubernetes 集群中節(jié)點的就地升級
就地升級的優(yōu)勢在于它需要最少的額外計算資源(單個額外節(jié)點)。這種策略的缺點是它可能需要相當(dāng)長的時間,因為節(jié)點會被排空并逐個升級一個個節(jié)點。此外,Pod 可能需要進行 1 次以上的移動,因為它們在節(jié)點排空期間被打亂。
對于異地升級,使用新的 Kubernetes 版本創(chuàng)建一個新的節(jié)點池。一旦新節(jié)點全部運行,就可以對舊節(jié)點池進行封鎖,將舊節(jié)點一一排空,然后再刪除舊節(jié)點池。該策略在下面的動畫中可視化:
動畫顯示了 Kubernetes 集群中節(jié)點的異地升級
異地升級需要臨時加倍計算資源以換取更短的升級窗口。升級持續(xù)時間的減少是由于新升級節(jié)點的啟動時間并行化,以及 pod 移動的最小化。在此策略中,Pod 從舊節(jié)點移動到新升級的節(jié)點。
假設(shè)您對計算資源利用率的暫時增加可以接受,我們建議您使用異地升級策略來加快速度。
配置 K8s 資源
無論您選擇哪種工作節(jié)點升級策略,都將涉及將您的 pod 從原始節(jié)點改組到升級節(jié)點。如果您的資源配置不正確,可能會導(dǎo)致停機。讓我們來看看一些潛在的陷阱。
獨立 Pod
Pod 是 Kubernetes 中最小的可部署對象。它代表在您的集群中運行的應(yīng)用程序的單個實例。Pod 是短暫的;如果一個 pod 從一個節(jié)點被驅(qū)逐,這個 pod 不會替換自己。由于 Pod 不是自愈的,因此不建議您直接創(chuàng)建單個 Pod。相反,請使用 Deployment 等控制器為您創(chuàng)建和管理 Pod。
為了最大限度地減少停機時間,請確保您的所有 pod 都由 ReplicaSet、Deployment、StatefulSet 或類似的東西管理,升級后可能需要手動重新安排獨立 pod。
Deployment
集群中的大多數(shù) pod 都可能由Deployment控制。Deployment 代表一組沒有唯一身份的相同 pod。部署通過管理應(yīng)用程序的多個副本并在任何實例失敗時部署替換來提高可用性。
要消除停機時間,請確保您的應(yīng)用程序具有PodDisruptionBudget (PDB)。PDB 通過限制同時關(guān)閉的復(fù)制應(yīng)用程序的 pod 數(shù)量來幫助提供更高的可用性。
例如,以下 PDB 聲明 80% 的帶有front-end標(biāo)簽的 pod 在中斷期間(例如我們的升級)必須可用。這確保了服務(wù)負載的副本數(shù)量永遠不會低于總副本的某個百分比。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: demo
spec:
minAvailable: 80%
selector:
matchLabels:
name: front-end
請注意,您需要確保有多個副本(至少在升級期間是暫時的),以便能夠升級節(jié)點。
DaemonSet
DaemonSet確保所有(或部分)節(jié)點運行一個 pod 的副本。守護程序集通常用于節(jié)點監(jiān)控或日志收集,通常不提供流量。對于這些用例,在工作程序節(jié)點升級期間數(shù)據(jù)存在小的差距通常是可以接受的。
StatefulSets
StatefulSet 是 Kubernetes 控制器類型,用于管理有狀態(tài)的應(yīng)用程序,例如數(shù)據(jù)庫或消息隊列。升級 StatefulSets 比升級 Deployments 需要更多考慮。
要消除停機時間,請確保您已配置以下內(nèi)容:
- 添加一個 PodDisruptionBudget(請參閱“部署”部分中的說明)。對于基于仲裁的應(yīng)用程序,確保運行的副本數(shù)永遠不會低于仲裁所需的數(shù)量(例如,minAvailable: 51%)。
- 確保您擁有多個副本(至少是暫時的,在升級期間)。
- 確保保留所有 PersistentVolume 。
- 對于基于選舉的應(yīng)用程序,請確保您已配置就緒探測。
StatefulSet 潛在事件-1
為了說明升級 StatefulSet 時 PodDisruptionBudget (PDB) 的重要性,讓我們考慮一個使用分布式消息系統(tǒng)STAN的示例集群。
STAN 依賴于Raft的仲裁共識,這意味著需要大多數(shù)(> 50%)的服務(wù)器可以就決策達成一致。這個集群的 STAN StatefulSet 有 5 個副本。如果其中 2 個副本失敗,STAN 仍然可以運行。但是,如果超過 2 個副本失敗,STAN 將無法達到法定人數(shù)并停止工作。
我們的示例集群的 STAN StatefulSet 沒有 PDB。使用此配置,升級期間可能會通過以下方式失去仲裁:
由于缺少 PDB,控制計劃表明可以中斷任意數(shù)量的 STAN pod。
- 這意味著節(jié)點池升級能夠同時中斷超過 50% 的 STAN pod。在這種情況下,當(dāng)?shù)谝粋€節(jié)點耗盡時,5 個 STAN pod 中的 3 個會立即被驅(qū)逐。
- 剩下的 2 個 STAN pod 無法維持仲裁,這會導(dǎo)致不可恢復(fù)的數(shù)據(jù)丟失。
- 這種故障模式在下面的動畫中進行了可視化。5 個方塊代表 5 個 STAN Pod。
升級期間 Raft 應(yīng)用程序失去仲裁的動畫。StatefulSet 缺少 PDB
在這種情況下,配置有的 PDB 可以minAvailable: 51%通過確保立即從正在耗盡的節(jié)點中驅(qū)逐不少于 51% 的 Pod 來防止仲裁損失。
StatefulSet 潛在事件-2
為了說明升級 StatefulSets 時就緒探測的重要性,讓我們考慮相同的示例集群。
我們的示例集群的 STAN StatefulSet 配置了一個 PDB(帶有minAvailable: 51%)和一個 liveness probe,但是它缺少一個 readiness probe。使用此配置,升級期間可能會通過以下方式失去仲裁:
- 控制器遵循 PDB 并確保在給定時間中斷的 STAN 節(jié)點不到一半。最初只有 2 個 STAN pod 會從排空節(jié)點中逐出。
- 然而,由于缺乏就緒探測,一旦中斷的 STAN pod 被調(diào)度并激活,控制器就可以中斷更多的 pod。
- 由于活躍度檢查旨在指示正在運行的容器,因此 STAN 在開始(或完成)讀取 Raft 日志之前將自己標(biāo)記為活躍。
- 但是,鑒于 2 個 STAN pod 還沒有完成對 Raft 日志的讀取,它還沒有準備好接受流量。
- 如果控制器現(xiàn)在中斷了更多的 STAN pod,那么當(dāng)我們有 > 50% 的活躍 STAN pod 時,可能有 < 50% 的就緒 STAN pod(即一些 pod 正忙于從 Raft 日志中恢復(fù)狀態(tài))。
- 剩下的 2 個 STAN pod 無法維持仲裁,這會導(dǎo)致不可恢復(fù)的數(shù)據(jù)丟失。
這種故障模式在下面的動畫中進行了可視化。5 個方塊代表 5 個 STAN Pod。紅色方塊表示Pod 尚未活躍。黃色方塊表示 pod 尚未準備好。
升級期間 Raft 應(yīng)用程序失去仲裁的動畫。StatefulSet 缺少 Readiness 探測。
在這種情況下,在新創(chuàng)建的 STAN pod 準備好之前,就緒探測會阻止更多的 STAN pod 被中斷。準備就緒探針可以配置為向/streaming/serverz監(jiān)控端點發(fā)送 HTTP GET 請求;在 STAN 服務(wù)器準備好之前,此端點不會響應(yīng)請求。
總結(jié)
升級 Kubernetes 集群可能會令人傷腦筋。但是,通過對升級過程的基本了解和對各種 Kubernetes 資源的簡要考慮,您應(yīng)該能夠在下次升級期間最大限度地減少停機時間。