Cloud Service Mesh 範例:初期測試部署


本教學課程將逐步介紹常見用途:使用 Istio API 透過 Cloud Service Mesh 推出 Canary 部署。

什麼是初期測試部署?

初期測試部署會將少部分流量路由至新版微服務,然後逐漸提高該比重,同時逐步淘汰舊版。如果這個程序發生錯誤,您可以將流量切換回先前的版本。您可以使用 Cloud Service Mesh 重新導向流量,確保新服務的導入作業安全無虞。

費用

在本文件中,您會使用 Google Cloud的下列計費元件:

您可以使用 Pricing Calculator 根據預測用量產生預估費用。 新 Google Cloud 使用者可能符合申請免費試用的資格。

完成本教學課程後,您可以刪除已建立的資源,以免持續產生費用。詳情請參閱「清除所用資源」。

事前準備

部署 Online Boutique

  1. kubectl 的目前情境設為您要部署 Online Boutique 的叢集。這項指令取決於您是在 GKE 叢集或 GKE 以外的 Kubernetes 叢集中佈建 Cloud Service Mesh:

    Google Cloud 上的 GKE

    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 Proxy。請按照這篇文章中的步驟啟用自動副載注入功能。

  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. 執行下列指令,將標籤 version=v1 新增至 productcatalog 部署作業:

    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 UI,並說明如何查看指標。

在 Google Cloud 控制台中查看服務

  1. 在 Google Cloud 控制台中,前往「Google Kubernetes Engine (GKE) Enterprise 版服務」頁面。

    前往 Google Kubernetes Engine (GKE) Enterprise 版服務

  2. 根據預設,您會在「清單」檢視畫面中查看服務。

    您可以透過「表格總覽」一覽所有服務和重要指標。

  3. 按一下右上方的「拓樸圖」。您可以在這裡查看服務和服務之間的互動情形。

    您可以展開「Services」,並將游標懸停在各項服務上,查看每項服務的「Requests per second」

  4. 返回「表格檢視」

  5. 在「Services Table」(服務表格) 中,選取 productcatalogservice。即可查看服務總覽。

  6. 按一下畫面左側的「流量」

  7. 請務必將 productcatalogservice 的 100% 傳入流量導向工作負載服務。

下一節將說明如何建立 productcatalog 服務的 2.0 版。

部署服務的 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
    

如果您造訪叢集入口的 EXTERNAL_IP,您應該會發現前端載入速度會變慢。

在下一節中,我們將在 Google Cloud 控制台中探索流量分配。

在 Google Cloud 控制台中觀察流量分配

  1. 返回 Google Cloud 控制台,前往 GKE Enterprise Services 頁面。 前往 GKE Enterprise 服務

  2. 按一下右上方的「拓樸圖」

    展開 productcatalogservice 工作負載,並記下 productcatalogserviceproductcatalogservice-v2 部署。

  3. 返回「Table View」

  4. 按一下「服務」表格中的 productcatalogservice

  5. 返回左側導覽列中的「流量」

  6. 請注意,傳入流量會根據 VirtualService 檔案中指定的百分比,在 v1 和 v2 之間進行分配,且 productcatalog 服務有 2 個工作負載。

    頁面右側會顯示「要求」、「錯誤率」和「延遲時間指標」。在 Cloud Service Mesh 中,每項服務都會提供這些指標,讓您瞭解可觀察性指標。

推出或復原至某個版本

在初期測試版本部署期間觀察指標後,您可以完成新服務版本的推出作業,或是利用 VirtualService 資源回溯至原始服務版本。

推出

當您對 v2 服務的行為感到滿意後,就可以逐步提高流量轉送至 v2 服務的百分比。最後,您可以從該資源移除流量分配,將流量 100% 轉送至您在上述步驟中建立的 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
    

後續步驟