在相似 Dark launch 的測試、發佈過程當中,流量複製是個很是有用的功能,istio 0.5.0 的更新,帶來了一個新的路由相關特性:流量鏡像。nginx
這一場景中,咱們會將正常的流量進行復制,將複製出來的流量分發給待上線的應用(v2),使用實際流量對新版本應用進行測試;而現有客戶端則僅會感知到單一版本(v1)的存在。api
下面作個小實驗來進行驗證。bash
條件
基於 Kubernetes 運行的 Istio 0.5.0 版本部署。微信
部署
源碼見後。markdown
用nginx:stabel-alpine
鏡像,生成v1
和v2
兩個版本的 Deployment,以及一個target
服務:架構
istioctl kube-inject -f v1.deploy.yaml| kubectl apply -f - istioctl kube-inject -f v2.deploy.yaml| kubectl apply -f - kubectl apply -f service.yaml
用dustise/sleep
鏡像做爲客戶端服務,來製造請求訪問目標服務。app
istioctl kube-inject -f sleep.yaml| kubectl apply -f -
使用kubectl get po
驗證 Pod 生成狀況,就緒以後開始進行驗證。ssh
NAME READY STATUS RESTARTS AGE sleep-6f569f4c9-hs6wx 2/2 Running 0 10m target-v1-7f78d974c-mfhzz 2/2 Running 0 1h target-v2-5886cd585d-tr22d 2/2 Running 0 1h
驗證
初始化
首先咱們生成一個缺省路由,將所有流量引入 v1:curl
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: rule-all-http spec: destination: name: target precedence: 1 route: - labels: app: target version: v1 weight: 100
使用kubectl apply -f rules.yaml
應用這一規則。工具
接下來監控 nginx 的訪問日誌:
kubectl logs -f [v1-pod] -c nginx kubectl logs -f [v2-pod] -c nginx
或者可使用
kubetail
工具:kubetail target -c nginx
,對部署內容的日誌進行監控。
kubectl exec -it [sleep-pod] -c sleep bash
進入客戶端服務 Pod,執行curl http://target
,會看到在v1
Pod 中出現了訪問跡象:
[target-v1-7f78d974c-mfhzz] 127.0.0.1 - - [12/Feb/2018:15:28:30 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "-" [target-v1-7f78d974c-mfhzz] 127.0.0.1 - - [12/Feb/2018:15:28:31 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "-" [target-v1-7f78d974c-mfhzz] 127.0.0.1 - - [12/Feb/2018:15:28:32 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "-"
開始鏡像
修改路由規則:
apiVersion: config.istio.io/v1alpha2 kind: RouteRule metadata: name: rule-all-http spec: destination: name: target precedence: 1 route: - labels: app: target version: v1 weight: 100 - labels: app: target version: v2 weight: 0 mirror: name: target labels: app: target version: v2
注意這裏爲v2
創建了一個權重爲0
的路由項,這是一個硬性規定,啓用mirror
的路由必需要在上面的route
中具有一致的入口,以此通知 Envoy 進行相應的數據面操做。
使用kubectl apply -f rules.yaml
來更新路由規則。
再次在客戶端 Pod 中訪問target
服務,會發現兩個版本的 Pod 中都出現了訪問日誌,而且數量上是一一對應的:
[target-v2-5886cd585d-tr22d] 127.0.0.1 - - [12/Feb/2018:15:20:16 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "10.240 .0.29" [target-v1-7f78d974c-mfhzz] 127.0.0.1 - - [12/Feb/2018:15:20:16 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "-" [target-v2-5886cd585d-tr22d] 127.0.0.1 - - [12/Feb/2018:15:20:17 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "10.240 .0.29" [target-v1-7f78d974c-mfhzz] 127.0.0.1 - - [12/Feb/2018:15:20:17 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.38.0" "-"
注
- 語法看來,僅支持一個複製
源碼
v1.deploy.yaml
將v1
替換成v2
生成另一個部署。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: target-v1 spec: replicas: 1 template: metadata: labels: app: target version: v1 spec: containers: - image: nginx:stable-alpine imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80
sleep.yaml
apiVersion: v1 kind: Service metadata: name: target labels: app: target spec: ports: - name: http port: 80 selector: app: target
sleep.yaml
apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep version: v1 spec: selector: app: sleep version: v1 ports: - name: ssh port: 80 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: sleep spec: replicas: 1 template: metadata: labels: app: sleep version: v1 spec: containers: - name: sleep image: dustise/sleep imagePullPolicy: IfNotPresent ---
本文分享自微信公衆號 - 僞架構師(fake-architect)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。