服务网格ASM的流量管理功能支持通过入口网关访问内部的gRPC服务。本文通过示例介绍如何通过ASM入口网关访问内部gRPC服务,并在gRPC的两个版本之间进行流量切换。

前提条件

步骤一:部署示例应用

部署名为istio-grpc-server-v1和istio-grpc-server-v2的示例应用。

  1. 登录容器服务控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的应用管理
  4. 无状态页面命名空间下拉列表中选择命名空间。
    说明 当前选中的命名空间应当已标注自动注入Sidecar,即包含istio-system=enabled标签,详细介绍请参见设置Sidecar自动注入
  5. 无状态页面单击使用模板创建
  6. 在模板创建页面将下面的YAML模版粘贴到模版文本框中,单击创建
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: istio-grpc-server-v1
      labels:
        app: istio-grpc-server
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: istio-grpc-server
          version: v1
      template:
        metadata:
          labels:
            app: istio-grpc-server
            version: v1
        spec:
          containers:
          - args:
            - --address=0.0.0.0:8080
            image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-server
            imagePullPolicy: Always
            livenessProbe:
              exec:
                command:
                - /bin/grpc_health_probe
                - -addr=:8080
              initialDelaySeconds: 2
            name: istio-grpc-server
            ports:
            - containerPort: 8080
            readinessProbe:
              exec:
                command:
                - /bin/grpc_health_probe
                - -addr=:8080
              initialDelaySeconds: 2
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: istio-grpc-server-v2
      labels:
        app: istio-grpc-server
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: istio-grpc-server
          version: v2
      template:
        metadata:
          labels:
            app: istio-grpc-server
            version: v2
        spec:
          containers:
            - args:
                - --address=0.0.0.0:8080
              image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-server
              imagePullPolicy: Always
              livenessProbe:
                exec:
                  command:
                    - /bin/grpc_health_probe
                    - -addr=:8080
                initialDelaySeconds: 2
              name: istio-grpc-server
              ports:
                - containerPort: 8080
              readinessProbe:
                exec:
                  command:
                    - /bin/grpc_health_probe
                    - -addr=:8080
                initialDelaySeconds: 2
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: istio-grpc-server
      labels:
        app: istio-grpc-server
    spec:
      ports:
      - name: grpc-backend
        port: 8080
        protocol: TCP
      selector:
        app: istio-grpc-server
      type: ClusterIP
    ---

步骤二:设置服务网格ASM的路由规则

设置服务网格的服务网关、虚拟服务和目标规则,将流量全部指向istio-grpc-server-v1。

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 创建服务网关。
    1. 控制平面区域单击Gateway页签,然后单击新建
    2. 新建页面设置命名空间default,将下面的YAML模板粘贴到文本框中,单击确定
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: grpc-gateway
      spec:
        selector:
          istio: ingressgateway # use Istio default gateway implementation
        servers:
        - port:
            number: 8080
            name: grpc
            protocol: GRPC
          hosts:
          - "*"

      Gateway页签下可以看到名为grpc-gateway的服务网关。

  5. 创建目标规则。
    1. 控制平面区域单击DestinationRule页签,然后单击新建
    2. 新建页面设置命名空间default,将下面的YAML模板粘贴到文本框中,单击确定
      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: dr-istio-grpc-server
      spec:
        host: istio-grpc-server
        trafficPolicy:
          loadBalancer:
            simple: ROUND_ROBIN
        subsets:
          - name: v1
            labels:
              version: "v1"
          - name: v2
            labels:
              version: "v2"

      DestinationRule页签下可以看到名为dr-istio-grpc-server的目标规则。

  6. 创建虚拟服务。
    1. 控制平面区域单击VirtualService页签,然后单击新建
    2. 新建页面设置命名空间default,将下面的YAML模板粘贴到文本框中,单击确定
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: grpc-vs
      spec:
        hosts:
        - "*"
        gateways:
        - grpc-gateway
        http:
          - match:
              - port: 8080
            route:
              - destination:
                  host: istio-grpc-server
                  subset: v1
                weight: 100
              - destination:
                  host: istio-grpc-server
                  subset: v2
                weight: 0

      VirtualService页签下可以看到名为grpc-vs的虚拟服务。

步骤三:部署入口网关

在入口网关中,添加端口8080,并指向服务网关的8080端口。

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 数据平面区域单击入口网关服务页签,单击部署默认入口网关
  5. 部署入口网关页面配置参数。
    参数 配置项
    部署集群 选择要部署入口网关的集群。
    负载均衡类型 此处指定负载均衡的类型为公网访问
    负载均衡 选择负载均衡。
    • 使用已有负载均衡:从已有负载均衡列表中选择。
    • 新建负载均衡:单击新建负载均衡,从下拉列表中选择所需的负载均衡规格。
    说明 建议您为每个Kubernetes服务分配一个SLB。如果多个Kubernetes服务复用同一个SLB,存在以下风险和限制:
    • 使用已有的SLB会强制覆盖已有监听,可能会导致您的应用不可访问。
    • Kubernetes通过Service创建的SLB不能复用,只能复用您手动在控制台(或调用OpenAPI)创建的SLB。
    • 复用同一个SLB的多个Service不能有相同的前端监听端口,否则会造成端口冲突。
    • 复用SLB时,监听的名字以及虚拟服务器组的名字被Kubernetes作为唯一标识符。请勿修改监听和虚拟服务器组的名字。
    • 不支持跨集群复用SLB。
    端口映射 单击添加端口,设置名称为tcp,服务端口容器端口为8080。
    说明 服务端口指的是整个网格对外暴露的端口,是外部访问使用的端口。而容器端口指的是从服务端口进来的流量所指向的服务网关端口。所以容器端口需要与服务网关端口一致。
  6. 单击确定

步骤四:运行gRPC客户端

  1. 启动gRPC客户端。
    docker run -d --name grpc-client registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-client 365d
  2. 登录到容器。
    docker exec -it grpc-client sh
  3. 访问网格内的gRPC服务。
    /bin/greeter-client --insecure=true --address=<入口网关的IP地址>:8080 --repeat=100

    返回以下结果,可以看到所有的请求都指向了istio-grpc-server-v1。

    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:18:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw

步骤五:按比例将流量路由到v2

将40%的流量指向istio-grpc-server-v2,其余60%的流量仍然指向istio-grpc-server-v1。

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 控制平面区域单击VirtualService页签。
  5. VirtualService页签单击grpc-vs操作列的YAML
  6. 编辑对话框中更新以下YAML内容,单击确定
    ....
          route:
            - destination:
                host: istio-grpc-server
                subset: v1
              weight: 60
            - destination:
                host: istio-grpc-server
                subset: v2
              weight: 40
  7. 登录到容器,执行以下命令,访问网格内的gRPC服务。
    /bin/greeter-client --insecure=true --address=<入口网关的IP地址>:8080 --repeat=100
    返回以下结果,可以看到40%的流量指向了istio-grpc-server-v2。
    说明 您的测试结果不一定总是100次中有40次指向istio-grpc-server-v2,但从总体比例来看,一定是接近40% 的。
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v2-665c4cf57d-h74lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v2-665c4cf57d-h74lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v1-dbdd97cc-n85lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v2-665c4cf57d-h74lw
    2020/09/11 03:34:51 Hello world from istio-grpc-server-v2-665c4cf57d-h74lw