透過 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-ZbJa08jwJqtmeeW8j9DLZDLZDLA

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

如果您從未啟動 Cloud Shell,您會看見中繼畫面 (需捲動位置),說明螢幕內容。如果出現這種情況,請按一下「繼續」 (之後不會再顯示)。以下是單次畫面的外觀:

VgsaqGbKPRiqK24CqAKjSXjepuJT96PmiDqQMcySmWKx8QyW5F3G2D8JH2d08ek-YM77wWKxPvggpOFER8Hbq3aaZipTDU2ozuil7A0kS3FXEmqDMqDMqDMqD

佈建並連線至 Cloud Shell 只需幾分鐘的時間。

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

這部虛擬機器都裝載了您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 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. 測試應用程式

開始研究室之前,請先確認先前研究室中的應用程式仍可正常運作。提醒您,以下是 EXTERNAL-IP 底下列出的閘道外部 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

如要進一步瞭解 Granfana,請參閱使用 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 建構網頁應用程式」訊息:

11d528132dbb6cee.png

在其他情況下,系統會顯示「瞭解如何在 Google Cloud 上使用 ASP.NET Core 建構網頁應用程式」訊息:

3eb0d5be1b4cb40b.png

這是因為 v1v2 Deployment 會在同一項 Kubernetes 服務 (aspnetcore-service) 中公開,而您在上一個研究室 (aspnetcore-virtualservice) 中建立的 VirtualService 則會將該服務做為主機使用。

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

7. 將服務固定至新版本

在這個步驟中,您會釘選服務以使用 v2 部署,並可透過 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。這項操作會建立兩個可透過 VirtualService 使用的子集 (v1 和 v2):

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 建構網頁應用程式」訊息:

3eb0d5be1b4cb40b.png

8. 在版本之間拆分流量

有時候,您可能會想將流量拆分至不同版本以進行測試。舉例來說,您可以把 75% 的流量傳送到第 1 版和第 25% 的服務。您可以使用 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。

後續步驟

授權

這項內容採用的是創用 CC 姓名標示 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