1. 程式人生 > >乾貨|採用Istio實現灰度釋出(金絲雀釋出)

乾貨|採用Istio實現灰度釋出(金絲雀釋出)

點選上方“中興開發者社群”,關注我們

每天讀一篇一線開發者原創好文640?wx_fmt=png&wxfrom=5&wx_lazy=1

灰度釋出(又名金絲雀釋出)介紹

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

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

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

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

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

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

640?wx_fmt=png&wxfrom=5&wx_lazy=1

灰度釋出(金絲雀釋出)的流程如下:

  • 準備和生產環境隔離的“金絲雀”伺服器。

  • 將新版本的服務部署到“金絲雀”伺服器上。

  • 對“金絲雀”伺服器上的服務進行自動化和人工測試。

  • 測試通過後,將“金絲雀”伺服器連線到生產環境,將少量生產流量匯入到“金絲雀”伺服器中。

  • 如果線上測試出現問題,則通過把生產流量從“金絲雀”伺服器中重新路由到老版本的服務的方式進行回退,修復問題後重新進行釋出。

  • 如果線上測試順利,則逐漸把生產流量按一定策略逐漸匯入到新版本伺服器中。

  • 待新版本服務穩定執行後,刪除老版本服務。

Istio實現灰度釋出(金絲雀釋出)的原理

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

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

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

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

0?wx_fmt=png

操作步驟

下面採用Istion自帶的BookinfoInfo示例程式來試驗灰度釋出的流程。

測試環境安裝

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

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

istio-0.2.10/samples/bookinfo/kube/cleanup.sh

部署V1版本的服務

首先只部署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

0?wx_fmt=png

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

0?wx_fmt=png

部署V2版本的reviews服務

在部署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,如下圖所示:

0?wx_fmt=png

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

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

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

0?wx_fmt=png

建立一條規則,將使用者名稱為 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版本帶星級的評價頁面。

0?wx_fmt=png登出test-user,只能看到V1版本不帶星級的評價頁面。如下圖所示:0?wx_fmt=png

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

在線上模擬測試完成後,如果系統測試情況良好,可以通過規則將一部分使用者流量匯入到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

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

0?wx_fmt=png

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

如果新版本的服務執行正常,則可以將所有流量匯入到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

系統部署如下圖所示:

0?wx_fmt=png

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

0?wx_fmt=png

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

刪除V1版本的reviews服務

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

kubectl delete pod reviews-v1-1360980140-0zs9z

istioctl delete -f route-rule-test-reviews-v2.yaml -n default

參考

  • Istio官方文件

推薦閱讀

640?wx_fmt=jpeg

相關推薦

乾貨採用Istio實現釋出(金絲雀釋出)

點選上方“中興開發者社群”,關注我們 每天讀一篇一線開發者原創好文 灰度釋出(又名金絲雀釋出)介紹 當應用上線以後,運維面臨的一大挑戰是如何能夠在不影響已上線業務的情況下進行升級。做過產品的同

採用輕量ServiceMesh實現釋出的實踐

軟體總會有缺陷的,解決問題的同時往往會引入新的問題,關鍵是看這些問題是否在我們的控制範圍內,“灰度釋出”就是讓問題受控的方法之一。    前言    我們的 CTO 經常說:“研發團隊最首要的任務是提供穩定的服務,然後才是提供符合客戶需求的、易用和低成本的產品”

Istio 太複雜?KubeSphere基於Ingress-Nginx實現釋出

在 Bookinfo 微服務的灰度釋出示例 中,KubeSphere 基於 Istio 對 Bookinfo 微服務示例應用實現了

Openresty+redis實現釋出

一、架構 環境: 192.168.189.131:tomcat服務 192.168.189.132:tomcat服務 192.168.189.130:OpenResty服務、redis服務 流程: 請求到達openresty,openresty從redis獲取白名單,然後判斷請求地址是否再白名單,

Apollo學習(四):建立配置並與zuul協作實現釋出

說明 通過之前對Apollo的學習,對Apollo的使用已經有了大概的瞭解。本篇博文通過與Spring Cloud Zuul作為閘道器配合,Apollo配置灰度例項來學習灰度釋出。本文的核心是以github上的灰度釋出開源專案ribbon-discovery-filter-sprin

利用nginx+lua+memcache實現釋出

一、灰度釋出原理說明 灰度釋出在百度百科中解釋: 灰度釋出是指在黑與白之間,能夠平滑過渡的一種釋出方式。AB test就是一種灰度釋出方式,讓一部分使用者繼續用A,一部分使用者開始用B,如果使用者對B沒有什麼反對意見,那麼逐步擴大範圍,把所有使用者都遷移到B上面 來。灰度釋出可以保證整體系統的穩定,在初

K8S基於ingress-nginx實現釋出

之前介紹過使用ambassador實現灰度釋出,今天介紹如何使用ingre-nginx實現。 介紹 Ingress-Nginx 是一個K8S ingress工具,支援配置 Ingress Annotations 來實現不同場景下的灰度釋出和測試。 Nginx Annotations 支援以下 4 種 Cana

架構設計:微服務模式下,實現釋出模式

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent) # 一、基本邏輯 請求通過8001

vs2015+opencv3.3.1 實現 高斯濾波器

3.3 edwin ont eight end wid img pre i++ #include <opencv2\highgui\highgui.hpp> #include <iostream> #include<vector> u

otsu結合OpenCV實現影象自動閾值處理

   簡單的說,這種演算法假設一副影象由前景色和背景色組成,通過統計學的方法來選取一個閾值,使得這個閾值可以將前景色和背景色儘可能的分開。 或者更準確的說是在某種判據下最優。與數理統計領域的 fisher 線性判別演算法其實是等價的。 otsu演算法中這個判據就是最大類間方差

Python中使用PIL快速實現

效果 原圖 效果圖 實現 新建資料夾grayImage,在此資料夾下新建gray.py from PIL import Image img=Image.open('1111.jpg') img=img.convert('L') img.save('灰度圖.jpg')

釋出(金絲雀釋出)

Gmail Labs是一個新特性櫥窗,使用者可以自己選擇一些未正式釋出的新特性進行體驗,不喜歡可以關閉,在這個過程中,吃了螃蟹,也當了Google的小白鼠。這個做法比傳統的灰度要高明很多,更加尊重使用者:1、它沒有強加使用者,使用者是否願意當小白鼠完全自願2、新特性不是打包在

C#RBG影象轉影象與影象反轉

我們將RBG影象轉灰度影象的方法寫成一個函式的形式,輸入為Bitmap格式的影象和影象的長和寬,輸出為byte型的陣列。 根據YUV的顏色空間中,Y的分量的物理意義是點的亮點,由該值反映亮點等級,根據RBG和YUV顏色控制元件的變換關係可建立亮度Y與R、G、B

Istio Routing 實踐掌握virtualservice/gateway/destinationrule/AB版本釋出/金絲雀釋出

[原文](https://medium.com/google-cloud/istio-routing-basics-14feab3c040e) 在學習像 Istio 這樣的新技術時,看一下示例應用程式總是一個好主意。 Istio repo 有一些示例應用程式,但它們似乎有各種不足。 文件中的 BookInf

釋出系統的實現

                灰度釋出,已經不是一個很新的概念了.一個產品,如果需要快速迭代開發上線,又要保證質量,保證剛上線的系統,一旦出現問題那麼可以很快的控制影響面,就需要設計一套灰度釋出系統.灰度釋出系統的作用在於,可以根據自己的配置,來將使用者的流量導到新上線的系統上,來快速驗證新的功能修改,而一

Linkerd + Namerd,實現Kubernetes 叢集的釋出_Kubernetes中文社群

主要內容源於 https://blog.buoyant.io/2016/11/04/a-service-mesh-for-kubernetes-part-iv-continuous-deployment-via-traffic-shifting/ ,砍掉了 Jenkins 等附加部分,更換了更

zuul釋出功能實現

灰度釋出、藍綠髮布、金絲雀釋出各是什麼意思,可以看這篇http://www.appadhoc.com/blog/product-release-strategy/。基於eureka、ribbon實現灰度釋出,是這一篇要講的知識。我們要釋出版本了,在不確定正確性的情況下,我們選

釋出-基於nginx的cookie實現

1、概念 灰度釋出是指在黑與白之間,能夠平滑過渡的一種釋出方式。AB test就是一種灰度釋出方式,讓一部分使用者繼續用A,一部分使用者開始用B,如果使用者對B沒有什麼反對意見,那麼逐步擴大範圍,把所有使用者都遷移到B上面來。灰度釋出可以保證整體系統的穩

Istio最佳實踐:在K8s上通過Istio服務網格進行釋出

Istio是什麼? Istio是Google繼Kubernetes之後的又一開源力作,主要參與的公司包括Google,IBM,Lyft等公司。它提供了完整的非侵入式的微服務治理解決方案,包含微服務的管理、網路連線以及安全管理等關鍵能力,無需修改任何程式碼就能夠實現微服務的負

Linkerd + Namerd,實現Kubernetes 叢集的釋出

主要內容源於 https://blog.buoyant.io/2016/11/04/a-service-mesh-for-kubernetes-part-iv-continuous-deployment-via-traffic-shifting/ ,砍掉了 Jenkin