下例实验前提:示例中proxy会在内部调用demoapp。

重写和跳转路由示例:

# redirect 是通知客户端让客户端重新发送请求
# rewrite 是服务端进行的
# 下面的路由意思是:请求demoapp服务的情况下,带有/canary的重写路径然后到demoapp服务,
# 带有/backend 路径的跳转到backend服务
# 其余流量都到default上
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: rewrite
    match:
    - uri:
        prefix: /canary # 当访问这个路径时
    rewrite:
      uri: / # 通过rewrite到“/”路径 
    route:
    - destination:
        host: demoapp # 最后到这个服务
        subset: v11
  - name: redirect
    match:
    - uri:
        prefix: /backend # 当访问这个路径时
    redirect:
      uri: / # 通过重定向到“/”路径
      authority: backend # 最后到这个服务,这里的authority和使用destination的效果是一样的
      port: 8082
  - name: default # 默认服务,其他的请求路径都路由到这个服务
    route:
    - destination:
        host: demoapp
        subset: v10 # 选择的是v10子集,子集是在DestinationRule中定义的


基于权重的金丝雀发布:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: weight-based-routing
    route:
    - destination:
        host: demoapp
        subset: v10
      weight: 90 # 90%的权重到v10版本
    - destination:
        host: demoapp
        subset: v11
      weight: 10 # 10%的权重到v11版本
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
  namespace: default
spec:
  host: demoapp
  subsets:
  - labels:
      version: v1.0
    name: v10
  - labels:
      version: v1.1
    name: v11


根据请求头来路由:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - headers:
        x-canary:
          exact: "true"
    route:
    - destination:
        host: demoapp
        subset: v11 # 路由到v11版本的流量
      headers: # 定义在destination下的只对当前destination生效
        request:
          set:
            User-Agent: Chrome # 请求头中添加此标头
        response:
          add:
            x-canary: "true" # 响应标头中添加此标头
  - name: default
    headers: # 定义在name下的表示对所有的route都生效
      response:
        add:
          x-Envoy: test
    route:
    - destination:
        host: demoapp
        subset: v10

加header头的请求:

# curl -I -H "x-canary: true" demoapp:8080
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 113
server: envoy
date: Mon, 28 Feb 2022 07:51:38 GMT
x-envoy-upstream-service-time: 8
x-canary: true # 响应头


# curl  -H "x-canary: true" demoapp:8080/user-agent
User-Agent: Chrome

不加header头的请求:

# curl -I demoapp:8080
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 114
server: envoy
date: Mon, 28 Feb 2022 07:53:43 GMT
x-envoy-upstream-service-time: 26
x-envoy: test


故障注入:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v11
    fault:
      abort: # 中断故障
        percentage:
          value: 20 # 流量比例
        httpStatus: 555 # 响应客户端的响应码
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v10
    fault:
      delay: # 延迟故障
        percentage:
          value: 20
        fixedDelay: 3s


重试:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: proxy
spec:
  hosts:
  - "demoapp.ops.net"
  gateways:
  - istio-system/proxy-gateway
  # - mesh
  http:
  - name: default
    route:
    - destination:
        host: proxy
    timeout: 1s # 超时时间
    retries: # 重试,因为加入了重试,所以实际请求成功率会高于故障注入的50%
      attempts: 5 # 重试次数
      perTryTimeout: 1s # 重试超时
      retryOn: 5xx,connect-failure,refused-stream # 重试条件
---
# demoapp
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v11
    fault:
      abort:
        percentage:
          value: 50 # 改成50%了
        httpStatus: 555
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v10
    fault:
      delay:
        percentage:
          value: 50
        fixedDelay: 3s

在外部调用:proxy的vs中没有加mesh,所以要在外部调用才能有效果。

while true; do curl demoapp.ops.net; sleep 0.$RANDOM; done
while true; do curl demoapp.ops.net/canary; sleep 0.$RANDOM; done


流量镜像:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: traffic-mirror
    route:
    - destination:
        host: demoapp
        subset: v10
    mirror: # 流量镜像到那个服务
      host: demoapp
      subset: v11