基于网格服务进行多版本发布

Fri Dec 20, 2019

300 Words|Read in about 2 Min
Tags: Devops  

Istio基于Kubernetes最大的方便就是可以基于金丝雀多版本进行业务服务发布。当然还有服务之间互相网格调度也是很大的进步。当然在有分布式服务框架(dubbo、Springcloud)下这根本不算什么。

istio金丝雀多版本发布,可以在不停机的情况下,进行灰度测试。测试好过后可以直接将金丝雀版本切换为生产正式版本。

常用的方式如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sklinux-prod
spec:
  hosts:
    - www.sklinux.com
  gateways:
    - sklinux-gateway
  http:
    - match:
        - headers:
            dev-mode:
              exact: "1"    #http请求头部为 dev-mode: 1 的请求
      route:
        - destination:
            host: sklinux-prod
            port:
              number: 80
            subset: canary  #匹配 流量将转到 canary后端(DR)

    - route:
        - destination:
            host: sklinux-prod
            port:
              number: 8080
            subset: main    #默认流量 去往DR为sklinux-prod 的main标签后端

以上是生产环境的VS示范,比如默认用户访问https://www.sklinux.com 的时候会直接访问DestinationRule后端名为sklinux-prod,并且subset值为main的后端服务(Deployment)。

但是,上面只是展示了/服务的金丝雀,2个版本的案例。

要是有多个子路径呢?比如 /sso、/buy等。这样就需要两个条件满足后才能转到匹配的后端DR去。

上示范:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sklinux-prod
spec:
  hosts:
    - www.sklinux.com
  gateways:
    - sklinux-gateway
  http:
    - match:
        - headers:
            dev-mode:
              exact: "1"    #http请求头部为 dev-mode: 1 的请求
          uri: 
            prefix: /sso    # 并且路径匹配为/sso的请求流量
        rewrite:
          uri: /
      route:
        - destination:
            host: sklinux-sso-prod
            port:
              number: 80
            subset: canary  #匹配 流量将转到 canary后端(DR)

    - route:
        - destination:
            host: sklinux-sso-prod
            port:
              number: 8080
            subset: main    #默认流量/sso(正式用户) 去往DR为sklinux-sso 的main标签后端

DR示范:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sklinux-sso-prod
spec:
  host: sklinux-sso
  subsets:
    - name: canary
      labels:
        traffic: canary
    - name: main
      labels:
        traffic: main
✗ curl https://www.sklinux.com/ip/
{
  "this main host"
}

✗ curl https://www.sklinux.com/ip/ -H "canary-mode: 1"
{
  "this cannar host"
}

当有/有很大流量的时候,一般是拆分路由,到多个后端(DR),但是这样会让整个yaml文件很冗长,不利于分散到项目。所以可以拆散VirtualService。

比如:

#根路由
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sklinux-service-main-prod
spec:
  hosts:
    - www.sklinux.com
  gateways:
    - sklinux-gateway
  http:
      route:
        - destination:
            host: service-main-prod
            port:
              number: 80
            subset: main  
#服务a
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sklinux-service-a-prod
spec:
  hosts:
    - www.sklinux.com
  gateways:
    - sklinux-gateway
  http:
    - match:
        uri: 
          prefix: /a    # 并且路径匹配为/sso的请求流量
        rewrite:
          uri: /
      route:
        - destination:
            host: service-a-prod
            port:
              number: 80
            subset: main  
---
#服务b
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sklinux-service-b-prod
spec:
  hosts:
    - www.sklinux.com
  gateways:
    - sklinux-gateway
  http:
    - match:
        uri: 
          prefix: /b    # 并且路径匹配为/sso的请求流量
        rewrite:
          uri: /
      route:
        - destination:
            host: service-b-prod
            port:
              number: 80
            subset: main  
---
以此类推

其他可以参考《Traffic Management Best Practices》

See Also

Fri Dec 20, 2019

300 Words|Read in about 2 Min
Tags: Devops