Kubernetes 集群升级指南:从理论到实践
作者 | 高相林(禪鳴)
**導讀:**集群升級是 Kubernetes?集群生命周期中最為重要的一環(huán),也是眾多使用者最為謹慎對待的操作之一。為了更好地理解集群升級這件事情的內涵外延,我們首先會對集群升級的必要性和難點進行闡述;隨后會對集群升級前必須要做的前置檢查進行逐一講解;接下來會對兩種常見的升級方式進行展開介紹;最后對集群升級的三個步驟進行講解,幫助讀者從理論走入實踐。
升級的必要性&難點
在 Kubernetes 領域,得益于活躍的開源社區(qū),Kubernetes 的迭代速度較快,目前保持在每個季度發(fā)行一個新版本的節(jié)奏。新版本的 Kubernetes 有著更為先進的新特性、更加全面的安全加固和漏洞修復。前一段時間社區(qū)剛剛完成了 1.19 版本的正式發(fā)布。
對于發(fā)展如此快速的開源項目,跟上社區(qū)的步伐就顯得更為重要,而集群升級能力就是幫助我們跟上社區(qū)步伐的不二選擇。我們可以從以下兩個方面對集群升級的必要性進行說明:
-
對于 Kubernetes 集群的使用者:更新的 Kubernetes 版本意味著更新的 feature,更加全面的安全補丁,和諸多的 bugfix。我們可以通過集群升級功能充分享受活躍的 Kubernetes 開源社區(qū)帶來的發(fā)展紅利;
-
對于 Kubernetes 集群的運維者:通過集群升級功能可以拉齊所管理的集群版本,減少集群版本的碎片化,從而減少 Kubernetes 版本碎片化帶來的管理成本和維護成本。
講完了集群升級的必要性,我們來詳細看一下集群升級的難點。
目前多數(shù) Kubernetes 使用者對集群升級這件事持有著非常保守的態(tài)度,害怕集群在升級的過程中出現(xiàn)不可預期的情況,也有使用者將集群升級稱之為“給飛行中的飛機換引擎”。那么,使用者對于升級的保守態(tài)度主要來源于什么原因呢?我認為有以下幾點:
-
經過長時間的運行后,Kubernetes 集群已經累計了復雜的運行時狀態(tài);
-
Kubernetes 集群運維者會根據(jù)集群承載的不同業(yè)務,對集群進行不同的配置,從而導致每個集群都有自己的差異化配置,可能會造成“千集群千面”;
-
對于云上運行的 Kubernetes 集群來說,其使用了大量的云計算底層資源。眾多的底層云資源就會帶來眾多的不確定性因素。
“千集群千面”的情況的存在,導致了集群升級需要以一套邏輯完成各種不同情況集群的升級工作,這也正是集群升級的困難之處。
升級預檢
正如我們前面所說,給正在對外提供服務的 Kubernetes 集群升級,就好比是“給飛行中的飛機換引擎”。因為集群升級面臨著眾多難點,也使得眾多的 Kubernetes 集群維護者對集群升級這件事情比較緊張。
我們可以通過詳細的升級預檢,來消除集群升級的不確定性。對于上面列舉的集群升級的難點,我們也可以分別進行詳細的升級預檢,對癥下藥,將難點逐一擊破。升級預檢主要可以分為三個方面:
- 核心組件健康檢查
- 節(jié)點配置檢查
- 云資源檢查
1. 核心組件健康檢查
說到核心組件健康檢查,就不得不剖析一下集群的健康對于集群升級的重要性。一個不健康的集群很可能會在升級中出現(xiàn)各種異常的問題,就算僥幸完成了升級,各種問題也會在后續(xù)使用中逐漸凸顯出來。
有人會說,我的集群看起來挺健康的,但是升級之后就出現(xiàn)問題了。一般來說,之所以會發(fā)生這種情況,是因為在集群在升級之前,這個問題已經存在了,只不過是在經歷了集群升級之后才顯現(xiàn)出來。
在了解了核心組件健康檢查的必要性之后,我們來看一下都需要對那些組件進行檢查:
- 網絡組件:需要確保網絡組件版本和需要升級到的目標 Kubernetes 版本兼容;
- apiservice:需要確保集群內的 apiservice 都可用;
- 節(jié)點:需要確定節(jié)點全部健康。
2. 節(jié)點配置檢查
節(jié)點作為承載 Kubernetes 的底層元計算資源,不僅運行著 Kubelet、Docker 等重要的系統(tǒng)進程,也充當著集群和底層硬件交互接口的角色。
確保節(jié)點的健康性和配置的正確性是確保整個集群健康性重要的一環(huán)。下面就對所需的檢查項進行講解。
- 操作系統(tǒng)配置:需要確定基礎的系統(tǒng)組件(yum、systemd 和 ntp 等系統(tǒng)服務是否正常)和內核參數(shù)是否配置合理;
- kubelet:需要確定 kubelet 的進程健康、配置正確;
- Docker:需要確定 Docker 的進程健康、配置正確。
3. 云資源檢查
運行在云上的 Kubernetes 集群依賴著眾多云資源,一旦集群所依賴的云資源不健康或者配置錯誤,就會影響到整個集群的正常運行。我們主要對下列云資源的狀態(tài)和配置進行預檢:
- apiserver 所使用的 SLB:需要確定實例的健康狀態(tài)和端口配置(轉發(fā)配置和訪問控制配置等);
- 集群所使用的 VPC 和 VSwitch:需要確定實例的健康狀況;
- 集群內的 ECS 實例:需要確定其健康狀況和網絡配置。
兩種常見的升級方式
在軟件升級領域,有兩種主流的軟件升級方式,即原地升級和替換升級。這兩種升級方式同樣適用于 Kubernetes 集群,它們采用了不同軟件升級思路,但也都存在著各自的利弊。下面我們來對這兩種集群升級方式進行逐一講解。
1. 原地升級
原地升級是一種精細化的、對這個那個集群改動量相對較小的一種升級方式。在升級容器的 worker 節(jié)點時,該升級方式會通過在 ECS 上原地替換 Kubernetes 組件的方式(主要為 kubelet 和其相關組件),完成整個集群的升級工作。阿里云容器服務 Kubernetes 為客戶提供的集群升級就是基于這種方式的。
以將 Kubernetes 的版本從 1.14 升級到 1.16 為例。首先我們會對 ECS A 上的原本為 1.14 的 Kubelet 及其配置升級為 1.16,在完成節(jié)點 ECS A 上的組件升級之后,該節(jié)點也就被成功的升級到了 1.16。然后我們再對 ECS B 進行相同的操作,將其升級為 1.16,從而完成整個集群的升級工作。
在這個過程中節(jié)點保持運行,ECS 的相關配置也不會被修改。如圖所示:
1)優(yōu)點
-
原地升級通過原地替換 kubelet 組件的方式對節(jié)點進行版本升級,從而保證了節(jié)點上的 Pod 不會因為集群升級而重建,確保了業(yè)務的連貫性;
-
該種升級方式不會對底層 ECS 本身進行修改和替換,保證了依賴特定節(jié)點調度的業(yè)務可以正常運行,也對 ECS 的包年包月客戶更加友好。
2)缺點
-
原地升級方式需要在節(jié)點上進行一系列升級操作,才能完成整個節(jié)點的升級工作,這就導致整個升級過程不夠原子化,可能會在中間的某一步驟失敗,從而導致該節(jié)點升級失敗;
-
原地升級的另一個缺點是需要預留一定量的資源,只有在資源足夠的情況下升級程序才能在 ECS 上完成對節(jié)點的升級。
2. 替換升級
替換升級又稱輪轉升級,相對于原地升級,替換升級是一種更加粗狂和原子化的升級方式。替換升級會逐個將舊版本的節(jié)點從集群中移除,并用新版本全新的節(jié)點來替換,從而完成整個 Kubernetes 集群的升級工作。
同樣以將 Kubernetes 的版本從 1.14 升級到 1.16 為例。使用替代輪轉方式的情況下,我們會將集群中 1.14 版本的節(jié)點依次進行排水并從集群中移除,并直接加入 1.16 版本的節(jié)點。即將 1.14 節(jié)點的 ECS A 從節(jié)點剔除,并將 1.16 節(jié)點的 ECS C 加入集群,再將 ECS B 從集群中刪除,最后將 ECS D 加入到集群中。
這樣就完成了所有節(jié)點的輪轉工作,整個集群就也就升級到 1.16 了。如圖所示:
1)優(yōu)點
替代升級通過將舊版本的節(jié)點替換為新版本的節(jié)點從而完成集群升級。這個替換的過程相較于原地升級更為原子化,也不存在那么復雜的中間狀態(tài),所以也不需要在升級之前進行太多的前置檢查。相對應地,升級過程中可能會出現(xiàn)的各種稀奇古怪的問題也會減少很多。
2)缺點
-
替代升級將集群內的節(jié)點全部進行替換和重置,所有節(jié)點都會經歷排水的過程,這就會使集群內的 pod 進行大量遷移重建,對于 pod 重建容忍度比較低的業(yè)務、只有單副本的應用、stateful set 等相關應用不夠友好,可能會因此發(fā)生不可用或者故障;
-
所有的節(jié)點經歷重置,儲存在節(jié)點本地磁盤上的數(shù)據(jù)都會丟失;
-
這種升級方式可能會帶來宿主機 IP 變化等問題,對包年包月用戶也不夠友好。
集群升級三部曲
一個 Kubernetes 集群主要由負責集群管控的 master,執(zhí)行工作負載的 worker 和眾多功能性的系統(tǒng)組件組成。對一個 Kubernetes 集群升級,也就是對集群中的這三個部分進行分別升級。
故集群升級的三部曲為:
- 滾動升級 master
- 分批升級 worker
- 系統(tǒng)組件升級(主要為 CoreDNS,kube-proxy 等核心組件)
下面我們來對集群升級三部曲進行詳細的講解。
1. 滾動升級?master
master 作為集群的大腦,承擔了與使用者交互、任務調度和各種功能性的任務處理。集群 master 的部署方式也比較多樣,可以通過 static pod 進行部署,可以通過本地進程進行部署,也可以通過 Kubernetes on Kubernetes 的方式在另一個集群內通過 pod 的方式部署。
總而言之,無論 master 為哪種部署方式,想要升級 master 主要就是對 master 中的三大件進行版本升級,主要包括:
- 升級 kube-apiserver
- 升級 kube-controller-manager
- 升級 kube-scheduler
需要注意,為了保證 Kubernetes apiserver 的可用性不中斷,master 中的 kube-apiserver 最少需要有兩個,這樣才可以實現(xiàn)滾動升級,從而保證 apiserver 不會出現(xiàn) downtime。
2. 分批升級 worker
在完成 master 的升級工作之后,我們才可以開始對 worker 進行升級。Worker 升級主要是對節(jié)點上的 kubelet 及其依賴組件(如 cni 等)進行升級。為了保證集群中 worker 不會同時發(fā)生大批量的 kubelet 重啟,所以我們需要對 worker 節(jié)點進行分批升級。
需要注意,我們必須要先升級 master,再升級 worker。因為高版本的 kubelet 在連接低版本的 master 時,很可能會出現(xiàn)不兼容的情況,從而導致節(jié)點 not ready。對于低版本的 kubelet 連接高版本的 apiserver,開源社區(qū)保證了 apiserver 對于 kubelet 兩個版本的向后兼容性,即 1.14 的 kubelet 可以連接到 1.16 的 apiserver,而不會發(fā)生兼容性問題。
3. 核心系統(tǒng)組件升級
為了保證集群中各個組件的兼容性,我們需要在升級集群的同時對集群中的核心系統(tǒng)組件進行同步升級,主要包括:
- Dns 組件:根據(jù)社區(qū)的版本兼容矩陣,將 CoreDNS 的版本升級為與集群版本相對應的版本;
社區(qū)的版本兼容矩陣:https://github.com/coredns/deployment/blob/master/kubernetes/CoreDNS-k8s_version.md
- 網絡轉發(fā)組件:Kube-proxy 的版本是跟隨 Kubernetes 的版本進行演進的,所有我們需要將 kube-proxy 的版本升級到與 Kubernetes 版本相同的版本。
課程推薦
去年,CNCF 與 阿里云聯(lián)合發(fā)布了《云原生技術公開課》已經成為了 Kubernetes 開發(fā)者的一門“必修課”。
今天,阿里云再次集結多位具有豐富云原生實踐經驗的技術專家,正式推出《云原生技術實踐公開課》。課程內容由淺入深,專注講解“ 落地實踐”。還為學習者打造了真實、可操作的實驗場景,方便驗證學習成果,也為之后的實踐應用打下堅實基礎。點擊鏈接查看課程:https://developer.aliyun.com/learning/roadmap/cloudnative2020
“阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規(guī)模的落地實踐,做最懂云原生開發(fā)者的公眾號?!?/p>
總結
以上是生活随笔為你收集整理的Kubernetes 集群升级指南:从理论到实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sentinel-Go 集成 Nacos
- 下一篇: Dubbo 3.0 前瞻:重塑 Spri