圖解 Kubernetes 中四種應(yīng)用平滑升級(jí)方式
如果你已經(jīng)使用 Kubernetes 一段時(shí)間了,則可能需要考慮計(jì)劃定期升級(jí)。從 Kubernetes 1.19 開始,每個(gè)開源版本都提供一年的補(bǔ)丁。你需要升級(jí)到最新的可用次要版本或補(bǔ)丁版本才能獲得安全性和錯(cuò)誤修復(fù)。但是,如何在不停機(jī)的情況下升級(jí)基礎(chǔ)架構(gòu)的關(guān)鍵部分呢?本文將指導(dǎo)你了解在任何環(huán)境中升級(jí) Kubernetes 時(shí)要考慮的常見模式。
我們不會(huì)深入研究執(zhí)行升級(jí)的所有工具和注意事項(xiàng)。如果你使用的是集群管理工具或托管 Kubernetes 服務(wù),你應(yīng)該查閱你的文檔以獲得最適合你環(huán)境的選項(xiàng)。你還需要注意,某些工作負(fù)載和環(huán)境可能會(huì)限制你選擇的升級(jí)策略。
我們將討論集群升級(jí)的一些高級(jí)模式:
- 原地升級(jí)
- 藍(lán)綠升級(jí)
- 滾動(dòng)升級(jí)
- 金絲雀升級(jí)
這些模式類似于應(yīng)用程序升級(jí)選項(xiàng),但由于其潛在的影響可能需要考慮一些獨(dú)特的因素。升級(jí)基礎(chǔ)設(shè)施可能會(huì)產(chǎn)生相當(dāng)大的成本,具體取決于升級(jí)需要多長時(shí)間以及你的規(guī)模有多大。
控制平面組件
Kubernetes 控制平面由 Kubernetes API Server、etcd 數(shù)據(jù)庫、controller manager,、scheduler以及你的環(huán)境中可能擁有的任何其他控制器(例如云或ingress )組成。升級(jí) API Server是升級(jí)集群的第一步。Kubernetes 將狀態(tài)存儲(chǔ)在 etcd 中,并且隨著任何重大應(yīng)用程序升級(jí),你需要確保至少有一個(gè)備份,并且你已經(jīng)驗(yàn)證可以恢復(fù)備份。在某些情況下,API Server升級(jí)可能還需要 etcd 升級(jí)。
數(shù)據(jù)平面組件
Kubernetes 數(shù)據(jù)平面由 kubelet、容器運(yùn)行時(shí)以及你在集群工作負(fù)載中使用的任何網(wǎng)絡(luò)、日志記錄或存儲(chǔ)驅(qū)動(dòng)程序組成。對(duì)于許多集群,至少需要 kube-proxy 和 CNI 插件更新。你的數(shù)據(jù)平面組件可以小于等于你的 API Server版本。理想情況下,你的主機(jī)操作系統(tǒng)、容器運(yùn)行時(shí)和數(shù)據(jù)平面組件可以相互獨(dú)立升級(jí)。將這些組件解耦,將確保你可以在出現(xiàn)錯(cuò)誤修復(fù)、新功能或安全補(bǔ)丁時(shí)快速升級(jí)。
Kubernetes 托管服務(wù)
如果你使用Amazon Elastic Kubernetes Service (EKS)等托管 Kubernetes 服務(wù),則會(huì)為你處理控制平面升級(jí)。如果你使用的是托管數(shù)據(jù)平面服務(wù),例如托管節(jié)點(diǎn)組 (MNG),你的數(shù)據(jù)平面升級(jí)也應(yīng)該由你的云提供商自動(dòng)處理。
即使使用托管服務(wù),你仍然有責(zé)任驗(yàn)證已安裝在集群中的工作負(fù)載、附加控制器和第三方插件(例如 CNI)。在測(cè)試或開發(fā)環(huán)境中升級(jí)集群之前,應(yīng)測(cè)試這些組件的 API 兼容性。
在所有這些升級(jí)策略中,你應(yīng)該避免在集群升級(jí)期間進(jìn)行應(yīng)用程序升級(jí)。如果可能,請(qǐng)保持你的工作負(fù)載使用相同的版本,以最大限度地減少可能錯(cuò)誤地歸因于 Kubernetes 升級(jí)的故障。還要盡量減少其他潛在問題,例如scheme升級(jí)或應(yīng)用程序 API 兼容性。
對(duì)于任何 Kubernetes 升級(jí),你應(yīng)該按以下順序升級(jí)組件:
- 控制平面
- 數(shù)據(jù)平面和節(jié)點(diǎn)
- 附加組件
- 工作負(fù)載
這些升級(jí)模式將幫助你決定如何升級(jí)最適合你的集群和環(huán)境的組件。
01.原地升級(jí)
In-Place Upgrade
執(zhí)行原地升級(jí)時(shí),你必須格外小心,確保組件保持健康,因?yàn)槟闶窃诋?dāng)前服務(wù)于生產(chǎn)流量的集群上執(zhí)行工作。原地升級(jí)可以包括包更新(例如 yum、apt)、配置管理自動(dòng)化(例如 Ansible、Chef)或 VM/容器鏡像更改。理想情況下,你的升級(jí)將是腳本化和自動(dòng)化的(包括回滾),但如果這是你第一次升級(jí),在開發(fā)或測(cè)試環(huán)境中手動(dòng)進(jìn)行升級(jí)可能會(huì)有所幫助。
原地升級(jí)意味著所有組件將大致同時(shí)升級(jí)。如果你通過配置管理更改所需的 API Server版本并推送新配置,則所有 API Server在收到新配置后都會(huì)升級(jí)。這與我們稍后討論的滾動(dòng)升級(jí)不同。
原地升級(jí)的主要好處是:
- 在任何規(guī)模下,它都是最快的。
- 如果手動(dòng)完成,則可以更好地控制組件和升級(jí)過程。
- 它很容易適用于多種環(huán)境(本地或云)。
- 從基礎(chǔ)設(shè)施成本的角度來看,它是最便宜的。
根據(jù)你的流程、規(guī)模和工具,原地升級(jí)可能是能夠編寫腳本的最直接的方法。腳本可以在本地或在開發(fā)集群中進(jìn)行測(cè)試,而無需重新配置集群管理員團(tuán)隊(duì)可能無法訪問的資源——例如負(fù)載均衡器或 DNS。
如果要使用此方法進(jìn)行升級(jí),原地升級(jí)還需要考慮以下限制:
- 如果你的所有 API Server或控制器同時(shí)升級(jí),則可能導(dǎo)致停機(jī)。
- 如果你想從 Kubernetes 1.16 遷移到 1.20,你必須將整個(gè)集群四次升級(jí)到每個(gè)次要版本。
- 驗(yàn)證每個(gè)步驟可能是一個(gè)手動(dòng)過程,這可能會(huì)增加額外的時(shí)間和出錯(cuò)的機(jī)會(huì)。
- 你應(yīng)該在失敗的情況下測(cè)試回滾計(jì)劃,因?yàn)槟承┥?jí)無法輕松恢復(fù)。(例如,scheme更改)。
02.藍(lán)/綠升級(jí)
藍(lán)/綠集群升級(jí)需要你使用新版本的 Kubernetes 創(chuàng)建第二個(gè)集群。你需要部署新的控制平面和數(shù)據(jù)平面,然后將所有工作負(fù)載復(fù)制到新集群,然后再將流量從舊集群切換到新集群。你可以使用藍(lán)/綠來更新集群的每個(gè)組件,但整體集群升級(jí)更易于部署和回滾。
息是,設(shè)置新集群通常比升級(jí)集群更容易。關(guān)于如何將工作負(fù)載部署到新集群,你有多種選擇。如果你的工作負(fù)載已經(jīng)是 GitOps 或持續(xù)交付的一部分,你可以在升級(jí)之前或期間將部署同時(shí)轉(zhuǎn)到新集群和舊集群。如果你沒有自動(dòng)部署,你可以使用Velero 之類的工具來備份你現(xiàn)有的工作負(fù)載并將它們部署到新集群。
創(chuàng)建新的“Green”集群可以讓你對(duì)新版本按預(yù)期工作充滿信心,并讓你控制何時(shí)切換版本。新集群還可用于驗(yàn)證自動(dòng)化工具,例如 Terraform 模塊或 GitOps 存儲(chǔ)庫。你可以隨時(shí)通過 DNS 或負(fù)載均衡器進(jìn)行更改,甚至可以在維護(hù)時(shí)段或低利用率期間進(jìn)行更改。
藍(lán)/綠升級(jí)的主要好處是:
- 在發(fā)送流量之前預(yù)先驗(yàn)證所有組件是否正常。
- 你可以一次升級(jí)多個(gè)版本(例如,從 1.16 直接升級(jí)到 1.20)。
- 你可以更改可能難以測(cè)試的基礎(chǔ)架構(gòu)的其他部分(例如,切換區(qū)域、添加區(qū)域、更改實(shí)例類型)。
- 回滾是最安全和最容易的。
藍(lán)/綠部署要考慮的缺點(diǎn)包括:
- 這是基礎(chǔ)架構(gòu)成本中最昂貴的策略,因?yàn)槟惚仨氃谶w移期間運(yùn)行兩倍的計(jì)算容量。
- 如果你有數(shù)千個(gè)工作程序節(jié)點(diǎn),你可能無法獲得運(yùn)行完整的第二個(gè)集群所需的所有計(jì)算容量。
- 如果你有多個(gè)并發(fā)集群升級(jí),則此策略很難擴(kuò)展到數(shù)十個(gè)或數(shù)百個(gè)集群。
- 除非你有備用服務(wù)器,否則在沒有虛擬化的情況下在本地實(shí)現(xiàn)藍(lán)/綠并不容易。
- 如果你有很多端點(diǎn)要更新,一次切換所有流量可能并不容易。負(fù)載均衡器可能需要預(yù)先調(diào)整并預(yù)熱緩存。請(qǐng)注意 DNS 生存時(shí)間 (TTL),它可能會(huì)或可能不會(huì)用于分散負(fù)載。
- 一次切換所有集群流量需要跨團(tuán)隊(duì)協(xié)調(diào)遷移到新集群;以及工程周期來驗(yàn)證工作負(fù)載的規(guī)模是否正確。
當(dāng)你擁有較少數(shù)量的集群或少于幾百個(gè)工作節(jié)點(diǎn)時(shí),藍(lán)/綠可能是一個(gè)很好的策略。它允許你跳過版本并且回滾是安全的,但它可能會(huì)需要更多的基礎(chǔ)設(shè)施支出和協(xié)調(diào)時(shí)間。
03.滾動(dòng)升級(jí)
如果你熟悉 Kubernetes 部署策略,你就會(huì)熟悉滾動(dòng)升級(jí)。滾動(dòng)升級(jí)將部署組件的一個(gè)升級(jí)為新副本,然后縮減一個(gè)舊副本。它將繼續(xù)這種模式,直到所有舊組件都被刪除。滾動(dòng)升級(jí)的增量性質(zhì)比原地升級(jí)和藍(lán)/綠策略有一些優(yōu)勢(shì)。
與原地升級(jí)類似,你需要一次升級(jí) Kubernetes 的一個(gè)次要版本。當(dāng)需要升級(jí)多個(gè)版本時(shí),這可能是額外的工作,但它是唯一受支持的選項(xiàng)。根據(jù)你要升級(jí)的組件,你可以使用不同的工具來升級(jí)每個(gè)組件。
對(duì)于像控制平面這樣的資源,你可能希望將帶有升級(jí)的 API Server的新服務(wù)器添加到控制平面,然后關(guān)閉舊服務(wù)器。如果你使用的是 AWS,則可以更改 Auto Scaling 組啟動(dòng)配置 AMI 并一次替換一個(gè)實(shí)例。其他控制平面組件(例如調(diào)度程序)可能在集群內(nèi)作為容器運(yùn)行,因此你可以使用標(biāo)準(zhǔn)的 Kubernetes 滾動(dòng)部署升級(jí)來升級(jí)這些組件。
與藍(lán)/綠相比,滾動(dòng)升級(jí)的主要區(qū)別在于你的外部流量路由(DNS 和負(fù)載均衡器)將保持指向同一位置。在進(jìn)行生產(chǎn)集群升級(jí)之前,你需要確保在不同的集群或環(huán)境中測(cè)試所有附加組件和工作負(fù)載。
請(qǐng)注意,AWS 托管節(jié)點(diǎn)組、kOps、Cluster-API和許多其他 Kubernetes 集群管理工具使用滾動(dòng)升級(jí)策略。好處包括:
- 與原地升級(jí)相比,更安全的更新和回滾。
- 成本低于藍(lán)色/綠色,并且資源耗盡的可能性較小。
- 如果出現(xiàn)問題,可以在升級(jí)過程中暫停。
- 可以在本地環(huán)境模擬。
滾動(dòng)升級(jí)是最常見的自動(dòng)化工具。它們?cè)谒俣群统杀局g取得了很好的平衡,也減少手動(dòng)工作和風(fēng)險(xiǎn)。
升級(jí)生產(chǎn)集群時(shí),你現(xiàn)有的所有工作負(fù)載仍將被部署;只要你測(cè)試了它們的兼容性,你的升級(jí)就應(yīng)該是可自動(dòng)化的。
使用滾動(dòng)升級(jí)時(shí)的進(jìn)一步考慮包括:
- 滾動(dòng)升級(jí)可能會(huì)很慢,具體取決于你的規(guī)模。
- 在升級(jí)期間,你可能需要協(xié)調(diào)控制器、守護(hù)進(jìn)程或插件升級(jí)。
- 你可能無法進(jìn)行集群范圍的更改,例如添加可用區(qū)或更改架構(gòu)。
04.金絲雀升級(jí)
Canary 應(yīng)用程序部署一次為應(yīng)用程序的新版本提供少量流量。Canary 升級(jí)可以被認(rèn)為是具有藍(lán)/綠優(yōu)勢(shì)的滾動(dòng)升級(jí)。
通過 Canary 升級(jí),你將使用要部署的版本創(chuàng)建一個(gè)新的 Kubernetes 集群。然后添加一個(gè)小型數(shù)據(jù)平面并將你現(xiàn)有的應(yīng)用程序以較小的規(guī)模部署到新集群。通過負(fù)載均衡器配置、DNS 循環(huán)或服務(wù)網(wǎng)格將新的集群工作負(fù)載添加到現(xiàn)有的生產(chǎn)流量中。
現(xiàn)在,你可以監(jiān)控流向新集群的流量,慢慢擴(kuò)展新集群中的工作負(fù)載并縮減舊集群中的工作負(fù)載。你可以一次完成一項(xiàng)工作,并且可以根據(jù)自己的習(xí)慣緩慢或快速完成。如果任何單個(gè)工作負(fù)載開始出現(xiàn)錯(cuò)誤,你可以縮減新集群中的單個(gè)工作負(fù)載,使其自動(dòng)使用舊集群。
Canary 集群升級(jí)的好處包括:
- 新集群更容易創(chuàng)建和驗(yàn)證。
- 你可以在升級(jí)期間跳過次要 Kubernetes 版本(例如,1.16 到 1.20)。
- 可以在每個(gè)團(tuán)隊(duì)的基礎(chǔ)上選擇加入應(yīng)用程序部署。
- 由于增加的流量使用,錯(cuò)誤的影響最小。
- 你可以在升級(jí)期間進(jìn)行大型基礎(chǔ)架構(gòu)更改。
- 集群從小規(guī)模開始,因此基礎(chǔ)設(shè)施成本較低,你可以在擴(kuò)展時(shí)預(yù)熱緩存和負(fù)載均衡器。
如果你想進(jìn)行較大的更改(例如更改架構(gòu))或者你想添加額外的可用區(qū),那么 Canary 是一個(gè)不錯(cuò)的選擇。通過啟動(dòng)較小的集群并根據(jù)工作負(fù)載增加它,你可以確保在新實(shí)例更高效或工作負(fù)載請(qǐng)求和限制發(fā)生變化時(shí)不會(huì)過度配置基礎(chǔ)設(shè)施。
與任何事情一樣,需要權(quán)衡取舍。使用金絲雀部署時(shí),你應(yīng)該注意以下一些問題:
- 回滾應(yīng)用程序可能需要手動(dòng)干預(yù)來更改負(fù)載均衡器或縮小新集群的規(guī)模。
- 調(diào)試應(yīng)用程序可能更難,因?yàn)槟阈枰腊l(fā)生了哪些集群錯(cuò)誤。
- 如果你有數(shù)十個(gè)或數(shù)百個(gè)集群,隨著集群的升級(jí),你的集群數(shù)量可能會(huì)增加 50% 或更多。
Canary 是最復(fù)雜的升級(jí)策略,但它受益于自動(dòng)化部署、健康檢查和性能監(jiān)控。
結(jié)論
無論你選擇哪種升級(jí)策略,重要的是要了解它們的工作原理以及隨著 Kubernetes 使用量的增長可能出現(xiàn)的任何問題。你需要有一個(gè)升級(jí)策略,因?yàn)?Kubernetes 有頻繁的發(fā)布和偶爾的錯(cuò)誤。
與新版本保持同步可能是你的基礎(chǔ)設(shè)施安全流程的重要組成部分,并使應(yīng)用程序能夠快速利用新功能。如果你部署了 Kubernetes 并遷移了所有工作負(fù)載,而沒有考慮如何升級(jí),那么現(xiàn)在是開始計(jì)劃的最佳時(shí)機(jī)。
如果你沒有運(yùn)行自己的 Kubernetes 集群的業(yè)務(wù)需求,我強(qiáng)烈建議你使用可用的托管 Kubernetes 選項(xiàng)之一。選擇托管控制平面和數(shù)據(jù)平面可以為你每年節(jié)省數(shù)天或數(shù)周的規(guī)劃和升級(jí)時(shí)間。每個(gè)托管選項(xiàng)可能執(zhí)行不同的升級(jí),但它們都允許你專注于工作負(fù)載和業(yè)務(wù)價(jià)值,而不是控制平面高可用性或數(shù)據(jù)平面兼容性。