您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么采用Istio實現灰度發布,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
灰度發布(又名金絲雀發布)介紹
當應用上線以后,運維面臨的一大挑戰是如何能夠在不影響已上線業務的情況下進行升級。做過產品的同學都清楚,不管在發布前做過多么完備的自動化和人工測試,在發布后都會出現或多或少的故障。根據墨菲定律,可能會出錯的版本發布一定會出錯。
“ANYTHING THAN CAN GO WRONG WILL GO WRONG” –MURPHY’S LAW
因此我們不能寄希望于在線下測試時發現所有潛在故障。在無法百分百避免版本升級故障的情況下,需要通過一種方式進行可控的版本發布,把故障影響控制在可以接受的范圍內,并可以快速回退。
可以通過灰度發布(又名金絲雀發布)來實現業務從老版本到新版本的平滑過渡,并避免升級過程中出現的問題對用戶造成的影響。
“金絲雀發布”的來源于礦工們用金絲雀對礦井進行空氣測試的做法。以前礦工挖煤的時候,礦工下礦井前會先把金絲雀放進去,或者挖煤的時候一直帶著金絲雀。金絲雀對甲烷和一氧化碳濃度比較敏感,會先報警。所以大家都用“金絲雀”來搞最先的測試。
下圖中,左下方的少部分用戶就被當作“金絲雀”來用于測試新上線的1.1版本。如果新版本出現問題,“金絲雀”們會報警,但不會影響其他用戶業務的正常運行。
灰度發布(金絲雀發布)的流程如下:
準備和生產環境隔離的“金絲雀”服務器。
將新版本的服務部署到“金絲雀”服務器上。
對“金絲雀”服務器上的服務進行自動化和人工測試。
測試通過后,將“金絲雀”服務器連接到生產環境,將少量生產流量導入到“金絲雀”服務器中。
如果在線測試出現問題,則通過把生產流量從“金絲雀”服務器中重新路由到老版本的服務的方式進行回退,修復問題后重新進行發布。
如果在線測試順利,則逐漸把生產流量按一定策略逐漸導入到新版本服務器中。
待新版本服務穩定運行后,刪除老版本服務。
從上面的流程可以看到,如果要實現一套灰度發布的流程,需要應用程序和運維流程對該發布過程進行支持,工作量和難度的挑戰是非常大的。雖然面對的問題類似,但每個企業或組織一般采用不同的私有化實現方案來進行灰度發布,為解決該問題導致研發和運維花費了大量的成本。
Istio通過高度的抽象和良好的設計采用一致的方式解決了該問題,采用sidecar對應用流量進行了轉發,通過Pilot下發路由規則,可以在不修改應用程序的前提下實現應用的灰度發布。
備注:采用kubernetes的滾動升級(rolling update)功能也可以實現不中斷業務的應用升級,但滾動升級是通過逐漸使用新版本的服務來替換老版本服務的方式對應用進行升級,在滾動升級不能對應用的流量分發進行控制,因此無法采用受控地把生產流量逐漸導流到新版本服務中,也就無法控制服務升級對用戶造成的影響。
采用Istio后,可以通過定制路由規則將特定的流量(如指定特征的用戶)導入新版本服務中,在生產環境下進行測試,同時通過漸進受控地導入生產流量,可以最小化升級中出現的故障對用戶的影響。并且在同時存在新老版本服務時,還可根據應用壓力對不同版本的服務進行獨立的縮擴容,非常靈活。采用Istio進行灰度發布的流程如下圖所示:
下面采用Istion自帶的BookinfoInfo示例程序來試驗灰度發布的流程。
首先參考手把手教你從零搭建Istio及Bookinfo示例程序安裝Kubernetes及Istio控制面。
因為本試驗并不需要安裝全部3個版本的reviews服務,因此如果已經安裝了該應用,先采用下面的命令卸載。
istio-0.2.10/samples/bookinfo/kube/cleanup.sh
首先只部署V1版本的Bookinfo應用程序。由于示例中的yaml文件中包含了3個版本的reviews服務,我們先將V2和V3版本的Deployment從yaml文件istio-0.2.10/samples/bookinfo/kube/bookinfo.yaml中刪除。
從Bookinfo.yaml中刪除這部分內容:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v2 spec: replicas: 1 template: metadata: labels: app: reviews version: v2 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v2:0.2.3 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v3 spec: replicas: 1 template: metadata: labels: app: reviews version: v3 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v3:0.2.3 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 ---
部署V1版本的Bookinfo程序。
kubectl apply -f <(istioctl kube-inject -f istio-0.2.10/samples/bookinfo/kube/bookinfo.yaml)
通過kubectl命令行確認pod部署,可以看到只有V1版本的服務。
kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-3688945616-nhkqk 2/2 Running 0 2m productpage-v1-2055622944-m3fql 2/2 Running 0 2m ratings-v1-233971408-0f3s9 2/2 Running 0 2m reviews-v1-1360980140-0zs9z 2/2 Running 0 2m
在瀏覽器中打開應用程序頁面,地址為istio-ingress的External IP。由于V1版本的reviews服務并不會調用rating服務,因此可以看到Product 頁面顯示的是不帶星級的評價信息。
http://10.12.25.116/productpage
此時系統中微服務的部署情況如下圖所示(下面的示意圖均忽略和本例關系不大的details和ratings服務):
在部署V2版本的reviews服務前,需要先創建一條缺省路由規則route-rule-default-reviews.yaml,將所有生產流量都導向V1版本,避免對線上用戶的影響。
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-default spec: destination: name: reviews precedence: 1 route: - labels: version: v1
啟用該路由規則。
istioctl create -f route-rule-default-reviews.yaml -n default
創建一個V2版本的部署文件bookinfo-reviews-v2.yaml,內容如下
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: reviews-v2 spec: replicas: 1 template: metadata: labels: app: reviews version: v2 spec: containers: - name: reviews image: istio/examples-bookinfo-reviews-v2:0.2.3 imagePullPolicy: IfNotPresent ports: - containerPort: 9080
部署V2版本的reviews服務。
kubectl apply -f <(istioctl kube-inject -f bookinfo-reviews-v2.yaml)
此時系統中部署了V1和V2兩個版本的reviews服務,但所有的業務流量都被規則reviews-default導向了V1,如下圖所示:
在進行模擬測試時,由于測試環境和生產環境的網絡,服務器,操作系統等環境存在差異,很難完全模擬生產環境進行測試。為了減少環境因素的對測試結果的影響,我們希望能在生產環境中進行上線前的測試,但如果沒有很好的隔離措施,可能會導致測試影響已上線的業務,對企業造成損失。
通過采用Istio的路由規則,可以在類生產環境中進行測試,又完全隔離了線上用戶的生產流量和測試流量,最小化模擬測試對已上線業務的影響。如下圖所示:
創建一條規則,將用戶名為 test-user 的流量導入到V2
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-test-user spec: destination: name: reviews precedence: 2 match: request: headers: cookie: regex: "^(.*?;)?(user=test-user)(;.*)?$" route: - labels: version: v2
注意:precedence屬性用于設置規則的優先級,在同時存在多條規則的情況下,優先級高的規則將先執行。這條規則的precedence設置為2,以確保其在缺省規則之前運行,將test-user用戶的請求導流到V2版本reviews服務中。
啟用該規則。
istioctl create -f route-rule-test-reviews-v2.yaml -n default
以test-user用戶登錄,可以看到V2版本帶星級的評價頁面。
注銷test-user,只能看到V1版本不帶星級的評價頁面。如下圖所示:
在線上模擬測試完成后,如果系統測試情況良好,可以通過規則將一部分用戶流量導入到V2版本的服務中,進行小規模的“金絲雀”測試。
修改規則route-rule-default-reviews.yaml,將50%的流量導入V2版本。
備注:本例只是描述原理,因此為簡單起見,將50%流量導入V2版本,在實際操作中,更可能是先導入較少流量,然后根據監控的新版本運行情況將流量逐漸導入,如采用5%,10%,20%,50% …的比例逐漸導入。
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-default spec: destination: name: reviews precedence: 1 route: - labels: version: v1 weight: 50 - labels: version: v2 weight: 50
istioctl replace -f route-rule-default-reviews.yaml -n default
此時系統部署如下圖所示:
如果新版本的服務運行正常,則可以將所有流量導入到V2版本。
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: reviews-default spec: destination: name: reviews precedence: 1 route: - labels: version: v2 weight: 100
istioctl replace -f route-rule-default-reviews.yaml -n default
系統部署如下圖所示:
備注:如果灰度發布的過程中新版本的服務出現問題,則可以通過修改路由規則,將流量重新導入到V1版本的服務中,將V2版本故障修復后再進行測試。
待V2版本上線穩定運行后,刪除V1版本的reviews服務和測試規則。
kubectl delete pod reviews-v1-1360980140-0zs9z istioctl delete -f route-rule-test-reviews-v2.yaml -n default
上述內容就是怎么采用Istio實現灰度發布,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。