1. 總覽
ASP.NET Core 是開放原始碼的跨平台架構,可使用 C# 程式設計語言建構現代化雲端和網際網路連線的應用程式。
Kubernetes 是開放原始碼系統,可自動部署、調度資源及管理容器化應用程式。Istio 是可用於連結、保護、管理及監控服務的開放式架構。
在研究室的第一部分,您會將簡單的 ASP.NET Core 應用程式部署至在 Google Kubernetes Engine (GKE) 上執行的 Kubernetes,並將其設為由 Istio 代管。
在研究室的第二部分,您將進一步探索 Istio 的功能,例如指標、追蹤、動態流量管理和容錯植入等。
課程內容
- 如何在 Docker 容器中建立及封裝簡易的 ASP.NET Core 應用程式。
- 瞭解如何使用 Google Kubernetes Engine (GKE) 建立 Kubernetes 叢集。
- 如何在 GKE 的 Kubernetes 叢集中安裝 Istio。
- 如何部署 ASP.NET Core 應用程式並設定其流量,讓 Istio 管理。
軟硬體需求
您會如何使用這個教學課程?
您對 Google Cloud Platform 的使用感想為何?
2. 設定和需求
自修環境設定
提醒您,專案 ID 是所有 Google Cloud 專案的專屬名稱 (已經有人使用上述名稱,很抱歉對您不符!)。稍後在本程式碼研究室中會稱為 PROJECT_ID
。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Google Cloud 資源。
執行這個程式碼研究室並不會產生任何費用,如果有的話。請務必依照「清除所用資源」一節指示本節將說明如何關閉資源,這樣您就不會產生本教學課程結束後產生的費用。Google Cloud 的新使用者符合 $300 美元免費試用計畫的資格。
啟動 Cloud Shell
雖然 Google Cloud 可以從筆記型電腦遠端操作,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是一種在 Google Cloud 中執行的指令列環境。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您先前從未啟動 Cloud Shell,您會看見中繼畫面 (需捲動位置),說明螢幕內容。如果出現這種情況,請按一下「繼續」 (之後不會再顯示)。以下是單次畫面的外觀:
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器搭載您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可以透過瀏覽器或 Chromebook 完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 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`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如果尚未設定,請使用下列指令進行設定:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
3. 在 Cloud Shell 建立 ASP.NET Core 應用程式
您可以透過 Cloud Shell 提示查看版本,確認是否已安裝 dotnet 指令列工具。這樣應該就會顯示已安裝的 dotnet 指令列工具版本:
dotnet --version
接著,建立新的 ASP.NET Core 網頁應用程式基本架構。
dotnet new mvc -o HelloWorldAspNetCore
這應該會建立專案並還原依附元件。顯示的訊息應如下所示。
Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.
Restore succeeded.
4. 執行 ASP.NET Core 應用程式
應用程式即將可以執行完畢。前往應用程式資料夾。
cd HelloWorldAspNetCore
最後,執行應用程式。
dotnet run --urls=http://localhost:8080
應用程式會開始監聽通訊埠 8080。
Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.
如要確認應用程式是否順利執行,請點選右上方的網頁預覽按鈕,然後選取「透過以下通訊埠預覽:8080」。
您會看到預設的 ASP.NET Core 網頁:
確認應用程式正在執行後,按下 Ctrl+C 鍵即可關閉應用程式。
5. 將 ASP.NET Core 應用程式封裝至 Docker 容器中
接下來,請準備讓應用程式以容器形式執行。第一步是定義容器及其內容。
在應用程式的基本目錄中,建立 Dockerfile
來定義 Docker 映像檔。
touch Dockerfile
使用您偏好的編輯器 (vim,
nano,emacs
或 Cloud Shell 的程式碼編輯器) 將以下內容新增至 Dockerfile
。
# Use Microsoft's official build .NET image. # https://hub.docker.com/_/microsoft-dotnet-core-sdk/ FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build WORKDIR /app # Install production dependencies. # Copy csproj and restore as distinct layers. COPY *.csproj ./ RUN dotnet restore # Copy local code to the container image. COPY . ./ WORKDIR /app # Build a release artifact. RUN dotnet publish -c Release -o out # Use Microsoft's official runtime .NET image. # https://hub.docker.com/_/microsoft-dotnet-core-aspnet/ FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime WORKDIR /app COPY --from=build /app/out ./ # Make sure the app binds to port 8080 ENV ASPNETCORE_URLS http://*:8080 # Run the web service on container startup. ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]
Dockerfile 中有一項重要的設定,就是應用程式要監聽連入流量的通訊埠 (8080)。方法是設定 ASPNETCORE_URLS
環境變數,ASP.NET Core 應用程式會使用該變數判斷要監聽的通訊埠。
儲存這個Dockerfile
。現在,要建構映像檔:
docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .
完成後 (請花一些時間下載並擷取所有內容),您就可以看到系統在本機建立並儲存圖片:
docker images REPOSITORY TAG gcr.io/yourproject-XXXX/hello-dotnet v1
使用下列指令在本機測試映像檔,會從新建立的容器映像檔,在本機的通訊埠 8080 執行 Docker 容器:
docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1
也可以再次利用 CloudShell 的網頁預覽功能:
您應該會在新分頁中看到預設的 ASP.NET Core 網頁。
確認應用程式在 Docker 容器中正常執行後,即可在 Ctrl-> C
前停止執行中的容器。
映像檔現已如預期運作,您可以將其推送至 Google Container Registry,這是 Docker 映像檔的私人存放區,可從每個 Google Cloud 專案存取 (但也可從 Google Cloud Platform 外部存取):
docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1
如果一切順利,一段時間後,您應該就能在 Container Registry 區段中看到容器映像檔。此時,您已取得適用於專案層級的 Docker 映像檔,請稍待幾分鐘,Kubernetes 可以用來存取及自動化調度管理。
如果想瀏覽儲存在 Google Cloud Storage 中的容器映像檔,請點選以下連結:https://console.cloud.google.com/storage/browser/ (完整的圖片連結格式如下:https://console.cloud.google.com/project/PROJECT_ID/storage/browser/)。
6. 使用 Istio 建立 Kubernetes/GKE 叢集
首先,請確認您已啟用 Kubernetes Engine API:
gcloud services enable container.googleapis.com
建立 Kubernetes 叢集。您可以視需要將區域變更為離您更近的地點:
gcloud container clusters create hello-istio \ --cluster-version=latest \ --machine-type=n1-standard-2 \ --num-nodes=4 \ --region europe-west1
正在為您設定叢集,請稍候片刻。這個名稱會顯示在 Google Cloud Platform 控制台的 Kubernetes Engine 區段中。
在本程式碼研究室中,我們會從 istio.io 下載並安裝 Istio。您也可以採用其他安裝選項,包括 GKE 適用的 Istio 外掛程式和 Anthos 服務網格。完成上述步驟後的應用程式步驟將適用於所有安裝的 Istio。
首先,請下載 Istio 用戶端和範例。Istio 版本頁面提供多個 OS 的下載構件。在本範例中,我們可以使用便利的指令下載和擷取目前平台的最新版本:
curl -L https://istio.io/downloadIstio | sh -
指令碼會顯示已下載的 Istio 版本:
Istio has been successfully downloaded into the istio-1.8.1 folder on your system.
安裝目錄包含範例應用程式和 istioctl
用戶端二進位檔。請變更為該目錄:
cd istio-1.8.1
複製及貼上提供的指令,將 bin
目錄新增至 PATH
,即可使用 istioctl
:
export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"
檢查叢集是否可用於 Istio,確認 istioctl
可以使用:
istioctl x precheck
您應該會看到顯示「Install Pre-Check passed! The cluster is ready for Istio installation.
」的訊息
使用示範設定檔安裝 Istio:
istioctl install --set profile=demo
您的叢集現已安裝 Istio。
自動插入補充資訊
如要開始使用 Istio,您無須對應用程式進行任何變更。當您設定並執行服務時,系統會自動將 Envoy 補充資訊插入服務的各個 Pod。
為此,您必須針對微服務使用的命名空間 (「預設」) 啟用補充插入功能。您只要套用標籤即可:
kubectl label namespace default istio-injection=enabled
如要確認標籤是否已成功套用,請執行下列指令:
kubectl get namespace -L istio-injection
輸出結果會確認預設命名空間已啟用補充插入功能:
NAME STATUS AGE ISTIO-INJECTION default Active 3m enabled istio-system Active 63s disabled ...
7. 驗證安裝
Istio 提供三種服務:istiod
控制層,以及輸入和輸出閘道 (可視為「網際網路其餘部分的邊車 Proxy」),分別命名為 istio-ingressgateway
和 istio-egressgateway
。
kubectl get svc -n istio-system
輸出內容應如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP AGE istio-egressgateway ClusterIP 10.55.252.182 <none> istio-ingressgateway LoadBalancer 10.55.250.185 35.233.118.42 istiod ClusterIP 10.55.253.217 <none>
Ingress Gateway 屬於 LoadBalancer
類型,可透過網際網路存取。其餘的只需從叢集內部存取
接著,請確認已部署對應的 Kubernetes Pod,且所有容器都已正常執行:
kubectl get pods -n istio-system
所有 Pod 都執行完畢後,即可繼續操作。
NAME READY STATUS istio-egressgateway-674988f895-m6tk4 1/1 Running istio-ingressgateway-6996f7dcc8-7lvm2 1/1 Running istiod-6bf5fc8b64-j79hj 1/1 Running
istiod
:Istio 控制層。處理 Proxy 補充資訊、服務探索、憑證發布和補充資訊插入的設定和程式設計ingress gateway
:處理來自叢集外部的傳入要求。egress gateway
:處理向叢集外端點發出的傳出要求。
8. 部署應用程式
您已確認已安裝並執行 Istio,現在可以部署 ASP.NET Core 應用程式。
部署和服務
首先,使用您慣用的編輯器 (vim, nano,emacs
或 Cloud Shell 的程式碼編輯器) 建立 aspnetcore.yaml
檔案,然後定義應用程式的 Kubernetes Deployment 和 Service:
apiVersion: v1 kind: Service metadata: name: aspnetcore-service labels: app: aspnetcore spec: ports: - port: 8080 name: http selector: app: aspnetcore --- apiVersion: apps/v1 kind: Deployment metadata: name: aspnetcore-v1 spec: replicas: 1 selector: matchLabels: app: aspnetcore version: v1 template: metadata: labels: app: aspnetcore version: v1 spec: containers: - name: aspnetcore image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 8080
檔案內容是部署應用程式的標準 Deployment 和 Service,不含任何 Istio 特定的內容。
使用 kubectl
將服務部署至預設命名空間:
kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created deployment.extensions "aspnetcore-v1" created
確認 Pod 正在執行:
kubectl get pods
NAME READY STATUS RESTARTS AGE aspnetcore-v1-6cf64748-mddb 2/2 Running 0 34s
Gateway 和 VirtualService
如要允許輸入流量進入網格,您必須建立 Gateway 和 VirtualService。
閘道會設定 HTTP/TCP 流量的負載平衡器,通常在網格邊緣運作,為應用程式啟用輸入流量。VirtualService 定義的規則會控管服務要求在 Istio 服務網格中的轉送方式,
建立 aspnetcore-gateway.yaml
檔案來定義閘道:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: aspnetcore-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
建立 aspnetcore-virtualservice.yaml
檔案來定義 VirtualService:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - route: - destination: host: aspnetcore-service
使用下列指令執行 kubectl 指令來部署閘道:
kubectl apply -f aspnetcore-gateway.yaml
這個指令會產生下列輸出內容:
gateway.networking.istio.io "aspnetcore-gateway" created
接下來,請執行下列指令來部署 VirtualService:
kubectl apply -f aspnetcore-virtualservice.yaml
這個指令會產生下列輸出內容:
virtualservice.networking.istio.io "aspnetcore-virtualservice" created
確認一切運作正常:
kubectl get gateway
NAME AGE aspnetcore-gateway 28s
kubectl get virtualservice
NAME AGE aspnetcore-virtualservice 33s
恭喜!您剛剛部署了支援 Istio 的應用程式。接下來,您會看到使用中的應用程式。
9. 測試應用程式
最終,您可以查看應用程式實際運作情形。您必須取得閘道的外部 IP 和通訊埠。SDK 列在 EXTERNAL-IP
中:
kubectl get svc istio-ingressgateway -n istio-system
將外部 IP 和通訊埠匯出為 GATEWAY_URL
變數:
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}') export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
使用 curl
測試應用程式。服務應以 200
的回應代碼回應:
curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/
或者,您也可以開啟瀏覽器,前往 http://<gatewayurl>
查看應用程式:
10. 恭喜!
您剛剛將簡易的 ASP.NET Core 應用程式部署至在 Google Kubernetes Engine (GKE) 上執行的 Kubernetes,並設定為由 Istio 代管。
您可能會想「Istio 有哪些優點?」。好問題!到目前為止,由 Istio 管理這個應用程式沒有好處。在研究室的第二部分,我們會進一步探索 Istio 的功能,例如指標、追蹤、動態流量管理、服務視覺化和錯誤植入。
後續步驟
- 使用 Istio 將 ASP.NET Core 應用程式部署至 GKE (第 2 部分)。
- 進一步瞭解 Istio。
- 進一步瞭解 Kubernetes。
- 進一步瞭解 Google Kubernetes Engine。
- 進一步瞭解 Google Cloud Platform 上的 .NET。
授權
這項內容採用的是創用 CC 姓名標示 2.0 通用授權。
11. 清除
如果您未進入研究室的第二部分,可以刪除應用程式並解除安裝 Istio,或是直接刪除 Kubernetes 叢集。
刪除應用程式
如要刪除該應用程式:
kubectl delete -f aspnetcore-gateway.yaml Kubectl delete -f aspnetcore-virtualservice.yaml kubectl delete -f aspnetcore.yaml
如何確認應用程式已消失:
kubectl get gateway kubectl get virtualservices 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-istio