Cloud Service Mesh 示例:Canary 部署


在本教程中,您将了解使用 Cloud Service Mesh 来发布 Canary 部署的常见用例。

什么是 Canary 部署?

Canary 部署会将一小部分流量路由到微服务的新版本,然后您可以逐步发布到整个用户群,同时逐步淘汰和弃用旧版本。如果在此过程中出现问题,可以将流量切换回旧版本。借助 Cloud Service Mesh,您可以路由流量,以确保安全引入新服务。

如需详细了解 Canary 测试,请参阅应用部署和测试策略

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本教程后,您可以删除所创建的资源以避免持续产生费用。如需了解详情,请参阅清理

准备工作

部署 Online Boutique

  1. kubectl 的当前上下文设置为在其中部署 Online Boutique 的集群:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. 为示例应用和入站流量网关创建命名空间:

    kubectl create namespace onlineboutique
    
  3. onlineboutique 命名空间添加标签以自动注入 Envoy 代理。请按照如何启用自动边车代理注入中的步骤操作。

  4. 部署示例应用。在本教程中,您将部署 Online Boutique,这是一个微服务演示版应用。

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. 通过运行以下命令,向 productcatalog 部署添加标签 version=v1

    kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}' \
    -n onlineboutique
    

    查看您部署的服务:

    kubectl get pods -n onlineboutique
    

    预期输出:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    应用的所有 Pod 都应启动并运行,READY 列中应显示 2/2。这表示 Pod 已成功注入 Envoy 边车代理。

  6. productcatalog v1 部署 VirtualServiceDestinationRule

    kubectl apply -f destination-vs-v1.yaml -n onlineboutique
    
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1

    请注意,资源中仅存在 v1

  7. 在浏览器中使用入站流量的外部 IP 地址访问应用:

    kubectl get services -n GATEWAY_NAMESPACE
    

下一部分将介绍 Cloud Service Mesh 界面,并说明如何查看指标。

在 Google Cloud 控制台中部署和查看您的服务

  1. 在 Google Cloud 控制台中,前往 GKE Enterprise 服务页面。

    前往 GKE Enterprise 服务

  2. 默认情况下,您可以在表格视图中查看服务。

    通过“表概览”,您可以一目了然地查看所有服务以及重要指标。

    所有服务工作负载

  3. 点击右上角的拓扑。在这里,您可以查看服务及其彼此的交互情况。

    您可以展开服务并将光标悬停在服务上以查看每个服务的每秒请求次数。

    所有服务工作负载拓扑

  4. 返回到表格视图

  5. 服务表中,选择 productcatalogservice。您将进入服务的概览。

  6. 在屏幕左侧,点击流量

  7. 确保 productcatalogservice 的所有传入流量都去往工作负载服务。

    productcatalog svc 流量

下一部分将介绍如何创建 productcatalog 服务的 v2 版。

部署服务的 v2 版

  1. 在本教程中,productcatalogservice-v2 将通过 EXTRA_LATENCY 字段向请求引入 3 秒的延迟。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productcatalogservice-v2
    spec:
      selector:
        matchLabels:
          app: productcatalogservice
      template:
        metadata:
          labels:
            app: productcatalogservice
            version: v2
        spec:
          containers:
          - env:
            - name: PORT
              value: '3550'
            - name: EXTRA_LATENCY
              value: 3s
            name: server
            image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.6
            livenessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            ports:
            - containerPort: 3550
            readinessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 64Mi
          terminationGracePeriodSeconds: 5

    将此资源应用于 onlineboutique 命名空间。

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. 查看应用 Pod。

    kubectl get pods -n onlineboutique
    

    预期输出:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-8wqfd                  2/2     Running   0          25h
    cartservice-c77f6b866-7jwcr                 2/2     Running   0          25h
    checkoutservice-654c47f4b6-n8c6x            2/2     Running   0          25h
    currencyservice-59bc889674-l5xw2            2/2     Running   0          25h
    emailservice-5b9fff7cb8-jjr89               2/2     Running   0          25h
    frontend-77b88cc7cb-bwtk4                   2/2     Running   0          25h
    loadgenerator-6958f5bc8b-lqmnw              2/2     Running   0          25h
    paymentservice-68dd9755bb-dckrj             2/2     Running   0          25h
    productcatalogservice-84f95c95ff-ddhjv      2/2     Running   0          25h
    productcatalogservice-v2-6df4cf5475-9lwjb   2/2     Running   0          8s
    recommendationservice-64dc9dfbc8-7s7cx      2/2     Running   0          25h
    redis-cart-5b569cd47-vw7lw                  2/2     Running   0          25h
    shippingservice-5488d5b6cb-dj5gd            2/2     Running   0          25h
    

    请注意,现在列出了两个 productcatalogservices

  3. DestinationRule 指定服务的子集。在此场景中,productcatalogservice 的 v1 版和 v2 版各有一个子集。

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
      - labels:
          version: v2
        name: v2

    注意 labels 字段。在 VirtualService 路由流量后,可以区分 productcatalogservice 的不同版本。

    应用 DestinationRule

    kubectl apply -f destination-v1-v2.yaml -n onlineboutique
    

在 v1 和 v2 之间拆分流量

  1. 您通过 VirtualService 将一小部分流量定向到 productcatalogservice 的 v2 版。

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1
          weight: 75
        - destination:
            host: productcatalogservice
            subset: v2
          weight: 25

    子集字段表示版本,权重字段表示流量拆分百分比。75% 的流量将流向 productcatalog 的 v1 版,25% 的流量将流向 v2 版。

    应用 VirtualService

    kubectl apply -f vs-split-traffic.yaml -n onlineboutique
    

如果您访问集群 Ingress 的 EXTERNAL_IP,应该会发现前端偶尔加载较慢。

在下一部分中,您将了解 GKE Enterprise Google Cloud 控制台中的流量拆分。

在 Google Cloud 控制台中观察流量拆分

  1. 返回 Google Cloud 控制台并前往 GKE Enterprise 服务页面 前往 GKE Enterprise 服务

  2. 点击右上角的拓扑

    展开 productcatalogservice 工作负载。您会看到 productcatalogserviceproductcatalogservice-v2 部署。

    productcatalog svc v1 v2 流量拓扑

  3. 返回到表格视图。点击服务表中的 productcatalogservice。返回左侧导航栏上的流量

  4. 请注意,传入流量按照 VirtualService 文件中指定的百分比在 v1 和 v2 之间拆分,并且有两个 productcatalog 服务工作负载。

    在屏幕右侧,您将看到请求数、错误率和延迟时间指标。借助 Cloud Service Mesh,每项服务都会获得这些指标的概述,以便为您提供可观测性。

    productcatalog svc v1 v2 流量

发布或回滚到某个版本

在观察 Canary 部署期间的指标后,您可以利用 VirtualService 资源发布到新服务或回滚到旧服务。

发布

对 v2 服务的行为感到满意后,您可以逐步增加流向 v2 服务的流量。最终,流量可以 100% 定向到新服务。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v2

如需将所有流量定向到 productcatalogservice 的 v2 版,请运行以下命令:

kubectl apply -f vs-v2.yaml -n onlineboutique

回滚

如果您需要回滚到 v1 服务,只需应用前面的 destination-vs-v1.yaml 即可。这会仅将流量定向到 productcatalogservice 的 v1 版。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v1

如需将所有流量定向到 productcatalogservice 的 v1 版,请运行以下命令:

kubectl apply -f vs-v1.yaml -n onlineboutique

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

为避免系统因本教程中使用的资源而导致您的 Google Cloud 账号继续产生费用,您可以删除项目或删除各个资源。

删除项目

  1. 在 Cloud Shell 中,删除项目:

    gcloud projects delete PROJECT_ID
    

删除资源

  • 如果您想防止产生额外费用,请删除集群:

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  • 如果您希望保留集群并移除 Online Boutique 示例,请执行以下操作:

    1. 删除应用命名空间:

      kubectl delete -f namespace onlineboutique
      

      预期输出:

      namespace "onlineboutique" deleted
      
    2. 删除服务条目:

      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend.yaml -n onlineboutique
      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend-gateway.yaml -n onlineboutique
      

      预期输出:

      serviceentry.networking.istio.io "allow-egress-googleapis" deleted
      serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
      

后续步骤

  • 如需查看有关如何配置 PeerAuthentication 政策的一般指南,请参阅配置传输安全性