ASM提供了自定义资源配置范围配置范围用于限制配置的生效范围。您可以使用配置范围逐步根据应用的机器配置灰度策略,扩大配置在机器的灰度范围。本文介绍如何通过配置范围限制虚拟服务的生效范围,逐步实现配置的灰度发布。

前提条件

背景信息

当应用版本升级时,需要将应用的旧版本A与新版本B同时部署在环境中,通过调整版本A和B的流量占比实现老版本和新版本的平滑过渡。您可以通过配置虚拟服务实现流量管理。以Bookinfo应用为例,ProductPage应用会调用Reviews,Reviews版本升级到v2后,您可以使用虚拟服务将ProductPage应用请求引流到v2版本Reviews。review
根据可灰度原则,需要控制路由规则配置变更的风险。您可以使用配置范围使虚拟服务只在Pod1生效,从而将ProductPage应用的一个Pod的请求引流到v2版本的Reviews,另一个Pod的请求引流到v1版本的Reviews。灰度
Istio社区目前有部分路由规则配置提供了WorkloadSelector选项限制生效的范围,但是存在以下两个问题:
  • WorkloadSelector只支持按Label的kv方式匹配,但是不支持多值匹配,例如idc: shanghai01,shanghai02
  • 无法处理原路由规则配置和灰度路由规则配置共存的问题。
ASM提供了配置范围,用于描述配置的生效范围。配置范围提供两种模式的配置灰度能力:
说明 rollingUpdate和Selector不能同时配置。
  • Selector模式:该模式需要给Pod添加标签,您可以给Pod添加机房、单元或者灰度标签。Envoy将这些标签携带到Istio,您可以使用matchLabels或者matchExpressions方式实现标签的匹配,将配置在指定的标签范围生效,从而达到配置灰度的效果。
  • rollingUpdate模式:该模式不需要给Pod添加标签,您可以定义配置分N批发布。Istio会根据节点数将节点分成N批,然后根据当前批次信息实现分批生效。
apiVersion: istio.alibabacloud.com/v1beta1
kind: ScopeConfig
metadata:
  name: reviews-route-canary
spec:
  scope:
    selector: //灰度的范围选择
        matchLabels:
            app: ratings
        matchExpressions:
        - {key: idc, operator: In, values: [shanghai01,shanghai02]}
        - {key: environment, operator: NotIn, values: [dev]}
    rollingUpdate:  //配置滚动发布,与selector不能同时配置。
        batchNum: 5    //滚动发布总的批次。
        batchOrder: 1  //滚动发布当前批次。
配置范围只是对配置的生效范围作出了定义,真正起作用是需要关联到相关的配置。您需要通过annotations方式将配置范围虚拟服务进行关联。
annotations:
  istio.canary.scopeconfig: default/reviews-route-canary  //新增annotations标识该配置关联的scopeconfig,格式为:namespace/name。
  istio.canary.prod-config: reviews //新增annotations标识该配置关联的正式配置。

步骤一:扩容Productpage应用

ProductPage默认实例数是1,需要将实例数扩容到2,用于验证在多个节点实现路由规则配置灰度策略。

  1. 通过kubectl工具连接集群
  2. 执行以下命令,编辑productpage-v1应用的实例数。
    kubectl edit deployment  productpage-v1
  3. replicas参数修改为2,然后保存。

步骤二:设置100%流量路由到v1版本Reviews

  1. 使用以下内容,创建网关规则。具体操作,请参见管理网关规则
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
  2. 使用以下内容,创建虚拟服务。具体操作,请参见管理虚拟服务

    以下虚拟服务定义来自productpage、static、login、logout、api/v1/products的请求可以访问到productpage服务。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
  3. 使用以下内容,创建目标规则。具体操作,请参见管理目标规则
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      subsets:
      - name: v1
        labels:
          version: v1
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v3
        labels:
          version: v3
  4. 使用以下内容,创建虚拟服务。具体操作,请参见管理虚拟服务
    以下虚拟服务定义流量100%路由到v1版本的Reviews。
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: productpage
    spec:
      hosts:
      - productpage
      http:
      - route:
        - destination:
            host: productpage
            subset: v1
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v1
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - route:
        - destination:
            host: ratings
            subset: v1
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: details
    spec:
      hosts:
      - details
      http:
      - route:
        - destination:
            host: details
            subset: v1

步骤三:设置将Pod1的流量路由到v2版本的Reviews,Pod2保持不变

  1. 查看Productpage应用的Pod IP。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
    5. 无状态页面单击productpage-v1应用的名称。
    6. 容器组页签下查看目标Pod的Pod IP。
  2. 使用以下内容,创建配置范围。具体操作,请参见管理配置范围
    以下配置范围定义虚拟服务只对Pod1生效。
    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ScopeConfig
    metadata:
      name: reviews-route-canary
    spec:
      scope:
        selector:
            matchExpressions:
            - {key: ip, operator: In, values: [<Pod IP1>]}
  3. 使用以下内容,创建虚拟服务。具体操作,请参见管理虚拟服务
    以下虚拟服务通过annotations绑定配置范围,使虚拟服务只对Pod1生效。
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews-canary
      annotations:
        istio.canary.scopeconfig: default/reviews-route-canary //新增annotations标识该配置关联的scopeconfig,格式为:namespace/name
        istio.canary.prod-config: reviews //新增annotations标识该配置关联的正式配置
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
  4. 验证Pod1的流量路由到v2版本的Reviews,Pod2保持不变。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择网络 > 服务
    5. 服务页面顶部设置命名空间为istio-system,查看istio-ingressgateway外部端点列下端口为80的IP地址。
    6. 在浏览器中输入http://<istio-ingressgateway IP地址>/productpage,多次刷新页面,可以看到Review1和Review2显示无星星和黑星星,随着页面刷新交替出现。

      调用v1版本的Reviews会显示无星星,调用v2版本的Reviews会显示黑星星。无星星和黑星星交替出现,说明Pod1的流量路由到v2版本的Reviews,Pod2的流量路由到v1版本的Reviews。

      V2v1

步骤四:设置将Pod1和Pod2的流量路由到v2版本的Reviews

  1. 查看Productpage应用的Pod IP。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
    5. 无状态页面单击productpage-v1应用的名称。
    6. 容器组页签下查看目标Pod的Pod IP。
  2. 使用以下内容,修改配置范围。具体操作,请参见管理配置范围
    以下ScopeConfig定义VirtualService对Pod1和Pod2生效。
    说明 因上文的VirtualService已绑定ScopeConfig,无需再次修改VirtualService。
    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ScopeConfig
    metadata:
      name: reviews-route-canary
    spec:
      scope:
        selector:
            matchExpressions:
            - {key: ip, operator: In, values: [<Pod IP1>,<PodIp2>]}
  3. 验证Pod1和Pod2的流量都路由到v2版本的Reviews。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择网络 > 服务
    5. 服务页面顶部设置命名空间为istio-system,查看istio-ingressgateway外部端点列下端口为80的IP地址。
    6. 在浏览器中输入http://<istio-ingressgateway IP地址>/productpage,多次刷新页面,可以看到Review1和Review2一直显示黑星星。
      调用v1版本的Reviews会显示无星星,调用v2版本的Reviews会显示黑星星。页面一直显示黑星星,说明Pod1和Pod2的流量都路由到v2版本的Reviews。V2
  4. 可选:完成灰度后,建议进行以下操作,防止自定义资源堆积。
    1. 使用以下内容,修改虚拟服务。具体操作,请参见管理虚拟服务
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
          - reviews
        http:
        - route:
          - destination:
              host: reviews
              subset: v2
    2. 删除名为reviews-route-canary的ScopeConfig和名为reviews-canary的虚拟服务。具体操作,请参见管理配置范围管理虚拟服务