透過 Istio 將 ASP.NET Core 應用程式部署至 Google Kubernetes Engine (第 2 部分)

1. 總覽

在實驗室的第一部分中,您建立了 ASP.NET Core 應用程式、容器化,並部署至 Google Kubernetes Engine (GKE),然後設定由 Istio 管理流量。

本實驗室的第二部分假設您已執行第一個實驗室的 Kubernetes 叢集和應用程式。您會瞭解如何透過 Istio 管理、監控及保護服務,而且不必大幅變更程式碼。具體來說,您會探索 Istio 的各項功能,例如指標、追蹤、服務視覺化、動態流量管理、錯誤植入等。

課程內容

  • 如何使用 Prometheus 查詢指標。
  • 如何使用 Grafana 視覺化指標。
  • 如何建立新版服務。
  • 如何將服務固定在特定版本。
  • 如何拆分不同版本之間的流量。
  • 如何在服務呼叫中注入錯誤。

軟硬體需求

您會如何使用本教學課程?

僅閱讀 閱讀並完成練習

你對 Google Cloud Platform 的使用體驗滿意嗎?

新手 中級 熟練

2. 設定和需求

自修實驗室環境設定

  1. 登入 Cloud 控制台,建立新專案或重複使用現有專案。(如果沒有 Gmail 或 G Suite 帳戶,請先建立帳戶)。

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

請記住專案 ID,這是所有 Google Cloud 專案中不重複的名稱 (上述名稱已遭占用,因此不適用於您,抱歉!)。本程式碼研究室稍後會將其稱為 PROJECT_ID

  1. 接著,您必須在 Cloud 控制台中啟用帳單,才能使用 Google Cloud 資源。

完成本程式碼研究室的費用應該不高,甚至完全免費。請務必按照「清除」部分的指示操作,瞭解如何停用資源,避免在本教學課程結束後繼續產生帳單費用。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。

啟動 Cloud Shell

雖然您可以透過筆電遠端操作 Google Cloud,但在本程式碼研究室中,您會使用 Google Cloud Shell,這是 Google Cloud 中執行的指令列環境。

啟用 Cloud Shell

  1. 在 Cloud 控制台,點選「啟用 Cloud Shell」 圖示 dnDTxS9j60RcXdTjea12HLB9paS9Gzf7PfFLE9RW8g0Qx1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtmeeW8jZ1tYfi2lyXqvW3WFHP0eAxDkQDfpO9Ljw

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

如果您是首次啟動 Cloud Shell,系統會顯示中繼畫面 (摺疊式螢幕下方),說明這個指令列環境。點選「繼續」後,這則訊息日後就不會再出現。以下是這個初次畫面的樣子:

VgsaqGbKPRiqK24CqAKjSXjepuJT96PmiDqQMcySmWKx8QyW5F3G2D8JH2d08ek-YM77wWKxPvggpOFER8Hbq3aaZipTDU2o0il7A0kS3FXY_NzuujjEqDF1nsbDKkNMThrqcdMGtQ

佈建並連至 Cloud Shell 預計只需要幾分鐘。

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

這部虛擬機器搭載各種您需要的開發工具,並提供永久的 5GB 主目錄,而且可在 Google Cloud 運作,大幅提升網路效能並強化驗證功能。本程式碼研究室幾乎所有工作都可在瀏覽器或 Chromebook 上完成。

連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。

  1. 在 Cloud Shell 中執行下列指令,確認您已通過驗證:
gcloud auth list

指令輸出

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

指令輸出

[core]
project = <PROJECT_ID>

如未設定,請輸入下列指令手動設定專案:

gcloud config set project <PROJECT_ID>

指令輸出

Updated property [core/project].

3. 測試應用程式

開始實驗室前,請確認應用程式仍可正常運作 (如上一個實驗室所示)。提醒您,閘道的外部 IP 和通訊埠會列在 EXTERNAL-IP 下方,如下所示:

kubectl get svc istio-ingressgateway -n istio-system

如要查看應用程式,請開啟瀏覽器並前往 http://<gatewayurl>

f579a9baedc108a9.png

如果沒有看到應用程式,請返回上一個實驗室,確認您已完成所有步驟,且應用程式和 Istio 都已安裝並正常運作。

此時,您可能會想問「Istio 有什麼好處?」。讓 Istio 管理應用程式流量,即可免費使用指標、追蹤、動態流量管理、服務視覺化、錯誤注入等功能。

您將在下一個步驟中開始探索指標。

4. 使用 Grafana 和 Prometheus 監控指標

根據預設,Istio 會產生部分指標。您可以使用外掛程式查詢及顯示這些預設指標。

Prometheus

Prometheus 是開放原始碼監控解決方案。您可以使用 Prometheus 查詢 Istio 產生的指標,但必須先安裝 Prometheus 外掛程式。

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml

確認 Prometheus 正在執行:

kubectl get svc prometheus -n istio-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.31.243.62   <none>        9090/TCP   1d

多次造訪 http://<gatewayurl> 或執行 curl 指令,將部分流量傳送至應用程式。

設定 Prometheus UI 的通訊埠轉送:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090

現在,您可以點選 Cloud Shell 右上角的「網頁預覽」按鈕,然後按一下「透過以下通訊埠預覽:8080」,執行查詢:

772a5248aa493025.png

新分頁會顯示 Prometheus UI:

272ee63c1fe0be16.png

如要進一步瞭解 Prometheus,請參閱「使用 Prometheus 查詢指標」。

Grafana

Grafana 是另一個用於將指標視覺化的外掛程式。

安裝 Grafana。將 istio-version 替換為目前的 Istio 版本,例如 1.0.3-gke.3

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml

確認 Grafana 正在執行:

kubectl get svc grafana -n istio-system

NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.31.248.230   <none>        3000/TCP   1d

多次造訪 http://<gatewayurl> 或執行 curl 指令,將部分流量傳送至應用程式。

設定 Grafana UI 的通訊埠轉送:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000

如要查看 Grafana 資訊主頁,請前往「網頁預覽」:

806d696d85267a37.png

524cb9f6d66f8655.png

如要進一步瞭解 Grafana,請參閱「使用 Grafana 將指標視覺化」。

5. 建立新版應用程式

您部署到實際工作環境的應用程式,在某個時間點會需要修正錯誤或新增功能。讓我們看看這個流程。

首先,請修改應用程式。從 Cloud Shell 開啟程式碼編輯器。

mxrggIJ2Zz8E47ULCEo4NywjM-EpSkZF5c3TQgfGx4nODwP2obiQXrwQjEEaXuBhJDA2jJ5evR7TuHIy1gsqqDRFm0Wh3xhZUu9tn_xb1ygFlBm1HKJqLdfz_aK7WJS33u2IBDO2oQ

前往「HelloWorldAspNetCore > Views > Home」下方的「Index.cshtml」,然後更新其中一則輪轉介面訊息。

找出以下程式碼:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

並變更為以下程式碼:

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

儲存變更,然後返回 Cloud Shell。在 HelloWorldAspNetCore, 內建構 Docker 映像檔:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

然後推送到 Container Registry:

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

推送容器映像檔後,即可在下一個步驟中部署新版本。

6. 建立新的部署作業

如要部署新版本,您必須先在 Kubernetes 中為該版本建立新的部署作業。在 aspnetcore.yaml 檔案結尾處加入以下內容:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v2
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v2
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

使用 kubectl 將新版本部署至預設命名空間:

kubectl apply -f aspnetcore.yaml
service "aspnetcore" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created

確認預期 Pod 正在執行:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s
aspnetcore-v2-5d765db-l9xmg   2/2       Running   0          1m

現在,請再次測試應用程式。取得閘道的外部 IP:

kubectl get svc istio-ingressgateway -n istio-system

這項資訊會列在「EXTERNAL-IP」下方。開啟無痕瀏覽器,然後前往 http://<replace-with-external-ip>

重新整理時,有時會看到「瞭解如何使用 ASP.NET Core 建構 Web 應用程式」訊息:

11d528132dbb6cee.png

有時您會看到「瞭解如何使用 Google Cloud 上的 ASP.NET Core 建構網頁應用程式」訊息:

3eb0d5be1b4cb40b.png

這是因為 v1v2 部署作業都公開在同一個 Kubernetes 服務 (aspnetcore-service) 後方,而您在上一個實驗室中建立的 VirtualService (aspnetcore-virtualservice) 會將該服務做為主機。

在下一個步驟中,您將使用 DestinationRule 將服務固定至 v2 部署作業。

7. 將服務固定在新版本

在這個步驟中,您會將服務固定為使用 v2 部署作業,這項作業可透過 DestinationRule 執行。DestinationRule 會設定一組政策,在 VirtualService 路由作業發生後套用至要求。

DestinationRule 也會定義對應目的地主機的可定址子集,也就是具名版本。將流量傳送至特定服務版本時,VirtualService 路由規格會使用這些子集。

建立名為 aspnetcore-destinationrule.yaml 的新檔案:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: aspnetcore-destinationrule
spec:
  host: aspnetcore-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

接著,建立 DestinationRule。這會建立兩個子集 (v1 和 v2),您可從 VirtualService 使用:

kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destionationrule" created

現在請返回 aspnetcore-virtualservice.yaml 檔案,更新 VirtualService 以使用 v2 子集:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v2

更新 VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

開啟瀏覽器並前往 http://<replace-with-external-ip>. 即使多次重新整理,您也應該會看到「瞭解如何在 Google Cloud 上使用 ASP.NET Core 建構 Web 應用程式」訊息:

3eb0d5be1b4cb40b.png

8. 在各版本之間拆分流量

有時,您可能想在不同版本之間拆分流量,以便進行測試。舉例來說,您可能想將 75% 的流量傳送至 v1 版服務,25% 的流量傳送至 v2 版服務。使用 Istio 即可輕鬆達成這個目標。建立新的 aspnetcore-virtualservice-weights.yaml 檔案,參照兩個不同權重的子集:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v1
      weight: 75
    - destination:
        host: aspnetcore-service
        subset: v2
      weight: 25

更新 VirtualService:

kubectl apply -f aspnetcore-virtualservice-weights.yaml

現在重新整理瀏覽器時,您應該會看到系統放送 v1 和 v2 版本,比例約為 3:1。

詳情請參閱「Istio 中的流量分配」。

9. 注入錯誤

另一個有用的開發工作是將錯誤或延遲注入流量,並查看服務的因應方式。

舉例來說,您可能想針對傳送至 v1 版本的流量,有 50% 的機率傳回錯誤要求 (HTTP 400) 回應。建立符合下列條件的 aspnetcore-virtualservice-fault-abort.yaml 檔案:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      abort:
        percentage:
          value: 50
        httpStatus: 400
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

更新 VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml

現在重新整理瀏覽器時,您應該會發現 v1 服務有一半的時間會傳回 HTTP 400s 回應代碼。

或者,您可能想在要求中加入 5 秒的延遲時間。建立符合下列條件的 aspnetcore-virtualservice-fault-delay.yaml 檔案:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percentage:
          value: 100
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

更新 VirtualService:

kubectl apply -f aspnetcore-virtualservice-fault-delay.yaml

現在重新整理瀏覽器,您應該會看到要求延遲了 5 秒。

如要進一步瞭解 Istio 功能,例如逾時、重試、條件規則、斷路器等,請參閱流量管理功能

10. 恭喜!

希望這個實驗室能讓您概略瞭解 Istio 可為服務提供的現成功能。進一步瞭解 Istio 和 GKE。

後續步驟

授權

這項內容採用的授權為 Creative Commons 姓名標示 2.0 通用授權。

11. 清除

您可以刪除應用程式並解除安裝 Istio,也可以直接刪除 Kubernetes 叢集。

刪除應用程式

如要刪除應用程式:

kubectl delete -f aspnetcore-gateway.yaml
kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore-destinationrule.yaml
kubectl delete -f aspnetcore.yaml

如要確認應用程式已移除,請按照下列步驟操作:

kubectl get gateway 
kubectl get virtualservices
kubectl get destinationrule
kubectl get pods

解除安裝 Istio

如要刪除 Istio,請執行下列操作:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

確認 Istio 已移除:

kubectl get pods -n istio-system

刪除 Kubernetes 叢集

gcloud container clusters delete hello-dotnet-cluster