金絲雀部署:在發佈新版本時,部署的新版本並不對外開放,而選擇一小部分用戶爲測試目標,這部分用戶對服務的訪問會指向特定的版本,經過對這些金絲雀用戶的使用狀況的觀察,來肯定新版本服務的發佈效果,在肯定結果以前,全部其餘用戶都繼續使用原有版本。html
cat flaskapp-default-vs-canary.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: flaskapp spec: hosts: - flaskapp.default.svc.cluster.local http: - match: - headers: lab: exact: canary route: - destination: host: flaskapp.default.svc.cluster.local subset: v2 - route: - destination: host: flaskapp.default.svc.cluster.local subset: v1
http header
, 還包含 uri
, scheme
, method
, authority
, 端口
, 來源標籤
及 gateway
等;bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version lab:canary ; done
cat flaskapp-default-vs-src.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: flaskapp spec: hosts: - flaskapp.default.svc.cluster.local http: - match: - sourceLabels: app: sleep version: v1 route: - destination: host: flaskapp.default.svc.cluster.local subset: v1 - route: - destination: host: flaskapp.default.svc.cluster.local subset: v2 # 應用 kubectl apply -f flaskapp-default-vs-src.yaml
# 驗證 # sleep v1 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') /bin/bash bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version; done # sleep v2 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') /bin/bash bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version; done
cat flaskapp-default-vs-uri.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: flaskapp spec: hosts: - flaskapp.default.svc.cluster.local http: - match: - sourceLabels: app: sleep version: v1 uri: exact: "/env/HOSTNAME" redirect: uri: "/env/version" - route: - destination: host: flaskapp.default.svc.cluster.local subset: v2 # 應用 kubectl apply -f flaskapp-default-vs-uri.yaml
# 驗證 sleep v2,正常返回 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') -- \ http http://flaskapp.default/env/HOSTNAME HTTP/1.1 200 OK content-length: 28 content-type: text/html; charset=utf-8 date: Wed, 12 Jun 2019 08:05:25 GMT server: envoy x-envoy-upstream-service-time: 1 flaskapp-v2-59b5b6cb94-jdfp4 # 驗證 sleep v1 # 返回 "301" 重定向代碼 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') -- \ http http://flaskapp.default/env/HOSTNAME HTTP/1.1 301 Moved Permanently content-length: 0 date: Wed, 12 Jun 2019 08:06:17 GMT location: http://flaskapp.default/ev/version server: envoy # "--follow" 跟隨重定向指令,重驗證 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') -- \ http --follow http://flaskapp.default/env/HOSTNAME HTTP/1.1 200 OK content-length: 2 content-type: text/html; charset=utf-8 date: Wed, 12 Jun 2019 08:09:26 GMT server: envoy x-envoy-upstream-service-time: 2 v2
redirect
指令會把 URI 總體替換,靈活性不高;301
指令沒法支持 Post
方法, istio 提供了 rewrite
方式來提供這種在調用前進行 URI 重寫的支持。cat httpbin-default-vs.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - httpbin.default.svc.cluster.local http: - match: - uri: exact: "/get" rewrite: uri: "/post" route: - destination: host: httpbin.default.svc.cluster.local - route: - destination: host: httpbin.default.svc.cluster.local
# 訪問測試 kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') -- http -f POST http://httpbin:8000/get data=nothing # 返回信息 HTTP/1.1 405 Method Not Allowed access-control-allow-credentials: true access-control-allow-origin: * allow: GET, OPTIONS, HEAD content-length: 178 content-type: text/html date: Wed, 12 Jun 2019 12:39:28 GMT server: envoy x-envoy-upstream-service-time: 5 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>405 Method Not Allowed</title> <h1>Method Not Allowed</h1> <p>The method is not allowed for the requested URL.</p>
rewrite
方法與 redirect
方法的不一樣之處在於: 在 rewrite
方法的 match
字段必須包含對目標的定義;rewrite
方法與 redirect
方法不能共存。