服务网格ASM配合阿里云应用高可用服务AHAS可以对部署在服务网格内的应用进行流量控制。本文介绍如何创建一个Mesh流控集群,并对网格实例进行流量控制。

前提条件

步骤一:部署演示应用Bookinfo

  1. 创建并拷贝以下内容到bookinfo.yaml中。
    apiVersion: v1
    kind: Service
    metadata:
      name: details
      labels:
        app: details
        service: details
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: details
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-details
      labels:
        account: details
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: details-v1
      labels:
        app: details
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: details
          version: v1
      template:
        metadata:
          labels:
            app: details
            version: v1
        spec:
          serviceAccountName: bookinfo-details
          containers:
          - name: details
            image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    ##################################################################################################
    # Ratings service
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: ratings
      labels:
        app: ratings
        service: ratings
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: ratings
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-ratings
      labels:
        account: ratings
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ratings-v1
      labels:
        app: ratings
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ratings
          version: v1
      template:
        metadata:
          labels:
            app: ratings
            version: v1
        spec:
          serviceAccountName: bookinfo-ratings
          containers:
          - name: ratings
            image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    ##################################################################################################
    # Reviews service
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews
      labels:
        app: reviews
        service: reviews
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: reviews
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-reviews
      labels:
        account: reviews
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v1
      labels:
        app: reviews
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v1
      template:
        metadata:
          labels:
            app: reviews
            version: v1
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v2
      labels:
        app: reviews
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v2
      template:
        metadata:
          labels:
            app: reviews
            version: v2
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v3
      labels:
        app: reviews
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v3
      template:
        metadata:
          labels:
            app: reviews
            version: v3
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    ##################################################################################################
    # Productpage services
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: productpage
      labels:
        app: productpage
        service: productpage
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: productpage
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-productpage
      labels:
        account: productpage
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
        spec:
          serviceAccountName: bookinfo-productpage
          containers:
          - name: productpage
            image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
          volumes:
          - name: tmp
            emptyDir: {}
    ---
  2. 执行以下命令,将Bookinfo应用部署到ASM实例的集群中。
    说明 DATA_PLANE_KUBECONFIG表示ASM实例集群的Kubeconfig保存在本地的路径。
    kubectl --kubeconfig=${DATA_PLANE_KUBECONFIG} apply -f bookinfo.yaml
  3. 创建并拷贝以下内容到virtual-service-all-v1.yaml中。
    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
    ---
  4. 执行以下命令,部署Bookinfo应用的VirtualServices。
    说明 ASM_KUBECONFIG表示网格实例的Kubeconfig保存在本地的路径。
    kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f virtual-service-all-v1.yaml
  5. 创建并拷贝以下内容到destination-rule-all.yaml中。
    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
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: ratings
    spec:
      host: ratings
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v2-mysql
        labels:
          version: v2-mysql
      - name: v2-mysql-vm
        labels:
          version: v2-mysql-vm
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: details
    spec:
      host: details
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
    ---
  6. 执行以下命令,部署Bookinfo应用的Destination。
    说明 ASM_KUBECONFIG表示网格实例的Kubeconfig保存在本地的路径。
    kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f destination-rule-all.yaml
  7. 创建并拷贝以下内容到bookinfo-gateway.yaml中。
    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:
        - "*"
    ---
    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
  8. 执行以下命令,部署Bookinfo应用的Gateway。
    说明 ASM_KUBECONFIG表示网格实例的Kubeconfig保存在本地的路径。
    kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f bookinfo-gateway.yaml

步骤二:创建Mesh流控集群

  1. 登录AHAS控制台
  2. 在左侧导航栏选择流量防护 > Mesh防护
  3. Mesh防护页面左上角选择地域,单击右上角的申请Mesh流控集群
    说明 您需要选择与ACK集群相同的地域,保证Mesh流控集群与ACK集群位于同一地域。
  4. 集群基本信息页,填写集群名称等信息。
    参数 描述
    集群名称 填写集群的名称。集群名称应包含1~63个字符,可包含数字、汉字、英文字符或连字符(-)。
    Envoy流控domain 流控服务的域。您可以随意设置流控服务的域,与网格内服务域名没有关联。
    集群预计QPS 该集群内需要流控的接口预估的最大QPS(每秒查询率),代表可能到来的最大流量,而非限流阈值,用于为Token Server自动分配提供参考。
    说明 设置的集群预计QPS是用于AHAS进行Server分配,不影响任何限流的实质逻辑。
  5. 单击下一步

步骤三:接入AHAS限流服务

  1. 在Mesh集群配置页面单击Mesh流控接入
  2. Istio接入页签复制页面中的代码,保存页面中的YAML配置文件。
    说明 如果generic_keydescriptor_value的值为AHASundefined,则说明AHAS限流服务尚未准备就绪,请等待并刷新页面,直到该值变化后再进行这一步操作。
  3. 设置EnvoyFilter。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 控制平面区域,选择EnvoyFilter页签,然后单击新建
    5. 新建页面,设置命名空间istio-system,在文本框中拷贝步骤2中保存的YAML配置文件,单击确定
    在网格管理详情页面基本信息区域的流量控制显示已接入,表示已接入AHAS限流服务。若流量控制显示点击接入,表示未接入AHAS限流服务。

步骤四:添加流控规则

为了便于触发流控,本示例中添加一个0.1QPS的流控规则,即10 s内只允许一次访问。

  1. 在Mesh集群配置页面集群规则配置区域单击添加
  2. 设置流控规则。
    参数 描述
    规则名称 用于标识该规则,不超过64个字符,规则名称不能重复。
    阈值 集群阈值,满足流控条件的请求量到达该阈值后会被拒绝。本例中设置为1。
    统计窗口时长 集群流控统计的时间窗口长度,取值范围为1秒~24小时。本例中设置为10秒
    匹配规则 流控针对的请求属性的匹配规则,如针对不同来源的请求分别限制不同的规则。单击添加匹配规则,设置匹配规则类型来源集群,设置针对方式针对具体值,设置针对值为productpage.default。单击新增
    说明 针对值的命名规则为{Pod中labels app的值}.{命名空间名称} ,例如productpage.default。
    是否开启 打开流控开关。
  3. 单击保存

步骤五:触发限流规则

根据代码逻辑Productpage应用会在收到访问请求时调用Reviews和Details应用,这两个调用几乎同时发出。按照0.1QPS的限制,这两个调用会有一个失败。通过服务网格ASM控制台获得入口网关地址,并在浏览器中输入http://{入口网关地址}/productpage,访问测试应用。可以看到productpage页面Reviews区域显示调用失败,限流规则成功生效。2