1. 如何在零停機(jī)的情況下遷移 Kubernetes 集群

        共 6274字,需瀏覽 13分鐘

         ·

        2022-01-15 02:02

        作者:顧靜(子白)|阿里云高級(jí)研發(fā)工程師;謝瑤瑤(初揚(yáng))|阿里云技術(shù)專家

         

        導(dǎo)語(yǔ)隨著云原生理念在企業(yè)中的深入和踐行,應(yīng)用容器化的比例大幅提升。是否可以保證應(yīng)用容器化遷移過(guò)程中的平穩(wěn)切換,保證應(yīng)用不停機(jī)遷移,成為影響用戶業(yè)務(wù)云化的一個(gè)重要條件。本文整理自阿里云云原生團(tuán)隊(duì)在 KubeCon China 2021 線上峰會(huì)的分享實(shí)錄,將通過(guò)集群遷移的需求、場(chǎng)景以及實(shí)踐方式,介紹如何基于阿里云容器服務(wù) ACK,在零停機(jī)的情況下遷移 Kubernetes 集群。


        大家好,我是謝瑤瑤,來(lái)自阿里云,目前是 Cloud-provider 開(kāi)源子項(xiàng)目 cloud-provider-alibaba-cloud 項(xiàng)目的 Maintainer。今天由我和我的同事顧靜一起為大家分享如何不停機(jī)的遷移 Kubernetes 集群。顧靜同學(xué)也是 cloud-provider-alibaba-cloud 項(xiàng)目的 Maintainer。


        我們將從上圖幾個(gè)方面來(lái)分享如何不停機(jī)的遷移 Kubernetes 集群。首先我們會(huì)為大家介紹一下集群遷移的需求以及應(yīng)用場(chǎng)景;接著我們會(huì)著重介紹如何實(shí)現(xiàn)不停機(jī)地 Kubernetes 集群遷移,包括如何進(jìn)行遷移前的前置檢查,如何做應(yīng)用的數(shù)據(jù)遷移與流量遷移等等。


        01

        為什么要遷移 Kubernetes 集群?

        Cloud Native


        下面簡(jiǎn)單介紹下集群遷移的應(yīng)用場(chǎng)景。

         

        1
         容器化的應(yīng)用遷云


        首先我們來(lái)看一下容器化的應(yīng)用遷移場(chǎng)景。近年來(lái)云原生理念已經(jīng)逐漸深入到了各大公司中。據(jù)相關(guān)調(diào)查統(tǒng)計(jì),將近有 65% 的應(yīng)用已經(jīng)實(shí)現(xiàn)了容器化,并逐步從線下的數(shù)據(jù)中心遷移到了云上,以便充分利用云的彈性來(lái)實(shí)現(xiàn)企業(yè)的降本增效。是否可以保證應(yīng)用容器化遷移過(guò)程中的平穩(wěn)切換,保證應(yīng)用不停機(jī)遷移,成為影響用戶業(yè)務(wù)云化的一個(gè)重要條件。


        2
         跨云同步與遷移
         

        其次是混合云場(chǎng)景下的跨云流量遷移。對(duì)用戶來(lái)講,如果云是一個(gè)極具性價(jià)比的選擇的話,那么混合云和多云的架構(gòu)進(jìn)一步為用戶提供了一個(gè)低成本全球可達(dá)的應(yīng)用發(fā)布平臺(tái)。多云可以讓用戶的應(yīng)用部署到多個(gè)云廠商,避免廠商鎖定。同時(shí)它能夠提供更高的議價(jià)能力、更強(qiáng)的備份、災(zāi)難恢復(fù)能力和更強(qiáng)的穩(wěn)定性。同時(shí)還可以為全球用戶提供基于地理位置的就近服務(wù)體驗(yàn)。如何進(jìn)行不停機(jī)跨云同步機(jī)遷移是部署跨云/多云應(yīng)用的前提。

         

        3
         集群新特性與 BreakingChange 場(chǎng)景

         

        更高的 Kubernetes 版本往往會(huì)具有更多的新特性,但是使用這些新特性并不是沒(méi)有代價(jià)的。如果你需要使用新特性,那就必須升級(jí) Kubernetes 到對(duì)應(yīng)的新版本。這通常不是一件容易的事情。如果你的集群版本太低,那么你需要多次升級(jí)集群才能到達(dá)預(yù)期的版本。比如從 1.14 依次升級(jí)到 1.16,然后是 1.18,然后才是 1.20,這樣來(lái)避免單次升級(jí)集群版本過(guò)大造成的兼容性問(wèn)題。并且這些新特性所引入的兼容性問(wèn)題還可能造成服務(wù)中斷。


         

        除了升級(jí)困難以及版本兼容性問(wèn)題,升級(jí)已有集群無(wú)法實(shí)現(xiàn)一些配置變更類的需求。比如你無(wú)法直接變更一個(gè)已有集群的網(wǎng)絡(luò)模式,比如從 IPTables 切換到 IPVS,F(xiàn)lannel 到 Terway,更改 Cluster CIDR 等。這些變更會(huì)造成整個(gè)集群已有節(jié)點(diǎn)及 Pod 的重建,造成服務(wù)不可用,甚至是整個(gè)集群配置被污染。因此不停止遷移 Kubernetes 集群應(yīng)用在這種情況下可能是一個(gè)更好的選擇。

         

        接下來(lái)我們介紹一下如何進(jìn)行不停機(jī)遷移。不停機(jī)遷移總體上分為 3 個(gè)階段。

         

        第一階段:前置檢查,提前暴露遷移可能存在的潛在風(fēng)險(xiǎn);第二階段是應(yīng)用遷移,這一階段需要新建一個(gè)目標(biāo)版本的集群,并將應(yīng)用及其數(shù)據(jù)遷移到新的集群中;第三階段是流量遷移,這一階段至關(guān)重要,他決定了如何不停機(jī)地將線上流量導(dǎo)入到新建的集群中,并使用新建的集群為用戶提供服務(wù)。

         

        首先在前置檢查階段,我們需要盡早的暴露遷移風(fēng)險(xiǎn),因此我們開(kāi)發(fā)了一套前置檢查框架,用來(lái)檢查集群是否做好了遷移準(zhǔn)備。比如不同版本的集群會(huì)有 API groups 兼容性,需要提前處理 Label 的兼容性,不同版本的組件的行為差異等,如 kubeproxy 處理 SLB 流量轉(zhuǎn)發(fā)的行為差異,會(huì)直接影響流量遷移的成功。因此前置檢查是一項(xiàng)非常重要的步驟。

         

        前置檢查項(xiàng)都通過(guò)后,接下來(lái)就是應(yīng)用的遷移與流量遷移。



        應(yīng)用的遷移可以通過(guò)開(kāi)源組件 Velero 進(jìn)行,官方有詳細(xì)的文檔來(lái)說(shuō)明應(yīng)用的遷移,阿里云也專門為其提交了阿里云相關(guān)驅(qū)動(dòng)。這里我們主要介紹一下如何做數(shù)據(jù)遷移,數(shù)據(jù)遷移是實(shí)現(xiàn)不停機(jī)遷移的重要一環(huán),我們會(huì)以磁盤存儲(chǔ)和有狀態(tài)應(yīng)用 MySQL/ETCD 的遷移為例,來(lái)說(shuō)明如何進(jìn)行數(shù)據(jù)的遷移。

         

        通常云上的存儲(chǔ)主要有 NFS、OSS 對(duì)象存儲(chǔ)、CloudDisk 云盤等,通常各大云廠商都為磁盤類型的存儲(chǔ)提供了完善的快照方法及恢復(fù)方法。上圖展示了如何將上海 Region 的應(yīng)用數(shù)據(jù)遷移到杭州 Region 的方法,對(duì)于磁盤存儲(chǔ)類型,首先在上海 Region 構(gòu)建磁盤快照,然后將快照通過(guò)云廠商的網(wǎng)絡(luò)同步到待恢復(fù)的地域杭州,然后通過(guò)快照恢復(fù)功能創(chuàng)建一塊磁盤,然后掛在到節(jié)點(diǎn)上后應(yīng)用即可隨時(shí)使用。

         

        對(duì)于自建 MySQL/ ETCD 一類的應(yīng)用數(shù)據(jù),由于其持續(xù)讀寫可能造成潛在的數(shù)據(jù)不一致的情況,我們可以通過(guò)為該應(yīng)用在目標(biāo) Region 構(gòu)建多個(gè) Slave 副本(或者 quorum 副本),用來(lái)進(jìn)行實(shí)時(shí)數(shù)據(jù)同步,當(dāng)流量低峰期到來(lái)的時(shí)候,執(zhí)行主從切換,或者強(qiáng)制選主流程。一旦目標(biāo) Region 選主完成,則代表切換完成,可以逐步下線原 Region 的 MySQL 或 ETCD 副本。這就是一個(gè)簡(jiǎn)單的數(shù)據(jù)遷移流程。

         

        接下來(lái)介紹一下流量遷移部分。流量遷移是集群遷移中十分重要的環(huán)節(jié)。流量遷移是指在業(yè)務(wù)流量無(wú)中斷的前提下,將業(yè)務(wù)流量從一個(gè)集群遷移到另一個(gè)集群中去??蛻舳藢?duì)流量遷移應(yīng)當(dāng)完全無(wú)感。

         

        DNS 是實(shí)現(xiàn)無(wú)損流量遷移的一種方式。分別在兩個(gè)集群中創(chuàng)建兩個(gè) LoadBalancer 類型 Service,然后將兩個(gè) SLB 添加到 DNS 后端,基于 DNS 的灰度能力實(shí)現(xiàn)流量分發(fā)到兩個(gè)不同的集群中。這種方式較為簡(jiǎn)單,但是有一個(gè)比較大的缺陷,DNS 緩存有過(guò)期時(shí)間,流量切換后需要等待 30 分鐘左右才能生效。當(dāng)在新集群中進(jìn)行業(yè)務(wù)回滾時(shí),這個(gè)延遲不可接受的。

         

         

        另外一種流量遷移方式是基于 Istio 實(shí)現(xiàn)的。Istio 方式比較復(fù)雜,學(xué)習(xí)成本比較高。需要新建一個(gè) Istio 集群,并且更改已有的應(yīng)用部署方式,然后基于 Istio 的灰度能力進(jìn)行流量遷移。

         

        那么有沒(méi)有一種方式,操作簡(jiǎn)單又可以實(shí)現(xiàn)實(shí)時(shí)無(wú)損流量遷移呢?


        02

        如何在零停機(jī)的情況下

        遷移 Kubernetes 集群

        Cloud Native

        為了解決這個(gè)問(wèn)題,我們還得從服務(wù)暴露方式入手。LoadBalancer 類型的 Service 實(shí)際是通過(guò)云上負(fù)載均衡器對(duì)外部暴露服務(wù)的。負(fù)載均衡器是由各云服務(wù)提供商通過(guò)部署在集群中的 controller 創(chuàng)建的,創(chuàng)建出來(lái)的負(fù)載均衡器的信息會(huì)顯示在 Service 的 status.loadBalancer 字段中。請(qǐng)求訪問(wèn)云上負(fù)載均衡器時(shí),由各云廠商負(fù)責(zé)將流量重定向到后端 Pod 上。


        Cloud Controller Manager(CCM)就是阿里云容器服務(wù)部署在 Kubernetes 集群中的 controller,負(fù)責(zé)對(duì)接 Kubernetes 資源及云上基礎(chǔ)產(chǎn)品,如 SLB、VPC、DNS 等。對(duì)于 SLB,CCM 支持兩種流量轉(zhuǎn)發(fā)方式,一種是 ECS 模式,一種是 ENI 模式。ECS 模式將 Node IP 和 NodePort 掛載到 SLB 后端,流量經(jīng)由 SLB 轉(zhuǎn)向 Node,然后經(jīng)過(guò)節(jié)點(diǎn)的 kube-proxy 轉(zhuǎn)發(fā)至 Pod 上。ENI 模式將 PodIP 及 TargetPort 掛載到 SLB 后端,流量經(jīng)由 SLB 直接轉(zhuǎn)發(fā)到 Pod 上。與 ECS 模式相比,ENI 模式少了一層網(wǎng)絡(luò)轉(zhuǎn)發(fā),網(wǎng)絡(luò)性能更好。流量轉(zhuǎn)發(fā)模式與 Kubernetes 中網(wǎng)絡(luò)插件有關(guān),F(xiàn)lannel 網(wǎng)絡(luò)插件默認(rèn)為 ECS 模式,Terway 網(wǎng)絡(luò)插件默認(rèn)為 ENI 模式。


         

        那么 CCM 是如何管理 SLB 的呢?

         


        對(duì)于 LoadBalancer 類型的 Service,CCM 會(huì)為該 Service 創(chuàng)建或配置阿里云負(fù)載均衡 SLB。CCM 首先會(huì)查詢 Kubernetes Service 信息,構(gòu)建 Local model,然后查詢 SLB 信息,構(gòu)建 Remote model。對(duì)比兩個(gè) model 的差別,根據(jù) Local model 更新 Remote model,直到兩個(gè) model 一致。當(dāng) Service 對(duì)應(yīng)的 Endpoint 或者集群節(jié)點(diǎn)發(fā)生變化時(shí),CCM 會(huì)自動(dòng)更新 SLB 的虛擬服務(wù)器組中的后端。此外,CCM 還提供了許多阿里云特定注解,支持豐富的負(fù)載均衡能力。

         

        當(dāng)用戶訪問(wèn) service 時(shí),如果在集群內(nèi)部,經(jīng)由 service 轉(zhuǎn)發(fā)至 Node,經(jīng)過(guò) kube-proxy 轉(zhuǎn)發(fā)到 Pod。如果訪問(wèn)負(fù)載均衡 ip 時(shí),則通過(guò) SLB 后轉(zhuǎn)發(fā)至節(jié)點(diǎn) Node 或者 Pod上。

         

        了解 LoadBalancer service 工作原理后,能不能通過(guò) CCM 實(shí)現(xiàn)實(shí)時(shí)無(wú)損流量遷移呢?答案是可以的。將兩個(gè)集群的節(jié)點(diǎn)加入到同一個(gè) SLB 的同一個(gè)端口中,然后通過(guò)修改兩個(gè)集群所占權(quán)重即可實(shí)現(xiàn)流量遷移。對(duì)于客戶端來(lái)講,訪問(wèn)的仍然是以前的 SLB ip 和 port,完全無(wú)感。

         

         

        具體操作如下:首先在 1.14 集群中創(chuàng)建一個(gè) Service,指定已有 SLB 及端口,以及端口關(guān)聯(lián)的虛擬服務(wù)器組。然后在 1.20 集群中創(chuàng)建一個(gè) Service,指定同樣的 SLB、端口及虛擬服務(wù)器組。通過(guò) weight annotation 為兩個(gè)集群設(shè)置權(quán)重。


         

        配置完成后,流量轉(zhuǎn)發(fā)方式如上圖所示。有 80% 的流量轉(zhuǎn)發(fā)到 1.14 集群中,20% 的流量轉(zhuǎn)發(fā)到 1.20 集群中。


        兩個(gè)集群共用 SLB 的同一個(gè)端口。通過(guò)修改 Service 中的 weight annotation 可以動(dòng)態(tài)實(shí)時(shí)修改流向兩個(gè)集群的流量比例,實(shí)現(xiàn)灰度流量遷移。當(dāng)遷移完成后,從 1.14 集群中刪除 Service 即可。


         

        設(shè)置權(quán)重 annotation 后,如何保證集群內(nèi) Pod 負(fù)載均衡呢?

         

        對(duì)于 externalTrafficPolicy 為 Cluster 的 service,CCM 會(huì)將所有節(jié)點(diǎn)加入到 SLB 后端。每個(gè)節(jié)點(diǎn)的權(quán)重為 weight/NodeNum。此時(shí),Node1,Node2,Node3 權(quán)重均為 27,但是三個(gè)節(jié)點(diǎn)上的 Pod 數(shù)量并不均衡,那么如何實(shí)現(xiàn) Pod 負(fù)載均衡呢?Cluster 模式是依賴 kube-proxy 實(shí)現(xiàn)的。在 cluster 模式下,kube-proxy 會(huì)將所有 Pod 信息寫入到本地的轉(zhuǎn)發(fā)規(guī)則中,并以輪訓(xùn)的方式向這些 Pod 轉(zhuǎn)發(fā)請(qǐng)求。以 Node3 為例,該節(jié)點(diǎn)上沒(méi)有 Pod,當(dāng)請(qǐng)求發(fā)送到 Node3 節(jié)點(diǎn)后,kube-proxy 會(huì)將請(qǐng)求轉(zhuǎn)發(fā)給 Node1 或者 Node2。


        對(duì)于 externalTrafficPolicy 為 Local 的 service,CCM 僅會(huì)將 Pod 所在節(jié)點(diǎn)加入到 SLB 后端。因?yàn)槿绻?jié)點(diǎn)沒(méi)有 Pod,當(dāng)請(qǐng)求轉(zhuǎn)發(fā)至該節(jié)點(diǎn)時(shí),請(qǐng)求會(huì)被直接丟棄。Local 模式下,需要先計(jì)算每個(gè) Pod 的權(quán)重,即 PerPodWeight=Weight/TotalPodNum。節(jié)點(diǎn)權(quán)重為 NodePodNum*PerPodWeight。Node1 為 50,Node2 為 30。由于每個(gè) Pod 的權(quán)重都為 10,因此 Pod 間可以實(shí)現(xiàn)負(fù)載均衡。


        基于 CCM 的流量遷移方案不僅適用于云上集群遷移,還適用于混合云、跨 Region 遷移及跨云遷移場(chǎng)景。以混合云場(chǎng)景為例,客戶可以將線下 ECS 加入到 SLB 后端,然后通過(guò)設(shè)置權(quán)重逐步將流量從線下集群遷移到線上集群中,無(wú)需進(jìn)行業(yè)務(wù)改造,客戶端也是完全無(wú)感的。

         

         

        在新集群中測(cè)試時(shí)不可避免的會(huì)遇到應(yīng)用更新的場(chǎng)景。如果保證應(yīng)用更新的過(guò)程中流量無(wú)損呢?

         

        應(yīng)用更新分為兩個(gè)步驟,創(chuàng)建新的 Pod,等待 Pod running 后,刪除舊的 Pod。新的 Pod 創(chuàng)建成功后,CCM 會(huì)將其掛在到 SLB 后端,如果新建的 Pod 無(wú)法提供服務(wù),那么請(qǐng)求就會(huì)失敗。因此,需要為 Pod 添加就緒檢測(cè)。僅當(dāng) Pod 可以對(duì)外服務(wù)時(shí),才將其加入到 SLB 后端。在刪除 Pod 時(shí)也會(huì)遇到同樣的場(chǎng)景。因?yàn)?Pod 刪除和從 SLB 后端移除 Pod 是異步進(jìn)行的,如果 Pod 以及刪除,但是還未從 SLB 后端移除,就會(huì)出現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)到后端,但是無(wú) Pod 處理導(dǎo)致請(qǐng)求失敗的情況。因此需要為 Pod 添加 prestop hook。

         


        Pod 優(yōu)雅退出過(guò)程如上圖所示。首先 kubelet delete pod,然后 endpoint controller 更新 endpoint。更新完畢后,kube-proxy 移除節(jié)點(diǎn)轉(zhuǎn)發(fā)規(guī)則。CCM 檢測(cè)到 endpoint 更新事件后,從 SLB 后端移除 Pod。在apiserver 刪除 Pod 時(shí),kubelet 同時(shí)開(kāi)始刪除 Pod 邏輯,觸發(fā) Pod prestop。在 prestop 結(jié)束后發(fā)送 sigterm 信息。在整個(gè) Pod 優(yōu)雅退出過(guò)程中,直到 CCM 從 SLB 后端移除 Pod 之前一直會(huì)有新的流量進(jìn)入。

         

         

        由于 CCM 與 kube-proxy 是異步進(jìn)行的,因此會(huì)出現(xiàn) SLB 還未移除 Pod,kubeproxy 已經(jīng)將節(jié)點(diǎn)轉(zhuǎn)發(fā)規(guī)則清理的情況。此時(shí),請(qǐng)求進(jìn)入 SLB 后,轉(zhuǎn)發(fā)至 Node上,由于 kube-proxy 已經(jīng)將路由規(guī)則清理了,所以該請(qǐng)求無(wú)法處理。將 service 改為 cluster 模式可以解決這一問(wèn)題。如果 Service 一定需要為 local 模式,那么需要保證一個(gè)節(jié)點(diǎn)上有多個(gè) Pod。也可以通過(guò)設(shè)置 Service 為 eni 模式解決這一問(wèn)題。


        總結(jié)來(lái)說(shuō),集群遷移可以分為如下三個(gè)步驟,前置檢查、應(yīng)用遷移及流量遷移三個(gè)步驟。前置檢查需要檢查不同集群間 api/Node label 等兼容性,應(yīng)用遷移可以使用開(kāi)源工具進(jìn)行,基于 CCM 則可以實(shí)現(xiàn)實(shí)時(shí)無(wú)損流量遷移。


        瀏覽 45
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 中文字幕av一区 青青操原 | 男女深夜福利视频 | 国产精品久久久久久久久久了 | 日韩AV中文字幕在线播放 | 久久综合88 |