上一篇我們學到如何使用 Istio 輕鬆完成 Canary Deployment,本篇會介紹另一個部署策略 A/B Testing,並且同樣使用 Istio 來實現看看。
應該有聽聞過 Facebook 偶而看到的 GUI 跟平常不一樣,或是 Youtube 播放連續 10 多個廣告的情況,這些應用程式其實就是在做 A/B Testing。使用 A/B Testing 時會先將不同版本的應用程式先部署到正式環境,接著透過特定條件 (Ex: 瀏覽器、Cookie、帳號、語言) 挑選出特定使用者,將他們的流量導入到不同版本,並蒐集在不同版本下的使用數據,像是使用者瀏覽的時間是否延長、點擊次數是否變多,透過 A/B Testing 我們就能搜集不同版本下的使用者行為,藉此決定出更好的商業策略。
抽樣特定使用者,將他們的應用程式流量導入不同的版本,並觀察其行為,藉以蒐集版本數據,決定商業策略。
本篇實現 A/B Testing 的方式是使用 Virtual Service
的 HTTPMatchRequest 功能,可以根據不同的 HTTP Request 決定流量要轉到哪個版本,本次實驗會去檢查 HTTP Header 裡的使用者名稱是否包含 ironman
字串,有的話轉傳到 v3 版本(紅星星),沒有的話則轉傳到 v2 版本(黑星星),至於要怎麼做,就讓我們繼續看下去吧!
實驗概念圖,根據 User 的名稱來執行 A/B Tesing
請先參考 Day10 - 準備 Istio 實驗環境 的教學,將 Istio 及 Bookinfo Application 環境準備好,接著就可以依照以下步驟實現 A/B Testing。
destination-rule.yaml
檔案,將 Pod 根據 Label 分群apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
kubectl apply -f destination-rule.yaml
kubectl get destinationRule
(輸出結果)
NAME HOST AGE
reviews reviews 177m
接著要如何使用 VirtualService
將流量分流呢?可以在 Yaml 設定 match HTTP 封包的規則,在這裡是設置當 header 存在 end-user: 包含 ironman 的字串
就會將流量傳至 v3,反之則會傳送至 v2。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
regex: .*ironman.*
route:
- destination:
host: reviews
subset: v3
- route:
- destination:
host: reviews
subset: v2
正規表達式(regex) 可以描述符合語法資格的字串,而
.*ironman.*
代表只要字串包含ironman
及符合語法
kubectl apply -f virtual-service.yaml
kubectl get virtualService
(輸出結果)
NAME GATEWAYS HOSTS AGE
reviews ["reviews"] 178m
kubectl port-forward
將流量轉入應用程式kubectl port-forward svc/productpage 8080:9080
# 在瀏覽器輸入
http://127.0.0.1:8080/productpage
剛進入到應用程式畫面,會發現看到的是 V2 版本,嘗試看看使用右上角的登入按鍵,輸入不包含 ironman
的名稱及任意密碼後按登入。
Sign in
-> 輸入完資料後登入可以觀察到 Reviews 部分顯示的還是 v2 版本。
接著我們登出此使用者帳號,再次點擊右上角的登入按鍵,這次輸入包含 ironman
的名稱及任意密碼後按登入。
Sign in
-> 輸入完資料後登入使用者名稱若包含 ironman
,就可以成功觀察到 Reviews 顯示的為 v3 版本,這樣我們的 A/B Testing 就成功了。
經過兩篇部署策略介紹,相信各位能對 Istio 有進一步的認識。這裡要強調一個重點,如果沒有 Istio 還是有其他方法可以完成 Canary Deployment
及 A/B Testing
,但有了 Istio 你就能輕鬆的做到各式部署策略,只需設定好 Yaml 檔案,不需修改 Application 即可實現。
請問一下
- match:
- headers:
end-user:
regex: .*ironman.*
這邊是不是 Application 的程式碼要做調整,在 Header 裡面放 end-user 才行?
我從範例 Pod 查看 Log 可以看到請求裡有 end-user ironman 字樣
但想確認下就找了一台 WordPress 在登入後,查看請求 Log 裡沒有 end-user
是否得進行程式碼調整,送出請求時加入 end-user
在 Productpage Application 有實作把原本放在 session 裡的 user 資料放入 end-user
headers 中
https://github.com/istio/istio/blob/master/samples/bookinfo/src/productpage/productpage.py#L176
if 'user' in session:
headers['end-user'] = session['user']
Istio 的範例 Code 已經幫你實作好這層邏輯了,若想開發自己的應用也可以參考同樣的方式
了解了,謝謝您的回覆