基于ASM实现多集群的一站式流量治理

通过ACK One的服务网格功能,您可以实现多集群的一站式应用分发和流量治理。本文介绍如何通过ACK One Fleet实例完成关联集群之间的应用分发和流量治理。

前提条件

  • ACK One Fleet实例已开启服务网格。具体操作,请参见开启服务网格

  • 已添加至少一个关联集群。具体操作,请参见添加关联集群

  • 已从ACK One控制台获取Fleet实例的KubeConfig,并通过kubectl连接至Fleet实例。

背景信息

本文示例通过使用ACK One Fleet实例的KubeConfig,在多个关联集群上部署Rollouts应用,同时下发相应的流量治理规则,从而完成多个版本之间的流量切换。关于多集群管理应用分发的更多信息,请参见应用分发

本文示例操作示意如下图所示。

image
  • 图中①表示用户可以部署相应的Kubernetes原生应用到关联集群,例如Deployment、Service、ConfigMap等。

  • 图中②表示用户可以通过ACK One Fleet实例下发流量治理相关的规则到关联集群,不需要使用服务网格ASM的KubeConfig,目前支持的有:

    • Destinationrules

    • Envoyfilters

    • Gateways

    • Serviceentries

    • Sidecars

    • Virtualservices

    • Workloadentries

    • Workloadgroups

  • 图中③表示用户通过访问网关地址访问应用,应用最终根据所部署的流量规则呈现相应的结果。

操作步骤

  1. 执行以下命令,在default命名空间开启自动注入。

    kubectl label namespace default istio-injection=enabled
  2. 创建资源。

    1. 使用以下内容,创建podinfo-meta.yaml文件,包含应用相关的Kubernetes原生资源。

      展开查看podinfo-meta.yaml文件

      apiVersion: v1
      kind: Service
      metadata:
        name: podinfo
        labels:
          app: podinfo
          service: podinfo
      spec:
        selector:
          app: podinfo
        ports:
          - protocol: TCP
            port: 80
            targetPort: 8080
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: podinfo-green
        labels:
          app: podinfo
          version: green
      spec:
        replicas: 4
        minReadySeconds: 5
        revisionHistoryLimit: 5
        progressDeadlineSeconds: 60
        strategy:
          rollingUpdate:
            maxUnavailable: 1
          type: RollingUpdate
        selector:
          matchLabels:
            app: podinfo
            version: green
        template:
          metadata:
            labels:
              app: podinfo
              version: green
          spec:
            containers:
              - name: podinfod
                image: registry.cn-hangzhou.aliyuncs.com/acs/rollouts-demo:green
                imagePullPolicy: IfNotPresent
                ports:
                  - name: http
                    containerPort: 8080
                    protocol: TCP
                readinessProbe:
                  tcpSocket:
                    port: 8080
                  initialDelaySeconds: 5
                  timeoutSeconds: 5
      
      
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: podinfo-blue
        labels:
          app: podinfo
          version: blue
      spec:
        replicas: 4
        minReadySeconds: 5
        revisionHistoryLimit: 5
        progressDeadlineSeconds: 60
        strategy:
          rollingUpdate:
            maxUnavailable: 1
          type: RollingUpdate
        selector:
          matchLabels:
            app: podinfo
            version: blue
        template:
          metadata:
            labels:
              app: podinfo
              version: blue
          spec:
            containers:
              - name: podinfod
                image: registry.cn-hangzhou.aliyuncs.com/acs/rollouts-demo:blue
                imagePullPolicy: IfNotPresent
                ports:
                  - name: http
                    containerPort: 8080
                    protocol: TCP
                readinessProbe:
                  tcpSocket:
                    port: 8080
                  initialDelaySeconds: 5
                  timeoutSeconds: 5
    2. 执行以下命令,在Fleet实例上添加资源。

      kubectl apply -f podinfo-meta.yaml
      
  3. 执行以下命令,获取Fleet实例已添加的关联集群信息。

    关于AMC命令行更多信息,请参见AMC命令行帮助

    kubectl amc get managedclusters

    预期输出:

    Name                                Alias       HubAccepted
    c5f4110f2ad88499583fc76cc568a****   ack-hy-01   true
    c7f78dd3b09a146b8b750b4c1c51d****   ack-hy-02   true
  4. 创建应用。

    1. 使用以下内容,创建podinfo-app.yaml文件,定义开源KubeVela Application podinfo,实现多集群分发。

      使用上一步获取的关联集群ID替换如下<clusterid1><clusterid2>

      apiVersion: core.oam.dev/v1beta1
      kind: Application
      metadata:
        name: podinfo
        namespace: default
        annotations:
          app.oam.dev/publishVersion: version1
      spec:
        components:
          - name: podinfo
            type: ref-objects
            properties:
              objects:
                - apiVersion: apps/v1
                  kind: Deployment
                  name: podinfo-blue
                - apiVersion: apps/v1
                  kind: Deployment
                  name: podinfo-green
                - apiVersion: v1
                  kind: Service
                  name: podinfo
        policies:
          - type: topology
            name: podinfo-clusters
            properties:
              clusters: ["<clusterid1>","<clusterid2>"]  # 定义下发的目标集群,如需更新目标集群,可在此字段新增或修改。           
    2. 执行如下命令,在Fleet实例上部署应用podinfo

      kubectl apply -f podinfo-app.yaml
  5. 登录ASM控制台,创建服务网格ASM入口网关。具体操作,请参见创建入口网关

  6. 创建Istio网关。

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

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: podinfo-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
    2. 执行以下命令,在Fleet实例上部署Istio网关。

      kubectl apply -f podinfo-gateway.yaml
  7. 创建虚拟服务。

    1. 使用以下内容,创建virtual-service-all-blue.yaml文件。

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: podinfo
      spec:
        hosts:
        - "*"
        gateways:
        - podinfo-gateway
        http:
        - match:
          - uri:
              prefix: /
          route:
          - destination:
              host: podinfo
              subset: blue
              port:
                number: 80
    2. 执行以下命令,在Fleet实例上部署虚拟服务。

      kubectl apply -f virtual-service-all-blue.yaml
  8. 创建目标规则。

    1. 使用以下内容,创建destination-rule-all.yaml文件。

      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: podinfo
      spec:
        host: podinfo
        trafficPolicy:
          outlierDetection:
            baseEjectionTime: 30s
            consecutiveErrors: 7
            interval: 30s
        subsets:
        - name: blue
          labels:
            version: blue
        - name: green
          labels:
            version: green
    2. 执行以下命令,在Fleet实例上部署目标规则。

      kubectl apply -f destination-rule-all.yaml
  9. 执行以下命令,获取ASM网关地址。

    AMC命令行更多信息,请参见AMC命令行帮助

    kubectl amc get svc -n istio-system -m <关联集群>

    预期输出:

    Run on ManagedCluster c5f4110f2ad88499583fc76cc568a**** (ack-hy-01)
    NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
    istio-ingressgateway     LoadBalancer   10.12.1**.***   47.113.***.***   80:30315/TCP,443:32***/TCP   47h
    Run on ManagedCluster c7f78dd3b09a146b8b750b4c1c51d**** (ack-hy-02)
    NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                      AGE
    istio-ingressgateway     LoadBalancer   10.75.9**.***   47.113.***.***   80:32101/TCP,443:30***/TCP   47h                     
  10. 在浏览器中访问http://<网关IP>/。

    使用上一步获取的EXTERNAL-IP替换<网关IP>,访问页面如下所示,此时仅展示blue版本。blue

  11. 创建虚拟服务,分配不同的流量比例。

    1. 使用以下内容,创建virtual-service-green-blue-80-20.yaml文件。

      以下示例中green版本权重为80,blue版本权重为20。

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: podinfo
      spec:
        hosts:
        - "*"
        gateways:
        - podinfo-gateway
        http:
        - match:
          - uri:
              prefix: /
          route:
          - destination:
              host: podinfo
              subset: green
              port:
                number: 80
            weight: 80
          - destination:
              host: podinfo
              subset: blue
              port:
                number: 80
            weight: 20
    2. 执行以下命令,在Fleet实例上部署虚拟服务。

      kubectl apply -f virtual-service-green-blue-80-20.yaml
  12. 继续在浏览器中访问http://<网关IP>/。

    可看到应用greenblue的版本会按照80%和20%流量比例呈现。blue-green