使用 Cloud Service Mesh 在 GKE 私有叢集中執行分散式服務
本文件說明如何使用 Cloud Service Mesh,在多個 Google Kubernetes Engine (GKE) 叢集中執行分散式服務。 Google Cloud 本文件也說明如何使用多叢集 Ingress 和 Cloud Service Mesh 公開分散式服務。您可以使用這份文件設定非私人 GKE 叢集;這份文件會強調專為私人叢集設計的設定。
本文件適用於具備 Kubernetes 基本知識的平台管理員和服務操作人員。具備一些服務網格相關知識會很有幫助,但並非必要。Cloud Service Mesh 以開放原始碼 Istio 技術為基礎。如要進一步瞭解服務網格和 Istio,請參閱 istio.io。
分散式服務是一種 Kubernetes 服務,可充當單一邏輯服務。分散式服務比 Kubernetes 服務更具彈性,因為它們會在相同命名空間的多個 Kubernetes 叢集中執行。只要健康的叢集能夠處理所需負載,分散式服務就會持續運作,即使有一或多個 GKE 叢集停止運作也不例外。
只有在 Kubernetes 服務執行的叢集中,Kubernetes API 伺服器才會知道 Kubernetes 服務。如果 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.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
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 位址空間中)。也就是說,需要存取外部資源 (位於 VPC 網路之外) 的 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 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
授權網路包含 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 控制層和入口網關後,就能透過機群 API 啟用跨叢集服務探索功能。跨叢集服務探索功能可讓兩個叢集從遠端叢集中探索服務端點。分散式服務會在相同命名空間的多個叢集中執行。
如要讓 Cloud Service Mesh 控制層都能探索分散式服務的所有端點,Cloud Service Mesh 必須能存取執行分散式服務的所有叢集。這個範例使用兩個叢集,因此兩個叢集都必須能夠查詢遠端叢集的服務端點。透過車隊 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
命名空間。標籤可讓系統在標記命名空間中的每個 Pod 中,自動注入補充 Envoy Proxy。# 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
命名空間中建立閘道,並在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-config。這樣一來,您就能看到補充 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 位址,每個叢集各一個。
存取 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 > 服務網格 頁面。
您可以在「表格」檢視畫面或「拓樸圖」檢視畫面中查看服務。預設檢視畫面為表格檢視畫面,會以表格格式顯示所有執行中的分散式服務。如要變更檢視畫面,請按一下要顯示的檢視畫面。
在「Tables」檢視畫面中,按一下
frontend distributed service
。點選個別服務後,您會看到該服務的詳細檢視畫面,以及已連結的服務。在服務詳細資料檢視畫面中,您可以按一下「顯示時間軸」,建立 SLO 並查看服務的歷史時間軸。
如要查看黃金信號,請在側邊面板中按一下「指標」。
在「每秒要求次數」圖表中,按一下「依據細分」,然後選取「地區」。
結果會顯示兩個區域中兩個叢集每秒的請求數。分散式服務狀態良好,且兩個端點都會處理流量。
如要查看服務網格的拓撲圖,請在側邊面板中依序點選「Anthos 服務網格」和「拓撲圖檢視畫面」。
如要查看其他資料,請將滑鼠游標懸停在
frontend
服務上。這項資訊會顯示前端與其他服務之間的每秒要求次數等資訊。如要查看詳細資料,請按一下
frontend
服務上的「展開」。系統會顯示服務和工作負載。您可以進一步將工作負載擴展為兩個部署作業、將部署作業擴展為 ReplicaSet,並將 ReplicaSet 擴展為 Pod。展開所有元素後,您可以看到分散式frontend
服務,這項服務基本上就是一個服務和兩個 Pod。
設定多叢集 Ingress
在本節中,您將建立多叢集 Ingress,將流量傳送至在兩個叢集中執行的 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。