使用 Cloud Service Mesh 在 GKE 私有叢集上執行分散式服務
本文說明如何使用 Google Cloud Cloud Service Mesh,在多個 Google Kubernetes Engine (GKE) 叢集上執行分散式服務。本文也說明如何使用 Multi Cluster Ingress 和 Cloud Service Mesh 公開分散式服務。您可以使用這份文件設定非私人 GKE 叢集;這份文件會著重說明專為私人叢集設計的設定。
本文件適用於具備 Kubernetes 基礎知識的平台管理員和服務營運人員。瞭解服務網格會有幫助,但並非必要。Cloud Service Mesh 以開放原始碼 Istio 技術為基礎。如要進一步瞭解服務網格和 Istio,請參閱 istio.io。
分散式服務是 Kubernetes 服務,可做為單一邏輯服務。分散式服務比 Kubernetes 服務更具彈性,因為這類服務會在相同命名空間中的多個 Kubernetes 叢集上執行。即使一或多個 GKE 叢集停止運作,只要健康叢集能夠處理所需負載,分散式服務仍可正常運作。
Kubernetes 服務只會向執行所在叢集的 Kubernetes API 伺服器公開。如果 Kubernetes 叢機發生故障 (例如在排定的維護期間),該叢集上執行的所有 Kubernetes 服務也會發生故障。執行分散式服務可簡化叢集生命週期管理,因為您可以在其他叢集處理流量時,關閉叢集進行維護或升級。如要建立分散式服務,請使用 Cloud Service Mesh 提供的服務網格功能,將在多個叢集上執行的服務連結在一起,做為單一邏輯服務。
GKE 私人叢集可讓您將節點和 API 伺服器設定為私人資源,僅供虛擬私有雲 (VPC) 網路使用。在 GKE 私有叢集中執行分散式服務,可為企業提供安全可靠的服務。
架構
本教學課程使用下圖所示的架構:
在上圖中,架構包含下列叢集:
- 兩個叢集 (
gke-central-priv
和gke-west-priv
) 在兩個不同區域中,做為相同的 GKE 私人叢集。 - 另一個叢集 (
ingress-config
) 則做為控制層叢集,用於設定多叢集 Ingress。
在本教學課程中,您會在兩個 GKE 私人叢集 (gke-central-priv
和 gke-west-priv
) 上部署 Bank of Anthos 範例應用程式。Bank of Anthos 是範例微服務應用程式,由多個微服務和 SQL 資料庫組成,可模擬線上銀行應用程式。這個應用程式包含客戶可存取的網頁前端,以及多個後端服務,例如模擬銀行的餘額、帳本和帳戶服務。
這個應用程式包含兩個 PostgreSQL 資料庫,以 StatefulSet 形式安裝在 Kubernetes 中。一個資料庫用於交易,另一個則用於使用者帳戶。除了這兩個資料庫以外,所有服務都會以分散式服務的形式執行。也就是說,所有服務的 Pod 都會在兩個應用程式叢集 (位於相同命名空間) 中執行,且 Cloud Service Mesh 的設定會讓每個服務顯示為單一邏輯服務。
目標
- 建立三個 GKE 叢集。
- 將兩個 GKE 叢集設定為私人叢集 (
gke-central-priv
和gke-west-priv
)。 - 將一個 GKE 叢集 (
ingress-config
) 設定為中央設定叢集。這個叢集會做為多叢集 Ingress 的設定叢集。 - 設定網路 (NAT 閘道、Cloud Router 和防火牆規則),允許兩個私人 GKE 叢集之間的流量和輸出流量。
- 設定授權網路,允許從 Cloud Shell 存取這兩個私人 GKE 叢集的 API 服務。
- 以多主控台模式,將多叢集 Cloud Service Mesh 部署及設定至兩個私有叢集。多主要模式會在兩個叢集中部署 Cloud Service Mesh 控制層。
- 在兩個私人叢集上部署 Bank of Anthos 應用程式。除了資料庫以外,所有服務都會部署為分散式服務 (在私人叢集上執行的 Pod)。
- 使用 Cloud Service Mesh 監控服務。
- 在 Bank of Anthos
frontend
服務上設定多叢集 Ingress。外部用戶端 (例如網頁瀏覽器) 即可存取在私人 GKE 叢集機群上執行的分散式服務。
費用
在本文件中,您會使用 Google Cloud的下列計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
事前準備
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
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.
您將使用 Cloud Shell 執行本教學課程中的所有指令。
定義本教學課程中會用到的環境變數。這些變數定義本教學課程中使用的叢集名稱、地區、區域、IP 位址和 Cloud Service Mesh 版本。
將
YOUR_PROJECT_ID
替換為您的專案 ID:export PROJECT_ID=YOUR_PROJECT_ID gcloud config set project ${PROJECT_ID}
設定其餘環境變數:
export CLUSTER_1=gke-west-priv export CLUSTER_2=gke-central-priv export CLUSTER_1_ZONE=us-west2-a export CLUSTER_1_REGION=us-west2 export CLUSTER_1_MASTER_IPV4_CIDR=172.16.0.0/28 export CLUSTER_2_ZONE=us-central1-a export CLUSTER_2_REGION=us-central1 export CLUSTER_2_MASTER_IPV4_CIDR=172.16.1.0/28 export CLUSTER_INGRESS=gke-ingress export CLUSTER_INGRESS_ZONE=us-west1-a export CLUSTER_INGRESS_REGION=us-west1 export CLUSTER_INGRESS_MASTER_IPV4_CIDR=172.16.2.0/28 export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog export ASM_VERSION=1.10 export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
準備環境
在 Cloud Shell 中啟用 API:
gcloud services enable \ --project=${PROJECT_ID} \ container.googleapis.com \ mesh.googleapis.com \ gkehub.googleapis.com
為專案啟用 Cloud Service Mesh Fleet:
gcloud container fleet mesh enable --project=${PROJECT_ID}
準備 GKE 私人叢集的網路
在本節中,您將準備私人 GKE 叢集的網路,以便執行分散式服務。
系統不會為私人 GKE 叢集節點指派公開 IP 位址。系統會為私人 GKE 叢集中的所有節點指派私人 VPC IP 位址 (位於 RFC 1918 位址空間)。也就是說,如要存取外部資源 (虛擬私有雲網路以外),Pod 需要 Cloud NAT 閘道。Cloud NAT 閘道是區域 NAT 閘道,可讓具有內部 IP 位址的 Pod 與網際網路通訊。在本教學課程中,您要在兩個區域中各設定一個 Cloud NAT 閘道。同一區域內的多個叢集可以共用同一個 NAT 閘道。
在 Cloud Shell 中,為兩個 NAT 閘道建立並保留兩個外部 IP 位址:
gcloud compute addresses create ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} gcloud compute addresses create ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION}
將 IP 位址和 IP 位址名稱儲存在變數中:
export NAT_REGION_1_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} \ --format='value(address)') export NAT_REGION_1_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} \ --format='value(name)') export NAT_REGION_2_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION} \ --format='value(address)') export NAT_REGION_2_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION} \ --format='value(name)')
在私有 GKE 叢集的兩個區域中建立 Cloud NAT 閘道:
gcloud compute routers create rtr-${CLUSTER_1_REGION} \ --network=default \ --region ${CLUSTER_1_REGION} gcloud compute routers nats create nat-gw-${CLUSTER_1_REGION} \ --router=rtr-${CLUSTER_1_REGION} \ --region ${CLUSTER_1_REGION} \ --nat-external-ip-pool=${NAT_REGION_1_IP_NAME} \ --nat-all-subnet-ip-ranges \ --enable-logging gcloud compute routers create rtr-${CLUSTER_2_REGION} \ --network=default \ --region ${CLUSTER_2_REGION} gcloud compute routers nats create nat-gw-${CLUSTER_2_REGION} \ --router=rtr-${CLUSTER_2_REGION} \ --region ${CLUSTER_2_REGION} \ --nat-external-ip-pool=${NAT_REGION_2_IP_NAME} \ --nat-all-subnet-ip-ranges \ --enable-logging
建立防火牆規則,允許 Pod 對 Pod 通訊和 Pod 對 API 伺服器通訊。Pod 對 Pod 通訊可讓分散式服務在 GKE 叢集之間相互通訊。透過 Pod 對 API 伺服器通訊,Cloud Service Mesh 控制層可查詢 GKE 叢集,進行服務探索。
gcloud compute firewall-rules create all-pods-and-master-ipv4-cidrs \ --project ${PROJECT_ID} \ --network default \ --allow all \ --direction INGRESS \ --source-ranges 10.0.0.0/8,${CLUSTER_1_MASTER_IPV4_CIDR},${CLUSTER_2_MASTER_IPV4_CIDR},${CLUSTER_INGRESS_MASTER_IPV4_CIDR}
網路現已準備就緒。在本教學課程中,您將使用整個 10.0.0.0/8
IP 位址範圍,包括所有 Pod 範圍。建議您根據條件和需求,在實際工作環境中建立更嚴格的防火牆規則。
建立私人 GKE 叢集
在本節中,您將建立兩個私人 GKE 叢集,並在當中部署範例應用程式。在本教學課程中,私人 GKE 叢集節點具有私人 IP 位址,而 API 伺服器則有公開端點。不過,API 伺服器的存取權會受到授權網路限制。
在 Cloud Shell 中,建立兩個具有授權網路的私人叢集。設定叢集,允許從 Pod IP CIDR 範圍 (適用於 Cloud Service Mesh 控制層) 和 Cloud Shell 存取,以便從終端機存取叢集。
gcloud container clusters create ${CLUSTER_1} \ --project ${PROJECT_ID} \ --zone=${CLUSTER_1_ZONE} \ --machine-type "e2-standard-4" \ --num-nodes "3" --min-nodes "3" --max-nodes "5" \ --enable-ip-alias --enable-autoscaling \ --workload-pool=${WORKLOAD_POOL} \ --enable-private-nodes \ --master-ipv4-cidr=${CLUSTER_1_MASTER_IPV4_CIDR} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 \ --labels=mesh_id=${MESH_ID} --async gcloud container clusters create ${CLUSTER_2} \ --project ${PROJECT_ID} \ --zone=${CLUSTER_2_ZONE} \ --machine-type "e2-standard-4" \ --num-nodes "3" --min-nodes "3" --max-nodes "5" \ --enable-ip-alias --enable-autoscaling \ --workload-pool=${WORKLOAD_POOL} \ --enable-private-nodes \ --master-ipv4-cidr=${CLUSTER_2_MASTER_IPV4_CIDR} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 \ --labels=mesh_id=${MESH_ID}
授權網路包含 Cloud NAT 閘道上的公開 IP 位址。由於私人叢集的 API 伺服器端點是公開端點,因此在私人叢集中執行的 Pod 必須使用 Cloud NAT 閘道,才能存取公開 API 伺服器端點。
Cloud Shell IP 位址也屬於授權網路,因此您可以透過 Cloud Shell 終端機存取及管理叢集。Cloud Shell 的公開 IP 位址是動態的,因此每次啟動 Cloud Shell 時,您可能會取得不同的公開 IP 位址。取得新 IP 位址後,您會失去叢集存取權,因為新 IP 位址不屬於這兩個叢集的授權網路。
如果無法存取叢集,請更新叢集的授權網路,加入新的 Cloud Shell IP 位址:
取得更新後的 Cloud Shell 公開 IP 位址:
export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
更新兩個叢集的授權網路:
gcloud container clusters update ${CLUSTER_1} \ --zone=${CLUSTER_1_ZONE} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 gcloud container clusters update ${CLUSTER_2} \ --zone=${CLUSTER_2_ZONE} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
確認所有叢集正在執行:
gcloud container clusters list
輸出內容如下:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS gke-central-priv us-central1-a 1.16.15-gke.6000 35.238.99.104 e2-standard-4 1.16.15-gke.6000 3 RUNNING gke-west-priv us-west2-a 1.16.15-gke.6000 34.94.188.180 e2-standard-4 1.16.15-gke.6000 3 RUNNING
連線至這兩個叢集,以在 kubeconfig 檔案中產生相關項目:
touch ~/asm-kubeconfig && export KUBECONFIG=~/asm-kubeconfig gcloud container clusters get-credentials ${CLUSTER_1} --zone ${CLUSTER_1_ZONE} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${CLUSTER_2_ZONE}
您可以使用 kubeconfig 檔案,為每個叢集建立使用者和背景資訊,藉此驗證叢集。在 kubeconfig 檔案中產生項目後,您就可以快速切換叢集之間的背景資訊。
為了方便起見,請重新命名叢集環境:
kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_1_ZONE}_${CLUSTER_1} ${CLUSTER_1} kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_2_ZONE}_${CLUSTER_2} ${CLUSTER_2}
確認兩個叢集環境都已正確重新命名及設定:
kubectl config get-contexts --output="name"
輸出內容如下:
gke-central-priv gke-west-priv
將叢集註冊至機群:
gcloud container fleet memberships register ${CLUSTER_1} --gke-cluster=${CLUSTER_1_ZONE}/${CLUSTER_1} --enable-workload-identity gcloud container fleet memberships register ${CLUSTER_2} --gke-cluster=${CLUSTER_2_ZONE}/${CLUSTER_2} --enable-workload-identity
您已建立私人 GKE 叢集並重新命名。
安裝 Cloud Service Mesh
在本節中,您將在兩個 GKE 叢集上安裝 Cloud Service Mesh,並設定叢集以進行跨叢集服務探索。
在 Cloud Shell 中,使用
fleet API
在兩個叢集上安裝 Cloud Service Mesh:gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
在叢集上啟用代管 Cloud Service Mesh 後,請設定監控項,以便安裝網格:
watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
為兩個叢集安裝 Cloud Service Mesh 入口閘道:
kubectl --context=${CLUSTER_1} create namespace asm-ingress kubectl --context=${CLUSTER_1} label namespace asm-ingress istio-injection=enabled --overwrite kubectl --context=${CLUSTER_2} create namespace asm-ingress kubectl --context=${CLUSTER_2} label namespace asm-ingress istio-injection=enabled --overwrite cat <<'EOF' > asm-ingress.yaml apiVersion: v1 kind: Service metadata: name: asm-ingressgateway namespace: asm-ingress spec: type: LoadBalancer selector: asm: ingressgateway ports: - port: 80 name: http - port: 443 name: https --- apiVersion: apps/v1 kind: Deployment metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: matchLabels: asm: ingressgateway template: metadata: annotations: # This is required to tell Anthos Service Mesh to inject the gateway with the # required configuration. inject.istio.io/templates: gateway labels: asm: ingressgateway spec: containers: - name: istio-proxy image: auto # The image will automatically update each time the pod starts. --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: asm-ingressgateway-sds namespace: asm-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: asm-ingressgateway-sds namespace: asm-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: asm-ingressgateway-sds subjects: - kind: ServiceAccount name: default EOF kubectl --context=${CLUSTER_1} apply -f asm-ingress.yaml kubectl --context=${CLUSTER_2} apply -f asm-ingress.yaml
確認已部署 Cloud Service Mesh 入口閘道:
kubectl --context=${CLUSTER_1} get pod,service -n asm-ingress kubectl --context=${CLUSTER_2} get pod,service -n asm-ingress
兩個叢集的輸出內容如下:
NAME READY STATUS RESTARTS AGE pod/asm-ingressgateway-5894744dbd-zxlgc 1/1 Running 0 84s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/asm-ingressgateway LoadBalancer 10.16.2.131 34.102.100.138 80:30432/TCP,443:30537/TCP 92s
為兩個叢集安裝 Cloud Service Mesh 控制層和 Ingress 閘道後,即可透過 Fleet API 啟用跨叢集服務探索功能。透過跨叢集服務探索功能,兩個叢集可以探索遠端叢集的服務端點。分散式服務會在相同命名空間的多個叢集上執行。
如要讓兩個 Cloud Service Mesh 控制平面探索分散式服務的所有端點,Cloud Service Mesh 必須有權存取執行分散式服務的所有叢集。這個範例使用兩個叢集,因此兩個叢集都必須能夠查詢遠端叢集的服務端點。透過 Fleet API 啟用代管 Cloud Service Mesh 後,系統會自動設定端點探索功能。
叢集和 Cloud Service Mesh 現已設定完成。
部署 Bank of Anthos 應用程式
在 Cloud Shell 中,複製 Bank of Anthos GitHub 存放區:
git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
在兩個叢集中建立並標記
bank-of-anthos
命名空間。標籤可讓您在標示的命名空間中,自動將補充 Envoy Proxy 植入每個 Pod。# cluster_1 kubectl create --context=${CLUSTER_1} namespace bank-of-anthos kubectl label --context=${CLUSTER_1} namespace bank-of-anthos istio-injection=enabled # cluster_2 kubectl create --context=${CLUSTER_2} namespace bank-of-anthos kubectl label --context=${CLUSTER_2} namespace bank-of-anthos istio-injection=enabled
將 Bank of Anthos 應用程式部署至
bank-of-anthos
命名空間中的兩個叢集。# The following secret is used for user account creation and authentication kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml # Deploy all manifests to both clusters kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
兩個叢集都必須有 Kubernetes 服務,才能進行服務探索。當其中一個叢集中的服務嘗試提出要求時,會先對主機名稱執行 DNS 查詢,以取得 IP 位址。在 GKE 中,叢集內執行的
kube-dns
伺服器會處理這項查詢,因此需要設定服務定義。從其中一個叢集刪除
StatefulSets
,讓兩個 PostgreSQL 資料庫只存在於其中一個叢集:# Delete the two DB statefulSets from Cluster2 kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset accounts-db kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset ledger-db
確認兩個叢集中的所有 Pod 都在執行中:
從
cluster_1
取得 Pod:kubectl --context=${CLUSTER_1} -n bank-of-anthos get pod
輸出內容如下:
NAME READY STATUS RESTARTS AGE accounts-db-0 2/2 Running 0 9m54s balancereader-c5d664b4c-xmkrr 2/2 Running 0 9m54s contacts-7fd8c5fb6-wg9xn 2/2 Running 1 9m53s frontend-7b7fb9b665-m7cw7 2/2 Running 1 9m53s ledger-db-0 2/2 Running 0 9m53s ledgerwriter-7b5b6db66f-xhbp4 2/2 Running 0 9m53s loadgenerator-7fb54d57f8-g5lz5 2/2 Running 0 9m52s transactionhistory-7fdb998c5f-vqh5w 2/2 Running 1 9m52s userservice-76996974f5-4wlpf 2/2 Running 1 9m52s
從
cluster_2
取得 Pod:kubectl --context=${CLUSTER_2} -n bank-of-anthos get pod
輸出內容如下:
NAME READY STATUS RESTARTS AGE balancereader-c5d664b4c-bn2pl 2/2 Running 0 9m54s contacts-7fd8c5fb6-kv8cp 2/2 Running 0 9m53s frontend-7b7fb9b665-bdpp4 2/2 Running 0 9m53s ledgerwriter-7b5b6db66f-297c2 2/2 Running 0 9m52s loadgenerator-7fb54d57f8-tj44v 2/2 Running 0 9m52s transactionhistory-7fdb998c5f-xvmtn 2/2 Running 0 9m52s userservice-76996974f5-mg7t6 2/2 Running 0 9m51s
將 Cloud Service Mesh 設定檔部署至兩個叢集。這會在
asm-ingress
命名空間中建立 Gateway,並在bank-of-anthos
命名空間中為frontend
服務建立 VirtualService,讓您將流量輸入frontend
服務。Gateways
通常由平台管理員或網路管理員團隊擁有。因此,Gateway
資源會在平台管理員擁有的 Ingress Gateway 命名空間中建立,並可透過各自的VirtualService
項目用於其他命名空間。這是「共用閘道」模型。cat <<'EOF' > asm-vs-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: asm: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: frontend namespace: bank-of-anthos spec: hosts: - "*" gateways: - asm-ingress/asm-ingressgateway http: - route: - destination: host: frontend port: number: 80 EOF kubectl --context=$CLUSTER_1 apply -f asm-vs-gateway.yaml kubectl --context=$CLUSTER_2 apply -f asm-vs-gateway.yaml
您現在已在兩個私人 GKE 叢集上部署 Bank of Anthos 應用程式。除了資料庫以外,所有服務都會以分散式服務的形式執行。
檢查分散式服務
在本節中,您將使用 istioctl
工具檢查任何 Proxy 的 Proxy 設定。這麼做可讓您查看每個服務的兩個 Pod,每個叢集各有一個 Pod 正在執行。
在 Cloud Shell 中,檢查
cluster_1
中frontend
Pod 的 proxy-config Endpoints 清單:export FRONTEND1=$(kubectl get pod -n bank-of-anthos -l app=frontend \ --context=${CLUSTER_1} -o jsonpath='{.items[0].metadata.name}') istioctl proxy-config endpoints \ --context $CLUSTER_1 -n bank-of-anthos $FRONTEND1 | grep bank-of-anthos
輸出內容如下:
10.12.0.6:5432 HEALTHY OK outbound|5432||accounts-db.bank-of-anthos.svc.cluster.local 10.12.0.7:8080 HEALTHY OK outbound|8080||balancereader.bank-of-anthos.svc.cluster.local 10.12.0.8:8080 HEALTHY OK outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local 10.12.0.9:8080 HEALTHY OK outbound|8080||userservice.bank-of-anthos.svc.cluster.local 10.12.1.10:8080 HEALTHY OK outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local 10.12.1.9:8080 HEALTHY OK outbound|8080||contacts.bank-of-anthos.svc.cluster.local 10.12.2.11:5432 HEALTHY OK outbound|5432||ledger-db.bank-of-anthos.svc.cluster.local 10.12.2.13:8080 HEALTHY OK outbound|80||frontend.bank-of-anthos.svc.cluster.local 10.76.1.10:8080 HEALTHY OK outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local 10.76.1.8:8080 HEALTHY OK outbound|8080||balancereader.bank-of-anthos.svc.cluster.local 10.76.1.9:8080 HEALTHY OK outbound|80||frontend.bank-of-anthos.svc.cluster.local 10.76.2.10:8080 HEALTHY OK outbound|8080||userservice.bank-of-anthos.svc.cluster.local 10.76.2.8:8080 HEALTHY OK outbound|8080||contacts.bank-of-anthos.svc.cluster.local 10.76.2.9:8080 HEALTHY OK outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
在上方的輸出內容中,每個分散式服務都有兩個端點 IP 位址。這些是 Pod IP 位址,每個叢集各有一個。
存取 Bank of Anthos
如要存取 Bank of Anthos 應用程式,可以使用任一叢集的asm-ingressgateway
服務公開 IP 位址。
從兩個叢集取得
asm-ingressgateway
IP 位址:kubectl --context ${CLUSTER_1} \ --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress" kubectl --context ${CLUSTER_2} \ --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
輸出內容如下所示。
{"ingress":[{"ip":"35.236.4.18"}]} {"ingress":[{"ip":"34.68.94.81"}]}
複製其中一個 IP 位址,以便在下一個步驟中使用。
在網路瀏覽器中開啟新分頁,然後前往先前輸出內容中的任一 IP 位址。系統應會顯示 Bank of Anthos 前端,您可以在這裡登入、將資金存入帳戶,以及將資金轉移至其他帳戶。應用程式應可正常運作。
以視覺化方式呈現分散式服務
您可以在 Cloud Service Mesh 中將分散式服務視覺化。
如要查看服務,請前往 Google Cloud 控制台的「Anthos」>「Service Mesh」頁面。
您可以透過「表格」或「拓撲」檢視畫面查看服務。預設檢視畫面為表格檢視,會以表格格式顯示所有分散式服務。如要變更檢視畫面,請按一下要顯示的檢視畫面。
在「表格」檢視畫面中,按一下
frontend distributed service
。 點選個別服務時,系統會顯示該服務的詳細檢視畫面,以及已連結的服務。在服務詳細資料檢視畫面中,您可以建立 SLO,並按一下「顯示時間軸」,查看服務的歷史時間軸。
如要查看黃金信號,請在側邊面板中點選「指標」。
在「每秒要求數」圖表中,按一下「依據細分」,然後選取「位置」。
結果會顯示兩個區域中兩個叢集的每秒要求數。分散式服務狀態良好,且兩個端點都在處理流量。
如要查看服務網格的拓撲,請在側邊面板中點選「Anthos Service Mesh」,然後點選「Topology View」(拓撲檢視)。
如要查看其他資料,請將滑鼠指標懸停在
frontend
服務上。這會顯示資訊,例如從前端到其他服務的每秒要求數。如要查看更多詳細資料,請按一下
frontend
服務的「展開」。系統會顯示服務和工作負載。您可以進一步將工作負載擴展為兩個 Deployment,將 Deployment 擴展為 ReplicaSet,並將 ReplicaSet 擴展為 Pod。展開所有元素後,您會看到分散式frontend
服務,這基本上是服務和兩個 Pod。
設定多叢集 Ingress
在本節中,您將建立多叢集 Ingress,將流量傳送至在兩個叢集中執行的 Bank of GKE Enterprise frontend
服務。您可以使用 Cloud Load Balancing 建立負載平衡器,並將兩個叢集中的 asm-ingressgateway
服務做為後端。ingress-config
叢集用於自動化調度管理多叢集 Ingress 設定。
如要建立負載平衡器,請使用 MultiClusterIngress
和一或多個 MultiClusterServices
。MultiClusterIngress
和 MultiClusterService
物件是現有 Kubernetes Ingress 和 Service 資源的多叢集類似項目,用於單一叢集環境。
啟用必要的 GKE Enterprise、GKE Fleet 和 Multi Cluster Ingress API:
gcloud services enable \ anthos.googleapis.com \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com
建立
ingress-config
叢集。您可以使用任何叢集,但建議您為此目的建立專屬叢集。gcloud container clusters create ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} \ --num-nodes=1 \ --enable-ip-alias \ --workload-pool=${WORKLOAD_POOL}
取得叢集憑證,並重新命名背景資訊,方便使用:
gcloud container clusters get-credentials ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} --project ${PROJECT_ID} kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_INGRESS_ZONE}_${CLUSTER_INGRESS} ${CLUSTER_INGRESS}
如要使用多叢集 Ingress,請將所有參與的叢集 (包括設定叢集) 註冊至 GKE Enterprise 機群:
註冊設定叢集:
gcloud container fleet memberships register ${CLUSTER_INGRESS} \ --project=${PROJECT_ID} \ --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \ --enable-workload-identity
確認所有叢集都已註冊至 GKE Enterprise 機群:
gcloud container fleet memberships list
輸出內容如下:
NAME EXTERNAL_ID gke-west 7fe5b7ce-50d0-4e64-a9af-55d37b3dd3fa gke-central 6f1f6bb2-a3f6-4e9c-be52-6907d9d258cd gke-ingress 3574ee0f-b7e6-11ea-9787-42010a8a019c
在
ingress-config
叢集上啟用多叢集 Ingress 功能。 這會在叢集上建立MulticlusterService
和MulticlusterIngress
CustomResourceDefinitions (CRD)。gcloud container fleet ingress enable \ --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
確認
ingress-config
叢集已啟用多叢集 Ingress:gcloud container fleet ingress describe
輸出內容如下:
membershipStates: projects/986443280307/locations/global/memberships/gke-central-priv: state: code: OK updateTime: '2022-09-29T13:57:02.972748202Z' projects/986443280307/locations/global/memberships/gke-ingress: state: code: OK updateTime: '2022-09-29T13:57:02.972744692Z' projects/986443280307/locations/global/memberships/gke-west-priv: state: code: OK updateTime: '2022-09-29T13:57:02.972746497Z'
確認這兩個 CRD 已部署至
ingress-config
叢集:kubectl --context=${CLUSTER_INGRESS} get crd | grep multicluster
輸出內容如下所示。
multiclusteringresses.networking.gke.io 2020-10-29T17:32:50Z multiclusterservices.networking.gke.io 2020-10-29T17:32:50Z
在
ingress-config
叢集中建立asm-ingress
命名空間:kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
建立
MultiClusterIngress
資源:cat <<EOF > ${HOME}/mci.yaml apiVersion: networking.gke.io/v1beta1 kind: MultiClusterIngress metadata: name: asm-ingressgateway-multicluster-ingress spec: template: spec: backend: serviceName: asm-ingressgateway-multicluster-svc servicePort: 80 EOF
建立
MultiClusterService
資源:cat <<'EOF' > $HOME/mcs.yaml apiVersion: networking.gke.io/v1beta1 kind: MultiClusterService metadata: name: asm-ingressgateway-multicluster-svc annotations: beta.cloud.google.com/backend-config: '{"ports": {"80":"gke-ingress-config"}}' spec: template: spec: selector: asm: ingressgateway ports: - name: frontend protocol: TCP port: 80 # servicePort defined in Multi Cluster Ingress clusters: - link: "us-west2-a/gke-west-priv" - link: "us-central1-a/gke-central-priv" EOF
建立健康狀態檢查的
BackendConfig
資源:cat <<EOF > $HOME/backendconfig.yaml apiVersion: cloud.google.com/v1beta1 kind: BackendConfig metadata: name: gke-ingress-config spec: healthCheck: type: HTTP port: 15021 requestPath: /healthz/ready EOF
套用
BackendConfig
、MultiClusterService
和MultiClusterIngress
資訊清單:kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/backendconfig.yaml kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mci.yaml kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mcs.yaml
您在 Ingress 叢集中部署的
MultiClusterService
會在叢集 1 和叢集 2 中建立「無標頭」Service
。確認是否已建立「無標題」Services
:kubectl --context=${CLUSTER_1} -n asm-ingress \ get services | grep multicluster-svc kubectl --context=${CLUSTER_2} -n asm-ingress \ get services | grep multicluster-svc
輸出內容類似如下:
mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw ClusterIP None <none> 80/TCP 77s mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw ClusterIP None <none> 80/TCP 78s
執行下列指令,並等待系統傳回 Cloud Load Balancing IP 位址:
watch kubectl --context ${CLUSTER_INGRESS} -n asm-ingress get multiclusteringress \ -o jsonpath="{.items[].status.VIP}"
輸出內容如下:
35.35.23.11
如要結束 watch 指令,請按 Ctrl+C。
在網路瀏覽器中前往 Cloud Load Balancing IP 位址,即可存取 Bank of Anthos 前端:
kubectl --context ${CLUSTER_INGRESS} \ -n asm-ingress get multiclusteringress \ -o jsonpath="{.items[].status.VIP}"
如果收到 404 錯誤 (或 502 錯誤),請稍候幾分鐘,然後重新整理網頁瀏覽器中的頁面。
清除所用資源
如要避免系統向您的帳戶收取費用,請刪除專案或叢集。
刪除專案
如要避免系統向您收費,最簡單的方法就是刪除您在教學課程中建立的專案。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
刪除叢集
在 Cloud Shell 中,取消註冊並刪除
blue
和green
叢集:gcloud container fleet memberships unregister ${CLUSTER_1} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_1_URI} gcloud container clusters delete ${CLUSTER_1} \ --zone ${CLUSTER_1_ZONE} \ --quiet gcloud container fleet memberships unregister ${CLUSTER_2} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_2_URI} gcloud container clusters delete ${CLUSTER_2} \ --zone ${CLUSTER_2_ZONE} \ --quiet
從 ingress-config 叢集刪除
MuticlusterIngress
資源:kubectl --context ${CLUSTER_INGRESS} -n istio-system delete -f $HOME/mci.yaml
這會從專案中刪除 Cloud Load Balancing 資源。
取消註冊並刪除
ingress-config
叢集:gcloud container fleet memberships unregister ${CLUSTER_INGRESS} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_INGRESS_URI} gcloud container clusters delete ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} \ --quiet
確認所有叢集都已刪除:
gcloud container clusters list
輸出內容如下:
<null>
重設
kubeconfig
檔案:unset KUBECONFIG
後續步驟
- 進一步瞭解多叢集 Ingress。
- 瞭解如何在叢集之間部署多叢集 Ingress。