Cloud Service Mesh 是一項強大的工具,可用於管理及監控分散式應用程式。如要充分運用 Cloud Service Mesh,建議您瞭解其基礎抽象概念,包括容器和 Kubernetes。本教學課程說明如何為 Cloud Service Mesh 準備應用程式,從原始碼到在 GKE 上執行的容器,一直到安裝 Cloud Service Mesh 之前。
如果您已熟悉 Kubernetes 和服務網格概念,可以略過本教學課程,直接參閱 Cloud Service Mesh 安裝指南。
目標
- 探索簡單的多服務「Hello World」應用程式。
- 從來源執行應用程式
- 將應用程式容器化。
- 建立 Kubernetes 叢集。
- 將容器部署至叢集。
事前準備
請依照下列步驟啟用 Cloud Service Mesh API:- 前往 Google Cloud 控制台的 Kubernetes Engine 頁面。
- 建立或選取專案。
- 等待 API 和相關服務完成啟用。 這可能需要幾分鐘的時間。
-
Make sure that billing is enabled for your Google Cloud project.
本教學課程使用 Cloud Shell,可佈建執行以 Debian 為基礎的 Linux 作業系統的 g1-small Compute Engine 虛擬機器 (VM)。
準備 Cloud Shell
使用 Cloud Shell 的好處如下:
- Python 2 和 Python 3 開發環境 (包括
virtualenv
) 都已設定完成。 - 本教學課程中使用的
gcloud
、docker
、git
和kubectl
指令列工具已安裝。 您可以選擇文字編輯器:
程式碼編輯器:按一下 Cloud Shell 視窗頂端的 即可存取。
Emacs、Vim 或 Nano,可透過 Cloud Shell 中的指令列存取。
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
下載程式碼範例
下載
helloserver
原始碼:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
變更為範例程式碼目錄:
cd anthos-service-mesh-samples/docs/helloserver
探索多服務應用程式
這個應用程式範例是以 Python 編寫,其中包含兩個使用 REST 通訊的元件:
server
:簡單的伺服器,其中包含一個GET
端點/
,會將「hello world」字串輸出至控制台。loadgen
:用於將流量傳送至server
的腳本,可設定每秒要求數 (RPS)。
從來源執行應用程式
如要熟悉範例應用程式,請在 Cloud Shell 中執行該應用程式。
在
sample-apps/helloserver
目錄中執行server
:python3 server/server.py
在啟動時,
server
會顯示以下內容:INFO:root:Starting server...
開啟另一個終端機視窗,以便您向
server
傳送要求。按一下 即可開啟其他工作階段。傳送要求至
server
:curl http://localhost:8080
server
回應:Hello World!
從下載範例程式碼的目錄,變更為包含
loadgen
的目錄:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/loadgen
建立下列的環境變數:
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
啟動
virtualenv
:virtualenv --python python3 env
啟用虛擬環境:
source env/bin/activate
安裝
loadgen
的必要條件:pip3 install -r requirements.txt
執行
loadgen
:python3 loadgen.py
在啟動時,
loadgen
會輸出類似以下的訊息:Starting loadgen: 2019-05-20 10:44:12.448415 5 request(s) complete to http://localhost:8080
在另一個終端機視窗中,
server
會將訊息寫入主控台,類似以下內容:127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */*
從網路連線的角度來看,整個應用程式現在都在同一個主機上執行。因此,您可以使用
localhost
將要求傳送至server
。如要停止
loadgen
和server
,請在每個終端機視窗中輸入Ctrl-c
。在
loadgen
終端機視窗中,停用虛擬環境:deactivate
將應用程式容器化
如要在 GKE 上執行應用程式,您必須將範例應用程式 (server
和 loadgen
) 封裝為容器。容器是封裝應用程式的方法,可將應用程式與基礎環境隔離。
如要將應用程式裝載到容器中,您需要 Dockerfile
。Dockerfile
是文字檔案,用於定義將應用程式原始碼及其依附元件組合成 Docker 映像檔所需的指令。建構映像檔後,請將其上傳至容器登錄,例如 Docker Hub 或 Container Registry。
範例會提供 server
和 loadgen
的 Dockerfile
,其中包含建構映像檔所需的所有指令。以下是 server
的 Dockerfile
:
FROM python:3-slim as base
指令會指示 Docker 使用最新的 Python 3 映像檔做為基礎映像檔。COPY . .
指令會將目前工作目錄中的來源檔案 (在本例中為server.py
) 複製到容器的檔案系統中。ENTRYPOINT
會定義用於執行容器的指令。在這種情況下,指令幾乎與您用來從原始碼執行server.py
時的指令相同。EXPOSE
指令會指定server
監聽通訊埠8080
。這個指令不會公開任何通訊埠,但會做為說明文件,說明您在執行容器時需要開啟通訊埠8080
。
準備將應用程式裝載到容器中
設定下列環境變數。將
PROJECT_ID
替換為Google Cloud 專案的 ID。export PROJECT_ID="PROJECT_ID"
export GCR_REPO="asm-ready"
您可以使用
PROJECT_ID
和GCR_REPO
的值,在建構 Docker 映像檔並推送至私人 Container Registry 時標記映像檔。為 Google Cloud CLI 設定預設 Google Cloud 專案。
gcloud config set project $PROJECT_ID
設定 Google Cloud CLI 的預設區域。
gcloud config set compute/zone us-central1-b
請確認您已在Google Cloud 專案中啟用 Container Registry 服務。
gcloud services enable containerregistry.googleapis.com
將 server
容器化
變更至範例
server
所在的目錄:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
使用先前定義的
Dockerfile
和環境變數建構映像檔:docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
-t
標記代表 Docker 標記。這是您在部署容器時使用的映像檔名稱。將映像檔推送至 Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
將 loadgen
容器化
變更至範例
loadgen
所在的目錄:cd ../loadgen
建構映像檔:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .
將映像檔推送至 Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1
列出圖片
取得存放區中的映像檔清單,確認是否已推送映像檔:
gcloud container images list --repository gcr.io/$PROJECT_ID/asm-ready
指令會傳回您剛推送的圖片名稱:
NAME gcr.io/PROJECT_ID/asm-ready/helloserver gcr.io/PROJECT_ID/asm-ready/loadgen
建立 GKE 叢集
您可以使用 docker run
指令,在 Cloud Shell VM 上執行這些容器。但在實際工作環境中,您需要以更統一的方式協調容器。舉例來說,您需要一個系統來確保容器一律運作,並需要一種方法來擴充並啟動容器的其他執行個體,以便處理流量增加的問題。
您可以使用 GKE 執行容器化應用程式。GKE 是容器調度平台,可將 VM 連線至叢集。每個 VM 都稱為「節點」。GKE 叢集是由 Kubernetes 開放原始碼叢集管理系統提供技術支援。您可以透過 Kubernetes 提供的機制與叢集互動。
如要建立 GKE 叢集,請按照下列步驟操作:
建立叢集:
gcloud container clusters create asm-ready \ --cluster-version latest \ --machine-type=n1-standard-4 \ --num-nodes 4
gcloud
指令會在您先前設定的Google Cloud 專案和區域中建立叢集。如要執行 Cloud Service Mesh,建議您至少使用 4 個節點和 n1-standard-4 機器類型。建立叢集的指令需要幾分鐘才能完成。叢集就緒後,指令會輸出類似以下的訊息:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS asm-ready us-central1-b 1.13.5-gke.10 203.0.113.1 n1-standard-2 1.13.5-gke.10 4 RUNNING
將憑證提供給
kubectl
指令列工具,以便使用該工具管理叢集:gcloud container clusters get-credentials asm-ready
您現在可以使用
kubectl
與 Kubernetes 通訊。例如,您可以執行下列指令取得節點的狀態:kubectl get nodes
指令會傳回節點清單,如下所示:
NAME STATUS ROLES AGE VERSION gke-asm-ready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13
瞭解主要的 Kubernetes 概念
下圖顯示在 GKE 上執行的應用程式:
在將容器部署至 GKE 之前,建議您先瞭解一些重要的 Kubernetes 概念。本教學課程的結尾會提供連結,方便您進一步瞭解每個概念。
節點和叢集:在 GKE 中,節點是指 VM。在其他 Kubernetes 平台上,節點可以是實體或虛擬機器。叢集是一組可視為單一機器的節點,可用於部署容器化應用程式。
Pod:在 Kubernetes 中,容器會在 Pod 內執行。Pod 是 Kubernetes 中的原子單位。一個 Pod 可容納一或多個容器。您可以將
server
和loadgen
容器分別部署在各自的 Pod 中。若 Pod 執行多個容器 (例如應用程式伺服器和Proxy 伺服器),系統會將這些容器視為單一實體進行管理,這些容器也共用 Pod 的資源。部署作業:部署作業是代表一組相同 Pod 的 Kubernetes 物件。部署會在叢集的節點中分散執行多個 Pod 備用資源。Deployment 會自動取代失敗或無法回應的 Pod。
Kubernetes Service:在 GKE 中執行應用程式程式碼會變更
loadgen
和server
之間的網路連線。在 Cloud Shell VM 中執行服務時,您可以使用localhost:8080
位址將要求傳送至server
。部署至 GKE 後,Pod 會排程在可用的節點上執行。根據預設,您無法控制 Pod 執行的節點,因此Pod 沒有穩定的 IP 位址。如要為
server
取得 IP 位址,您必須在 Pod 上定義稱為 Kubernetes Service 的網路抽象概念。Kubernetes Service 會為一組 Pod 提供穩定的網路端點。服務有幾種類型。server
使用LoadBalancer
,可公開外部 IP 位址,讓您從叢集外部存取server
。Kubernetes 也有內建 DNS 系統,可將 DNS 名稱 (例如
helloserver.default.cluster.local
) 指派給 Service。這樣一來,叢集中的 Pod 就能透過穩定的位址存取叢集中的其他 Pod。您無法在叢集外使用這個 DNS 名稱,例如在 Cloud Shell 中。
Kubernetes 資訊清單
從原始碼執行應用程式時,您使用了命令式指令:python3 server.py
命令式指的是動詞驅動:「做這件事」。
相較之下,Kubernetes 則是採用宣告式模型運作。也就是說,您不必明確告知 Kubernetes 要執行哪些作業,只需提供所需狀態即可。舉例來說,Kubernetes 會視需要啟動及終止 Pod,讓實際系統狀態符合所需狀態。
您可以在一組資訊清單或 YAML 檔案中指定所需狀態。YAML 檔案包含一或多個 Kubernetes 物件的規格。
範例包含 server
和 loadgen
的 YAML 檔案。每個 YAML 檔案都會指定 Kubernetes 部署物件和服務的所需狀態。
伺服器
kind
表示物件類型。metadata.name
會指定部署作業的名稱。- 第一個
spec
欄位包含所需狀態的說明。 spec.replicas
會指定所需的 Pod 數量。spec.template
部分定義 Pod 範本。Pod 的規格包含image
欄位,這是從 Container Registry 提取的映像檔名稱。
服務的定義如下:
LoadBalancer
:用戶端將要求傳送至網路負載平衡器的 IP 位址,該 IP 位址穩定且可從叢集外部存取。targetPort
:請注意,Dockerfile
中的EXPOSE 8080
指令實際上並不會公開任何連接埠。您公開8080
通訊埠,即可存取叢集外的server
容器。在這種情況下,hellosvc.default.cluster.local:80
(簡稱:hellosvc
) 會對應至helloserver
Pod IP 的通訊埠8080
。port
:這是叢集中其他服務在傳送要求時使用的通訊埠號碼。
負載產生器
loadgen.yaml
中的 Deployment 物件與 server.yaml
類似。其中一個明顯的差異是,Deployment 物件包含名為 env
的部分。本節會定義 loadgen
所需的環境變數,這些變數是在您從來源執行應用程式時設定的。
由於 loadgen
不接受傳入要求,因此 type
欄位會設為 ClusterIP
。這類型會提供叢集中的服務可使用的穩定 IP 位址,但不會向外部用戶端公開 IP 位址。
將容器部署至 GKE
變更至範例
server
所在的目錄:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
在文字編輯器中開啟
server.yaml
。將
image
欄位中的名稱替換為 Docker 映像檔名稱。image: gcr.io/PROJECT_ID/asm-ready/helloserver:v0.0.1
請將
PROJECT_ID
替換為您的 Google Cloud 專案 ID。儲存並關閉
server.yaml
。將 YAML 檔案部署至 Kubernetes:
kubectl apply -f server.yaml
成功後,指令會傳回以下內容:
deployment.apps/helloserver created service/hellosvc created
切換至
loadgen
所在的目錄。cd ../loadgen
在文字編輯器中開啟
loadgen.yaml
。將
image
欄位中的名稱替換為 Docker 映像檔名稱。image: gcr.io/PROJECT_ID/asm-ready/loadgen:v0.0.1
請將
PROJECT_ID
替換為您的 Google Cloud 專案 ID。儲存並關閉
loadgen.yaml
,然後關閉文字編輯器。將 YAML 檔案部署至 Kubernetes:
kubectl apply -f loadgen.yaml
成功後,指令會傳回以下內容:
deployment.apps/loadgenerator created service/loadgensvc created
檢查 Pod 的狀態:
kubectl get pods
指令會傳回類似以下的狀態:
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
從
loadgen
Pod 取得應用程式記錄。將POD_ID
替換為上一個輸出的 ID。kubectl logs loadgenerator-POD_ID
取得
hellosvc
的外部 IP 位址:kubectl get service
該指令會輸出類似以下的結果:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s
傳送要求給
hellosvc
。將EXTERNAL_IP
替換為hellosvc
的外部 IP 位址。curl http://EXTERNAL_IP
準備好使用 Cloud Service Mesh
您現在已將應用程式部署至 GKE。loadgen
可以使用 Kubernetes DNS (hellosvc:80
) 將要求傳送至 server
,您也可以使用外部 IP 位址將要求傳送至 server
。雖然 Kubernetes 提供許多功能,但缺少某些服務資訊:
- 服務如何互動?服務之間的關係為何?服務之間的流量流向為何?您知道
loadgen
會將要求傳送至server
,但假設您不熟悉該應用程式。您無法透過查看 GKE 上執行中的 Pod 清單來回答這些問題。 - 指標:
server
回應傳入要求需要多長時間?server
的傳入要求數 (RPS) 為何?是否有任何錯誤回應? - 安全性資訊:
loadgen
與server
之間的流量是使用純HTTP
還是 mTLS?
Cloud Service Mesh 可以提供這些問題的解答。Cloud 服務網格是 開放原始碼 Istio 專案的 Google Cloud代管版本。Cloud Service Mesh 會在每個 Pod 中放置 Envoy 補充 Proxy。Envoy Proxy 會攔截應用程式容器的所有傳入和傳出流量。這表示 server
和 loadgen
各自取得 Envoy 邊車 Proxy,且從 loadgen
到 server
的所有流量都由 Envoy Proxy 調解。這些 Envoy Proxy 之間的連線會形成服務網格。這個服務中介架構可在 Kubernetes 上提供控制層。
由於 Envoy 代理程式會在自己的容器中執行,因此您可以在 GKE 叢集上安裝 Cloud Service Mesh,而無須大幅變更應用程式程式碼。不過,您可以透過幾種主要方式,準備要使用 Cloud Service Mesh 檢測的應用程式:
- 所有容器的服務:
server
和loadgen
部署作業都已連結 Kubernetes 服務。即使是不會接收任何內送要求的loadgen
,也都有服務。 - 服務中的通訊埠必須有名稱:雖然 GKE 允許您定義未命名的服務通訊埠,但 Cloud Service Mesh 要求您提供通訊埠名稱,且該名稱必須與通訊埠的通訊協定相符。在 YAML 檔案中,
server
的通訊埠名為http
,因為server
使用HTTP
通訊協定。如果service
使用gRPC
,您可以將通訊埠命名為grpc
。 - 部署作業已標示:這樣一來,您就能使用 Cloud Service Mesh 流量管理功能,例如在同一服務的不同版本之間分配流量。
安裝 Cloud Service Mesh
請參閱 Cloud Service Mesh 安裝指南,並按照操作說明在叢集上安裝 Cloud Service Mesh。
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。
如要清理,請刪除 GKE 叢集。刪除叢集會刪除組成容器叢集的所有資源,例如運算執行個體、磁碟和網路資源。
gcloud container clusters delete asm-ready
後續步驟
進一步瞭解本教學課程使用的技術:
進一步瞭解這些工具:
進一步瞭解 Kubernetes 概念: