基于集群內(nèi)服務層使用流量鏡像
流量鏡像功能可以將生產(chǎn)的流量鏡像拷貝到測試集群或者新的測試版本中,在不影響實際生產(chǎn)環(huán)境的情況下,測試具有實際生產(chǎn)流量的服務,幫助您減低版本變更的風險。本文介紹什么是流量鏡像,以及如何基于集群內(nèi)服務層使用流量鏡像。
什么是流量鏡像?
微服務能夠幫助用戶快速地開發(fā)和部署應用,但版本變更中也存在一定風險。服務網(wǎng)格ASM提供流量鏡像(Traffic Mirroring)的功能,也稱影子流量(Traffic Shadowing)。該功能將實時流量的副本發(fā)送到鏡像服務,而鏡像流量發(fā)生在主服務的關(guān)鍵請求路徑之外。當流量被鏡像時,請求將通過其主機或授權(quán)報頭發(fā)送到鏡像服務添加“–shadow”標記,用以區(qū)分流量從何處被鏡像到何處。流量鏡像功能可以將生產(chǎn)的流量鏡像拷貝到測試集群或者新的測試版本中,在引導實時流量之前進行測試,有效地降低版本變更的風險。
功能優(yōu)勢
優(yōu)勢 | 說明 |
測試環(huán)境更加真實,版本部署風險更低。 | 流量鏡像功能可以將生產(chǎn)的流量鏡像拷貝到測試集群或者新的測試版本中,利用實時生產(chǎn)用例和流量進行測試,使得測試服務環(huán)境更加真實,測試結(jié)果更加準確,幫助您降低生產(chǎn)環(huán)境部署的風險。 |
不影響實際生產(chǎn)環(huán)境。 |
|
適用場景
流量鏡像可以在不影響最終客戶端的情況下,測試具有實際生產(chǎn)流量的服務。您可以使用流量鏡像功能,驗證新版本是否能夠以相同的方式處理真正的各種傳入請求、在同一服務的兩個版本之間進行比較基準測試等。
下面介紹幾種典型的應用場景,幫助您發(fā)揮流量鏡像的優(yōu)勢。
應用場景 | 說明 |
線上流量模擬和測試 | 測試集群的測試可以使用生產(chǎn)實例真實流量,不會影響正常生產(chǎn)的關(guān)鍵路徑。例如,用新系統(tǒng)替換老舊系統(tǒng)或者系統(tǒng)經(jīng)歷大規(guī)模改造時,您可以將線上流量導入新系統(tǒng),進行試運行;對于一些實驗性的架構(gòu)調(diào)整,您也可以通過線上流量進行模擬測試。 |
新版本校驗 | 您可以實時對比生產(chǎn)流量和鏡像流量的輸出結(jié)果。由于是全樣本的模擬,影子流量可以應用于新服務的預上線演練。傳統(tǒng)的手工測試本身是一種樣本化的行為,通過導入真實流量形態(tài),可以完整地模擬線上的所有情況,例如異常的特殊字符、帶惡意攻擊的Token等,幫助您探測預發(fā)布服務最真實的處理能力和對異常的處理能力。 |
隔離測試數(shù)據(jù)庫 | 與數(shù)據(jù)處理相關(guān)的業(yè)務,可以使用空的數(shù)據(jù)存儲并加載測試數(shù)據(jù)。針對該數(shù)據(jù)進行鏡像流量操作,實現(xiàn)測試數(shù)據(jù)的隔離。 |
線上問題排查和臨時的數(shù)據(jù)采集 | 對于一些線上突發(fā)性問題,在線下流量總是無法復現(xiàn),此時您可以臨時開啟一個分支服務,導入影子流量進行調(diào)試和排查。采用此方式,不影響線上服務。 |
日志行為采集 | 對于推薦系統(tǒng)和算法來說,樣本和數(shù)據(jù)非常核心。傳統(tǒng)的自動化測試在算法類的應用面臨的最大挑戰(zhàn)是無法構(gòu)建真實環(huán)境的用戶行為數(shù)據(jù)。通過影子流量可以將用戶行為以日志的形式保存起來,既可以為推薦系統(tǒng)和算法模型構(gòu)建模擬測試樣本數(shù)據(jù),也可以作為后續(xù)大數(shù)據(jù)分析用戶畫像的數(shù)據(jù)來源再應用到推薦服務中。 |
啟用流量鏡像示例代碼
使用Istio啟用流量鏡像的YAML示例如下。YAML示例中,VirtualService將100%的流量路由到v1子集,同時將相同的流量鏡像到v1-mirroring子集。發(fā)送給v1子集的相同請求將被復制并觸發(fā)v1-mirroring子集。
當v1-mirroring將一些請求發(fā)送到應用程序的v1版本時,您可以查看應用程序的日志。調(diào)用應用程序時,獲得的響應來自v1子集。您還可以看到請求鏡像到v1-mirroring子集。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-traffic-mirroring
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp.default.svc.cluster.local
port:
number: 8000
subset: v1
weight: 100
mirror:
host: myapp.default.svc.cluster.local
port:
number: 8000
subset: v1-mirroring
集群內(nèi)使用流量鏡像流程介紹
本文示例將所有流量分配到v1版本,然后使用規(guī)則將流量鏡像到v1-mirroring版本。
步驟一:配置并啟動示例應用服務
使用以下內(nèi)容,創(chuàng)建httpbin.yaml文件。
apiVersion: v1 kind: ServiceAccount metadata: name: httpbin --- apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin service: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1 spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-v1-mirroring spec: replicas: 1 selector: matchLabels: app: httpbin version: v1-mirroring template: metadata: labels: app: httpbin version: v1-mirroring spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80
執(zhí)行以下命令,部署v1和v1-mirroring兩個版本的
httpbin
服務。kubectl apply -f httpbin.yaml
使用以下內(nèi)容,創(chuàng)建sleep.yaml文件。
apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep service: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep spec: replicas: 1 selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: terminationGracePeriodSeconds: 0 serviceAccountName: sleep containers: - name: sleep image: curlimages/curl command: ["/bin/sleep", "infinity"] imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /etc/sleep/tls name: secret-volume volumes: - name: secret-volume secret: secretName: sleep-secret optional: true ---
執(zhí)行以下命令,部署一個客戶端應用
sleep
服務。kubectl apply -f httpbin.yaml
步驟二:創(chuàng)建路由策略
創(chuàng)建目標規(guī)則,定義v1和v1-mirroring兩個版本。
登錄ASM控制臺,在左側(cè)導航欄,選擇 。
在網(wǎng)格管理頁面,單擊目標實例名稱,然后在左側(cè)導航欄,選擇 ,然后單擊創(chuàng)建。
在創(chuàng)建頁面,進行如下配置,然后單擊創(chuàng)建。
創(chuàng)建新的虛擬服務路由策略。將100%流量導入到v1版,同時將流量鏡像到v1-mirroring服務。
在網(wǎng)格詳情頁面左側(cè)導航欄,選擇 。
在虛擬服務頁面,單擊創(chuàng)建,進行如下配置,然后單擊創(chuàng)建。
步驟三:發(fā)送流量請求
等待應用服務運行正常之后,執(zhí)行以下命令,通過
sleep
應用向httpbin
服務發(fā)送一些流量。export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) kubectl exec -it $SLEEP_POD -c sleep -- curl http://httpbin:8000/headers
查看v1和v1-mirroring版本的Pod日志。具體操作,請參見檢查Pod的日志。
日志顯示,v1和v1-mirroring版本的Pod中有上述請求流量訪問的記錄,表明100%的流量被發(fā)送到v1版本的同時,也有50%的流量被鏡像到v1-mirroring的Pod中,符合上述定義的鏡像策略。
如下圖所示,對比v1和v1-mirroring版本的日志,可以看到在v1的流量被鏡像到了v1-mirroring。日志中的v1-mirroring報文比v1大,是因為流量被標記為影子流量,且在
authority
結(jié)果中影子流量自動補加了-shadow
。