基于流量规则配置实现流量泳道和流量降级

流量泳道是指通过配置流量管理规则将应用的相关版本(或者其他特征)隔离成一个独立的运行环境(即泳道),并将满足规则的请求流量路由到目标版本(或者其他特征)的应用。您可以基于VirtualService和DestinationRule等流量规则实现流量泳道,同时通过配置流量降级,在某个版本(或者其他特征)的应用不可用时,将流量发往一个指定的降级版本(或其他特征)的应用。本文介绍如何在ASM中基于流量规则配置实现流量泳道和流量降级。

前提条件

步骤一:部署示例服务

  1. 为default命名空间开启自动注入。具体操作,请参见启用自动注入

    关于自动注入的更多信息,请参见配置Sidecar注入策略

  2. 使用数据面集群的KubeConfig,执行以下命令,部署示例服务。

    示例服务包含mocka、mockb、mockc三个服务,每个服务都有v1、v2、v3三个版本。

    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v1/application-v1.yaml
    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v2/application-v2.yaml
    kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v3/application-v3.yaml

步骤二:创建流量规则实现流量泳道

  1. 创建DestinationRule流量规则。

    1. 使用以下内容,创建dr-mock.yaml文件。

      以下文件表示将mocka、mockb、mockc三个服务各自分为v1、v2、v3三个子集。

      展开查看dr-mock.yaml

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: mocka
        namespace: istio-system
      spec:
        host: mocka.default.svc.cluster.local
        subsets:
          - labels:
              version: v1
            name: v1
          - labels:
              version: v2
            name: v2
          - labels:
              version: v3
            name: v3
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: mockb
        namespace: istio-system
      spec:
        host: mockb.default.svc.cluster.local
        subsets:
          - labels:
              version: v1
            name: v1
          - labels:
              version: v2
            name: v2
          - labels:
              version: v3
            name: v3
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: mockc
        namespace: istio-system
      spec:
        host: mockc.default.svc.cluster.local
        subsets:
          - labels:
              version: v1
            name: v1
          - labels:
              version: v2
            name: v2
          - labels:
              version: v3
            name: v3
    2. 使用ASM实例的KubeConfig,执行以下命令,生效DestinationRule流量规则。

      kubectl apply -f dr-mock.yaml
  2. 创建VirtualService流量规则。

    1. 使用以下内容,创建vs-mock.yaml文件。

      以下文件表示为mocka→mockb→mockc的服务调用链路创建泳道。创建泳道后,由一个版本的服务发出的请求,只能发送到相同版本的服务。

      展开vs-mock.yaml

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: mockb
        namespace: istio-system
      spec:
        hosts:
          - mockb.default.svc.cluster.local
        http:
        - match:
          - sourceLabels:
              version: v1
          route:
          - destination:
              host: mockb.default.svc.cluster.local
              subset: v1
        - match:
          - sourceLabels:
              version: v2
          route:
          - destination:
              host: mockb.default.svc.cluster.local
              subset: v2
        - match:
          - sourceLabels:
              version: v3
          route:
          - destination:
              host: mockb.default.svc.cluster.local
              subset: v3
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: mockc
        namespace: istio-system
      spec:
        hosts:
          - mockc.default.svc.cluster.local
        http:
        - match:
          - sourceLabels:
              version: v1
          route:
          - destination:
              host: mockc.default.svc.cluster.local
              subset: v1
        - match:
          - sourceLabels:
              version: v2
          route:
          - destination:
              host: mockc.default.svc.cluster.local
              subset: v2
        - match:
          - sourceLabels:
              version: v3
          route:
          - destination:
              host: mockc.default.svc.cluster.local
              subset: v3
    2. 使用ASM实例的KubeConfig,执行以下命令,生效VirtualService流量规则。

      kubectl apply -f vs-mock.yaml
  3. 创建网关引流规则。

    1. 使用以下内容,创建gw-mock.yaml文件。

      以下文件表示为mocka→mockb→mockc的服务调用链路创建网关引流规则。通过匹配发往网关请求的x-asm-prefer-tag Header,根据其中的Header值将请求路由到mocka服务的v1、v2、v3三个不同版本。

      展开查看gw-mock.yaml

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        selector:
          istio: ingressgateway
        servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
              - '*'
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        gateways:
          - istio-system/ingressgateway
        hosts:
          - '*'
        http:
          - match:
              - headers:
                  x-asm-prefer-tag:
                    exact: v1
                uri:
                  exact: /mock
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: v1
          - match:
              - headers:
                  x-asm-prefer-tag:
                    exact: v2
                uri:
                  exact: /mock
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: v2
          - match:
              - headers:
                  x-asm-prefer-tag:
                    exact: v3
                uri:
                  exact: /mock
            route:
              - destination:
                  host: mocka.default.svc.cluster.local
                  subset: v3
    2. 使用ASM实例的KubeConfig,执行以下命令,生效网关引流规则。

      kubectl apply -f gw-mock.yaml

步骤三:验证流量泳道是否生效

  1. 获取ASM网关的公网IP。具体操作,请参见获取ASM网关地址

  2. 执行以下命令,设置环境变量。

    xxx.xxx.xxx.xxx为上一步获取的IP。

    export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
  3. 验证全灰度链路功能是否生效。

    1. 执行以下命令,查看v1泳道的访问效果。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: v1' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      预期输出:

      -> mocka(version: v1, ip: 172.17.0.54)-> mockb(version: v1, ip: 172.17.0.129)-> mockc(version: v1, ip: 172.17.0.130)

      由预期输出得到,通过设置HTTP标头x-asm-prefer-tag: v1声明的流量流向v1版本的相关服务,符合预期。

    2. 执行以下命令,查看v2泳道的访问效果。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: v2' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      预期输出:

      -> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v2, ip: 172.17.0.126)-> mockc(version: v2, ip: 172.17.0.128)

      由预期输出得到,通过设置HTTP标头x-asm-prefer-tag: v2声明的流量流向v2版本的相关服务,符合预期。

    3. 执行以下命令,查看v3泳道的访问效果。

      for i in {1..100};  do curl   -H 'x-asm-prefer-tag: v3' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

      预期输出:

      -> mocka(version: v3, ip: 172.17.0.132)-> mockb(version: v3, ip: 172.17.0.127)-> mockc(version: v3, ip: 172.17.0.69)

      由预期输出得到,通过设置HTTP标头x-asm-prefer-tag: v3声明的流量流向v3版本的相关服务,符合预期。

步骤四:配置流量泳道内的流量降级

  1. 使用以下内容,修改vs-mock.yaml文件。

    以下文件表示为mocka→mockb→mockc的服务调用链路创建泳道,同时,当mockb或mockc的v2、v3版本不可用时,请求将发往服务的v1版本调用链。

    展开查看vs-mock.yaml

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: mockb
      namespace: istio-system
    spec:
      hosts:
        - mockb.default.svc.cluster.local
      http:
      - match:
        - sourceLabels:
            version: v1
        route:
        - destination:
            host: mockb.default.svc.cluster.local
            subset: v1
      - match:
        - sourceLabels:
            version: v2
        route:
        - destination:
            host: mockb.default.svc.cluster.local
            subset: v2
          fallback:
            target:
              host: mockb.default.svc.cluster.local
              subset: v1
      - match:
        - sourceLabels:
            version: v3
        route:
        - destination:
            host: mockb.default.svc.cluster.local
            subset: v3
          fallback:
            target:
              host: mockb.default.svc.cluster.local
              subset: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: mockc
      namespace: istio-system
    spec:
      hosts:
        - mockc.default.svc.cluster.local
      http:
      - match:
        - sourceLabels:
            version: v1
        route:
        - destination:
            host: mockc.default.svc.cluster.local
            subset: v1
      - match:
        - sourceLabels:
            version: v2
        route:
        - destination:
            host: mockc.default.svc.cluster.local
            subset: v2
          fallback:
            target:
              host: mockc.default.svc.cluster.local
              subset: v1
      - match:
        - sourceLabels:
            version: v3
        route:
        - destination:
            host: mockc.default.svc.cluster.local
            subset: v3
          fallback:
            target:
              host: mockc.default.svc.cluster.local
              subset: v1
  2. 使用ASM实例的KubeConfig,执行以下命令,修改原有VirtualService流量规则,生效流量降级配置。

    kubectl apply -f vs-mock.yaml

步骤五:验证流量降级是否生效

  1. 登录容器服务管理控制台,在左侧导航栏选择集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态

  3. 无状态页面的操作列,单击mockb-v2工作负载对应的伸缩,在伸缩对话框,将所需容器组数量调整至1,单击确定,在确认对话框,单击确定,模拟v2版本的mockb服务故障效果。

  4. 执行以下命令,查看v2泳道的访问效果。

    for i in {1..100};  do curl   -H 'x-asm-prefer-tag: v2' http://${ASM_GATEWAY_IP}/mock ;  echo ''; sleep 1; done;

    预期输出:

    -> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v1, ip: 172.17.0.126)-> mockc(version: v1, ip: 172.17.0.128)

    由预期输出得到,通过设置HTTP标头x-asm-prefer-tag: v2声明的流量流向v2版本的相关服务。在流量流经v2版本的mockb服务时,由于v2版本的mockb服务发生故障,请求后续发往服务的v1版本调用链路,实现了流量降级。