背景
為了降低EMQX在Kubernetes上的部署、運維成本,我們将一些日常運維能力進行總結、抽象并整合到代碼中,以EMQX Kubernetes Operator的方式幫助使用者實作EMQX的自動化部署和運維。
此前,EMQX Kubernetes Operator v1beta1、v1beta2、v1beta3的更新政策均為滾動更新,相關更新流程如下:
更新流程示意圖
問題分析
滾動更新在生産環境中可能會面臨以下問題:
- 更新過程中會逐個銷毀舊的節點再建立新的節點,是以可能導緻用戶端多次斷連(最糟糕的情況下斷連次數與節點數量一緻),進而影響使用者體驗。
- 當叢集處于較高連接配接的情況下,一個節點被銷毀,那麼該節點上面的連接配接會在瞬間斷開,由用戶端重試邏輯來進行重連;當單節點連接配接數較大時,如果大量用戶端進行重連,則可能會給服務端造成壓力導緻過載。
- 更新完成後,各節點間的負載不均衡(如上圖:emqx-ee-0在更新過程中,用戶端可能會進行重連,此時由于emqx-ee-0還未就緒,是以可能連接配接到emqx-ee-1或者emqx-ee-2,更新完成後emqx-ee-0上可能隻有較少負載或者無負載),進而打破業務容量模型的規劃,可能影響到服務。
- 由于使用StatefulSets進行部署,在更新過程中提供服務的節點會比實際節點要少一個(影響到使用者的業務模型),這可能會增加服務端的一些壓力。
如果上面幾個步驟的問題疊加(多次斷連與大量斷連的用戶端不停的重試連接配接),則可能會放大用戶端重連的規模,進而造成服務端過載或雪崩。
下圖是在現有更新模式下連接配接數的監控圖(在不同的業務中會存在差異,比如後端依賴的不同資源、伺服器配置、用戶端重連或重試政策等,均會帶來一些不同的影響)。其中:
- sum:總的連接配接數,圖中最上面的一條線
- emqx-ee-a:字首表示的是更新前3個EMQX節點
- emqx-ee-b:字首表示的是更新後3個EMQX節點
在上圖中,當我們開始執行滾動更新時,首先emqx-ee-a-emqx-ee-2進行銷毀,并建立新的emqx-ee-b-emqx-ee-2,此時僅有emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0能夠提供服務,當用戶端進行重連時,LB會将流量轉移到emqx-ee-a-emqx-ee-0、emqx-ee-a-emqx-ee-1上面,是以我們能夠看到emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0有明顯的流量上升,當後面更新這兩個pod時,意味着用戶端可能多次斷連。由于新pod建立的過程存在着時間差,以上圖為例,emqx-ee-a-emqx-ee-0最後更新,當更新完成後,可能用戶端已經完成重試、重連,此時主要連接配接已經被另兩個pod接納,是以會導緻pod之間流量不均衡,進而影響到使用者業務模型的評估,或者影響到服務。
為了友善展示,我們未壓測大量連接配接模拟重連、導緻服務端過載的場景(在實際生産環境中可能遇到,TPS超過雲端規劃的容量模型),但從連接配接數監控圖上,我們依然看到一個大缺口,說明對業務産生了較大影響。是以我們需制定一種方案來規避以上幾個問題,保障更新過程中的平滑穩定。
問題解決
目标
- 更新過程中實作連接配接數可控遷移(可根據服務端處理能力設定相應的遷移速率)。
- 更新過程中減少連接配接斷開的次數(一次斷連)。
- 在整個更新的過程中始終保持預期的節點來提供服務。
- 更新完成後,不需要叢集負載重平衡,各節點間的連接配接相對均衡(與LB排程政策有一定關系)。
方案設計
藍綠釋出是一種同時運作兩個版本應用的釋出政策。EMQX Kubernetes Operator近日在2.1.0版本中實作了EMQX Enterprise的藍綠釋出,即從現有的EMQX Enterprise叢集開始,建立一套新版本的EMQX Enterpriser叢集,在這一過程中不停止掉老版本,等新版本叢集運作起來後,再将流量逐漸平滑切換到新版本上。
從4.4.12版本開始,EMQX企業版本支援節點疏散功能。節點疏散功能允許使用者在關閉節點之前強制将連接配接和會話以一定速率遷移到其他節點,以避免節點關閉帶來的會話資料丢失。
在Kubernetes上我們通過模拟藍綠釋出以及結合節點疏散功能,實作了連接配接可控遷移,極大減少了斷連的次數(僅斷連一次)。相關更新流程圖如下:
整個更新流程大緻可分為以下幾步:
- 更新時(鏡像、Pod相關資源修改調整)我們會先建立一個同規格的節點加入到現有叢集中。
- 當新節點全部就緒後,我們将service全部指向新建立的節點,此時新節點開始接受新的連接配接請求。
- 将舊節點從service中摘出,此時舊節點不再接收新的連接配接請求。
- 通過EMQX節點疏散功能,逐個對節點上的連接配接進行可控遷移,直至連接配接全部完成遷移,再對節點進行銷毀。
操作流程
節點疏散是EMQX Enterpriser 4.4.12開始支援的新特性,EMQX Kubernetes Operator在2.1版本中對該能力進行适配,如需使用該能力,請将EMQX更新到企業版v4.4.12,EMQX Kubernetes Operator更新到v2.1。
- 配置藍綠更新
apiVersion: apps.emqx.io/v1beta4
...
spec:
blueGreenUpdate:
initialDelaySeconds: 60
evacuationStrategy:
waitTakeover: 5
connEvictRate: 200
sessEvictRate: 200
...
initialDelaySeconds:所有的節點就緒後(藍綠節點),開始節點疏散前的等待時間(由于切換Service後,LoadBalancer需要時間來處理service與pod的關系)(機關:秒)
waitTakeover:所有連接配接斷開後,等待用戶端重連以接管會話的時間(機關:秒)
connEvictRate:用戶端每秒斷開連接配接速
sessEvictRate:waitTakeover之後每秒會話疏散速度
更新過程中連接配接數監控圖如下(本次測試以10萬連接配接進行):
sum:總的連接配接數,圖中最上面的一條線
emqx-ee-86d7758868:字首表示的是更新前的3個EMQX節點
emqx-ee-745858464d:字首表示更新後的3個EMQX節點
如上圖,我們通過EMQX Kubernetes Operator的藍綠釋出在Kubernetes中實作了優雅更新,通過該方案更新,總連接配接數未出現較大抖動(取決于遷移速率、服務端能夠接收的速率、用戶端重連政策等),能夠極大程度保障更新過程的平滑,有效防止服務端過載,減少業務感覺,進而提升服務的穩定性。
*注:由于更新後的叢集,三個節點負載較平均,是以上圖三條線重疊在了一起。
結語
通過采用節點疏散功能結合模拟藍綠釋出,本文所提供的方案解決了普通更新導緻的多次斷連和可能的服務過載與負載不均問題,實作了在Kubernetes上的優雅更新。
作為一個自動化管理工具,EMQX Kubernetes Operator旨在幫助使用者輕松建立和管理EMQX叢集,充分享受EMQX的強大産品能力。通過本文方案完成EMQX的更新,使用者可以進一步體驗EMQX的最新特性,建構創新物聯網應用。