Cloud Service Mesh 示例:Canary 部署


在本教程中,您将了解一个常见用例:使用 Istio API 通过 Cloud Service Mesh 发布 Canary 部署。

什么是 Canary 部署?

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

费用

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

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

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

准备工作

部署 Online Boutique

  1. kubectl 的当前上下文设置为您计划部署 Online Boutique 的集群。该命令取决于您是在 GKE 集群上还是在 GKE 之外的 Kubernetes 集群上预配了 Cloud Service Mesh:

    GKE on Google Cloud

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    

    Google Cloud 外部的 GKE

    kubectl config use-context CLUSTER_NAME 
    
  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
    

    如果 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 控制台中,前往 Google Kubernetes Engine (GKE) 企业版服务页面。

    前往“Google Kubernetes Engine (GKE) Enterprise 版本服务”

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

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

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

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

  4. 返回到表格视图

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

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

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

下一部分将介绍如何创建 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,应该会发现前端偶尔加载较慢。

在下一部分中,探索 Google Cloud 控制台中的流量拆分。

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

  1. 返回 Google Cloud 控制台,然后前往 GKE Enterprise 服务页面。 前往 GKE Enterprise 服务

  2. 点击右上角的拓扑

    展开 productcatalogservice 工作负载,并记下 productcatalogserviceproductcatalogservice-v2 部署。

  3. 返回到表格视图

  4. 点击“服务”表中的 productcatalogservice

  5. 返回左侧导航栏上的流量

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

    在页面右侧,您会看到请求数错误率延迟时间指标。 使用 Cloud Service Mesh,每个服务都会具有这些指标的概览,以为您提供可观测性指标。

发布或回滚到某个版本

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

发布

对 v2 服务的行为感到满意后,您可以逐步增加流向 v2 服务的流量百分比。最终,您可以从上述 VirtualService 资源中移除流量拆分,将所有流量定向到该资源中的新服务。

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 账号继续产生费用,您可以删除项目或删除各个资源。

删除项目

在 Cloud Shell 中,删除项目:

gcloud projects delete PROJECT_ID

删除资源

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

gcloud container clusters delete  CLUSTER_NAME  \
  --project=PROJECT_ID \
  --zone=CLUSTER_LOCATION 

如果您使用 gcloud container fleet memberships(而不是在创建集群期间使用 --enable-fleet--fleet-project)向舰队注册了集群,请移除过时的成员资格:

gcloud container fleet memberships delete  MEMBERSHIP  \
  --project=PROJECT_ID

如果您希望保留为 Cloud Service Mesh 配置的集群,但移除 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 政策的一般指南,请参阅配置传输安全性