採用Istio實現灰度發佈

灰度發佈(又名金絲雀發佈)介紹

當應用上線以後,運維面臨的一大挑戰是如何能夠在不影響已上線業務的情況下進行升級。做過產品的同學都清楚,不管在發佈前做過多麼完備的自動化和人工測試,在發佈後都會出現或多或少的故障。根據墨菲定律,可能會出錯的版本發佈一定會出錯。

“ANYTHING THAN CAN GO WRONG WILL GO WRONG” –MURPHY’S LAW

因此我們不能寄希望於在線下測試時發現所有潛在故障。在無法百分百避免版本升級故障的情況下,需要通過一種方式進行可控的版本發佈,把故障影響控制在可以接受的範圍內,並可以快速回退。

可以通過灰度發佈(又名金絲雀發佈)來實現業務從老版本到新版本的平滑過渡,並避免升級過程中出現的問題對用戶造成的影響。

“金絲雀發佈”的來源於礦工們用金絲雀對礦井進行空氣測試的做法。以前礦工挖煤的時候,礦工下礦井前會先把金絲雀放進去,或者挖煤的時候一直帶著金絲雀。金絲雀對甲烷和一氧化碳濃度比較敏感,會先報警。所以大家都用“金絲雀”來搞最先的測試。

下圖中,左下方的少部分用戶就被當作“金絲雀”來用於測試新上線的1.1版本。如果新版本出現問題,“金絲雀”們會報警,但不會影響其他用戶業務的正常運行。

採用Istio實現灰度發佈

灰度發佈(金絲雀發佈)的流程如下:

  • 準備和生產環境隔離的“金絲雀”服務器。
  • 將新版本的服務部署到“金絲雀”服務器上。
  • 對“金絲雀”服務器上的服務進行自動化和人工測試。
  • 測試通過後,將“金絲雀”服務器連接到生產環境,將少量生產流量導入到“金絲雀”服務器中。
  • 如果在線測試出現問題,則通過把生產流量從“金絲雀”服務器中重新路由到老版本的服務的方式進行回退,修復問題後重新進行發佈。
  • 如果在線測試順利,則逐漸把生產流量按一定策略逐漸導入到新版本服務器中。
  • 待新版本服務穩定運行後,刪除老版本服務。

Istio實現灰度發佈(金絲雀發佈)的原理

從上面的流程可以看到,如果要實現一套灰度發佈的流程,需要應用程序和運維流程對該發佈過程進行支持,工作量和難度的挑戰是非常大的。雖然面對的問題類似,但每個企業或組織一般採用不同的私有化實現方案來進行灰度發佈,為解決該問題導致研發和運維花費了大量的成本。

Istio通過高度的抽象和良好的設計採用一致的方式解決了該問題,採用sidecar對應用流量進行了轉發,通過Pilot下發路由規則,可以在不修改應用程序的前提下實現應用的灰度發佈。

備註:採用kubernetes的滾動升級(rolling update)功能也可以實現不中斷業務的應用升級,但滾動升級是通過逐漸使用新版本的服務來替換老版本服務的方式對應用進行升級,在滾動升級不能對應用的流量分發進行控制,因此無法採用受控地把生產流量逐漸導流到新版本服務中,也就無法控制服務升級對用戶造成的影響。

採用Istio後,可以通過定製路由規則將特定的流量(如指定特徵的用戶)導入新版本服務中,在生產環境下進行測試,同時通過漸進受控地導入生產流量,可以最小化升級中出現的故障對用戶的影響。並且在同時存在新老版本服務時,還可根據應用壓力對不同版本的服務進行獨立的縮擴容,非常靈活。採用Istio進行灰度發佈的流程如下圖所示:

採用Istio實現灰度發佈

操作步驟

下面採用Istion自帶的BookinfoInfo示例程序來試驗灰度發佈的流程。

測試環境安裝

首先參考手把手教你從零搭建Istio及Bookinfo示例程序安裝Kubernetes及Istio控制面。

因為本試驗並不需要安裝全部3個版本的reviews服務,因此如果已經安裝了該應用,先採用下面的命令卸載。

部署V1版本的服務

首先只部署V1版本的Bookinfo應用程序。由於示例中的yaml文件中包含了3個版本的reviews服務,我們先將V2和V3版本的Deployment從yaml文件istio-0.2.10/samples/bookinfo/kube/bookinfo.yaml中刪除。

從Bookinfo.yaml中刪除這部分內容:

部署V1版本的Bookinfo程序。

通過kubectl命令行確認pod部署,可以看到只有V1版本的服務。

在瀏覽器中打開應用程序頁面,地址為istio-ingress的External IP。由於V1版本的reviews服務並不會調用rating服務,因此可以看到Product 頁面顯示的是不帶星級的評價信息。

http://10.12.25.116/productpage

採用Istio實現灰度發佈

此時系統中微服務的部署情況如下圖所示(下面的示意圖均忽略和本例關係不大的details和ratings服務):

採用Istio實現灰度發佈

部署V2版本的reviews服務

在部署V2版本的reviews服務前,需要先創建一條缺省路由規則route-rule-default-reviews.yaml,將所有生產流量都導向V1版本,避免對線上用戶的影響。

啟用該路由規則。

創建一個V2版本的部署文件bookinfo-reviews-v2.yaml,內容如下

部署V2版本的reviews服務。

此時系統中部署了V1和V2兩個版本的reviews服務,但所有的業務流量都被規則reviews-default導向了V1,如下圖所示:

採用Istio實現灰度發佈

將測試流量導入到V2版本的reviews服務

在進行模擬測試時,由於測試環境和生產環境的網絡,服務器,操作系統等環境存在差異,很難完全模擬生產環境進行測試。為了減少環境因素的對測試結果的影響,我們希望能在生產環境中進行上線前的測試,但如果沒有很好的隔離措施,可能會導致測試影響已上線的業務,對企業造成損失。

通過採用Istio的路由規則,可以在類生產環境中進行測試,又完全隔離了線上用戶的生產流量和測試流量,最小化模擬測試對已上線業務的影響。如下圖所示:

採用Istio實現灰度發佈

創建一條規則,將用戶名為 test-user 的流量導入到V2

注意:precedence屬性用於設置規則的優先級,在同時存在多條規則的情況下,優先級高的規則將先執行。這條規則的precedence設置為2,以確保其在缺省規則之前運行,將test-user用戶的請求導流到V2版本reviews服務中。

啟用該規則。

以test-user用戶登錄,可以看到V2版本帶星級的評價頁面。

採用Istio實現灰度發佈

註銷test-user,只能看到V1版本不帶星級的評價頁面。如下圖所示:

採用Istio實現灰度發佈

將部分生產流量導入到V2版本的reviews服務

在線上模擬測試完成後,如果系統測試情況良好,可以通過規則將一部分用戶流量導入到V2版本的服務中,進行小規模的“金絲雀”測試。

修改規則route-rule-default-reviews.yaml,將50%的流量導入V2版本。

備註:本例只是描述原理,因此為簡單起見,將50%流量導入V2版本,在實際操作中,更可能是先導入較少流量,然後根據監控的新版本運行情況將流量逐漸導入,如採用5%,10%,20%,50% …的比例逐漸導入。

此時系統部署如下圖所示:

採用Istio實現灰度發佈

將所有生產流量導入到到V2版本的reviews服務

如果新版本的服務運行正常,則可以將所有流量導入到V2版本。

系統部署如下圖所示:

採用Istio實現灰度發佈

此時不管以任何用戶登錄,都只能看到V2版本帶星級的評價頁面,如下圖所示:

採用Istio實現灰度發佈

備註:如果灰度發佈的過程中新版本的服務出現問題,則可以通過修改路由規則,將流量重新導入到V1版本的服務中,將V2版本故障修復後再進行測試。

刪除V1版本的reviews服務

待V2版本上線穩定運行後,刪除V1版本的reviews服務和測試規則。


分享到:


相關文章: