istio 0.5.0 新特性:流量鏡像

在相似 Dark launch 的測試、發佈過程當中,流量複製是個很是有用的功能,istio 0.5.0 的更新,帶來了一個新的路由相關特性:流量鏡像。nginx

這一場景中,咱們會將正常的流量進行復制,將複製出來的流量分發給待上線的應用(v2),使用實際流量對新版本應用進行測試;而現有客戶端則僅會感知到單一版本(v1)的存在。api

下面作個小實驗來進行驗證。bash

條件

基於 Kubernetes 運行的 Istio 0.5.0 版本部署。微信

部署

源碼見後。markdown

nginx:stabel-alpine鏡像,生成v1v2兩個版本的 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,會看到在v1Pod 中出現了訪問跡象:

[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" "-"

  1. 語法看來,僅支持一個複製

源碼

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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索