本教學課程說明如何在私人 Google Kubernetes Engine (GKE) 叢集中建立私人 HTTP 端點,使用 Eventarc 接收 Pub/Sub 訊息事件。如要進一步瞭解這個事件目的地,請參閱「將事件轉送至虛擬私有雲網路中的內部 HTTP 端點」。
私人 GKE 叢集是虛擬私有雲 (VPC) 原生叢集的一種,節點只會使用內部 IP 位址,因此節點和 Pod 預設會與網際網路隔離。您可以選擇不開放用戶端存取控制層、限制存取權,或開放無限制存取權。您無法將現有的非私人叢集轉換為私人叢集。詳情請參閱「關於私人叢集」。
您可以在終端機或 Cloud Shell 中,使用 Google Cloud CLI 執行下列指令。
目標
在這個教學課程中,您將執行下列操作:
- 在預設虛擬私有雲網路中建立僅限 Proxy 的子網路,並建立虛擬私有雲防火牆規則。
- 建立無法透過用戶端存取公開端點的私人 GKE Autopilot 叢集。
- 在 VPC 網路的指定子網路中,建立 Compute Engine 虛擬機器 (VM) 執行個體。
- 建立與 VM 執行個體的 SSH 連線,並在 VM 執行個體上部署事件接收器服務。
- 在叢集中部署 Gateway 和
HTTPRoute
資訊清單,以便在 Kubernetes 中設定流量的轉送路徑,將流量轉送至應用程式後端。 - 建立網路連結,讓供應商虛擬私有雲網路啟動與用戶虛擬私有雲網路的連線。
- 建立 Eventarc 觸發條件,將 Pub/Sub 事件轉送至 VM 執行個體上的事件接收器。
- 將訊息發布至 Pub/Sub 主題以產生事件,並在應用程式 Pod 記錄檔中查看事件主體。
費用
在本文件中,您會使用 Google Cloud的下列計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
完成本文所述工作後,您可以刪除已建立的資源,避免繼續計費。詳情請參閱清除所用資源一節。
事前準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:
gcloud services enable compute.googleapis.com
container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com -
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:
gcloud services enable compute.googleapis.com
container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com - 更新 Google Cloud CLI 元件:
gcloud components update
- 登入帳戶:
gcloud auth login
-
如果您是專案建立者,系統會授予基本「擁有者」角色 (
roles/owner
)。根據預設,這個身分與存取權管理 (IAM) 角色包含完全存取大多數 Google Cloud資源所需的權限,因此您可以略過這個步驟。如果您不是專案建立者,必須在專案中將必要權限授予適當的主體。舉例來說,主體可以是 Google 帳戶 (適用於使用者) 或服務帳戶 (適用於應用程式和運算工作負載)。詳情請參閱活動目的地的「角色和權限」頁面。
所需權限
如要取得完成本快速入門所需的權限,請要求管理員為您授予專案的下列 IAM 角色:
-
Compute 網路管理員 (
roles/compute.networkAdmin
) -
Compute 安全性管理員 (
roles/compute.securityAdmin
) -
Eventarc 管理員 (
roles/eventarc.admin
) -
Kubernetes Engine 管理員 (
roles/container.admin
) -
記錄檔檢視存取者 (
roles/logging.viewAccessor
) -
專案 IAM 管理員 (
roles/resourcemanager.projectIamAdmin
) -
Pub/Sub Publisher (
roles/pubsub.publisher
) -
服務帳戶管理員 (
roles/iam.serviceAccountAdmin
) -
服務帳戶使用者 (
roles/iam.serviceAccountUser
) -
服務使用情形管理員 (
roles/serviceusage.serviceUsageAdmin
)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
-
Compute 網路管理員 (
記下 Compute Engine 預設服務帳戶,因為您會將其附加至 Eventarc 觸發程序,代表觸發程序的身分,以利進行測試。啟用或使用採用 Compute Engine 的服務後,系統會自動建立這個服務帳戶,電子郵件地址格式如下: Google Cloud
PROJECT_NUMBER-compute@developer.gserviceaccount.com
將
PROJECT_NUMBER
替換為專案編號。 Google Cloud您可以在 Google Cloud 控制台的「歡迎」頁面找到專案編號,也可以執行下列指令:gcloud projects describe PROJECT_ID --format='value(projectNumber)'
- 如果您是在 2021 年 4 月 8 日當天或之前啟用 Cloud Pub/Sub 服務代理,請將服務帳戶權杖建立者角色 (
roles/iam.serviceAccountTokenCreator
) 授予服務代理,以支援已驗證的 Pub/Sub 推送要求。否則,系統會預設授予這個角色:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountTokenCreator
建立僅限 Proxy 的子網路
除非您建立禁止此行為的機構政策,否則新專案一開始都會具備預設網路 (自動模式 VPC 網路),其中在每個地區都有一個子網路。每個虛擬私有雲網路都含有一或多個稱為「子網路」的 IP 位址範圍。子網路屬於區域性資源,具有相關聯的 IP 位址範圍。
使用
gcloud compute networks subnets create
指令,在預設網路中建立僅限 Proxy 的子網路。gcloud compute networks subnets create proxy-only-subnet \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-central1 \ --network=default \ --range=10.10.10.0/24
請注意,具有
purpose=REGIONAL_MANAGED_PROXY
的子網路會保留給以 Envoy 為基礎的負載平衡器,且range
必須提供 64 個以上的 IP 位址。建立防火牆規則,比對僅限 Proxy 的子網路範圍,並允許 TCP 通訊埠 8080 上的流量。
gcloud compute firewall-rules create allow-proxy-connection \ --allow tcp:8080 \ --source-ranges 10.10.10.0/24 \ --network=default
建立私人 GKE 叢集
使用 gcloud container clusters create-auto
指令,在Autopilot 模式中建立具備私人節點的私人 GKE 叢集,且用戶端無法存取公開端點。
下列範例會建立名為 private-cluster
的私人 GKE 叢集,並建立名為 my-subnet
的子網路:
gcloud container clusters create-auto private-cluster \
--create-subnetwork name=my-subnet \
--enable-master-authorized-networks \
--enable-private-nodes \
--enable-private-endpoint \
--region=us-central1
注意事項:
--enable-master-authorized-networks
表示僅有您授權的 IP 位址範圍可以存取公開端點。--enable-private-nodes
代表叢集節點沒有外部 IP 位址。--enable-private-endpoint
表示叢集是使用控制層 API 端點的內部 IP 位址進行管理。
建立叢集可能需要幾分鐘的時間。叢集建立完成後,輸出內容應會顯示叢集狀態為 RUNNING
。
在指定子網路中建立 VM 執行個體
Compute Engine VM 執行個體是指託管在 Google 基礎架構上的虛擬機器。「Compute Engine 執行個體」、「VM 執行個體」和「VM」這幾個詞是同義詞,可以互換使用。VM 執行個體包括 GKE 叢集、App Engine 彈性環境執行個體,以及其他 Google Cloud 以 Compute Engine VM 為基礎建構的產品。
使用 gcloud compute instances create
指令,在先前建立的子網路中建立 Compute Engine VM 執行個體。附加服務帳戶,並將 VM 的存取範圍設為 cloud-platform
。
gcloud compute instances create my-vm \
--service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--zone=us-central1-a \
--subnet=my-subnet
詳情請參閱「建立及啟動 VM 執行個體」。
在 VM 上部署事件接收器
使用預先建構的映像檔 us-docker.pkg.dev/cloudrun/container/hello
,在 VM 上部署服務,監聽通訊埠 80,並接收及記錄事件。
執行下列指令,與 VM 執行個體建立 SSH 連線:
gcloud compute ssh my-vm --project=PROJECT_ID --zone=us-central1-a
建立與 SSH 伺服器的連線後,請在 VM 執行個體上執行其餘指令。
如有必要,請安裝
kubectl
和任何必要的外掛程式。在 VM 執行個體中,使用
get-credentials
指令啟用kubectl
,以便與您建立的叢集搭配使用。gcloud container clusters get-credentials private-cluster \ --region=us-central1 \ --internal-ip
使用 Kubernetes 指令
kubectl create deployment
,將應用程式部署至叢集。kubectl create deployment hello-app \ --image=us-docker.pkg.dev/cloudrun/container/hello
這會建立名為「
hello-app
」的部署。Deployment 的 Pod 會執行hello
容器映像檔。部署應用程式後,您可以建立 Kubernetes Service,對流量公開應用程式。執行下列
kubectl expose
指令:kubectl expose deployment hello-app \ --type ClusterIP \ --port 80 \ --target-port 8080
輸出內容應會顯示
service/hello-app exposed
。您可以忽略類似下列的訊息:
E0418 14:15:33.970933 1129 memcache.go:287] couldn't get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
設定 Kubernetes 流量轉送
Gateway 資源代表 Kubernetes 中轉送流量的資料層。視衍生自的 GatewayClass 而定,Gateway 可以代表多種不同的負載平衡和路由。詳情請參閱部署閘道。系統會部署 HTTPRoute
資訊清單來建立路徑,並將流量傳送至應用程式後端。
在叢集中部署 Gateway。
kubectl apply -f - <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 EOF
注意事項:
gatewayClassName: gke-l7-rilb
會指定這個 Gateway 衍生自的 GatewayClass。gke-l7-rilb
對應於內部應用程式負載平衡器。port: 80
指定閘道只公開通訊埠 80,以監聽 HTTP 流量。
確認閘道已正確部署。部署所有資源可能需要幾分鐘的時間。
kubectl describe gateways.gateway.networking.k8s.io internal-http
輸出結果會與下列內容相似:
Name: internal-http Namespace: default ... API Version: gateway.networking.k8s.io/v1beta1 Kind: Gateway ... Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.36.172.5 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 80s sc-gateway-controller default/internal-http Normal UPDATE 20s (x3 over 80s) sc-gateway-controller default/internal-http Normal SYNC 20s sc-gateway-controller SYNC on default/internal-http was a success
部署
HTTPRoute
資訊清單,將 HTTP 流量轉送至通訊埠 80 的hello-app
服務。kubectl apply -f - <<EOF kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: hello-app-route spec: parentRefs: - kind: Gateway name: internal-http rules: - backendRefs: - name: hello-app port: 80 EOF
建立網路連結
網路連結是一種資源,可讓供應商虛擬私有雲網路透過 Private Service Connect 介面,啟動與用戶端虛擬私有雲網路的連線。
發布事件時,Eventarc 會使用網路連結,與虛擬私有雲網路中託管的內部 HTTP 端點建立連線。
您可以建立網路連結,自動接受參照該網路連結的任何 Private Service Connect 介面連線。在包含 HTTP 目的地服務的相同網路和區域中,建立網路連結。
gcloud compute network-attachments create my-network-attachment \ --region=us-central1 \ --subnets=my-subnet\ --connection-preference=ACCEPT_AUTOMATIC
詳情請參閱「關於網路連結」。
建立 Eventarc 觸發條件
建立 Eventarc 觸發程序,在訊息發布至 Pub/Sub 主題時,建立新的 Pub/Sub 主題,並將事件傳送至部署在 VM 上的事件接收器。
擷取閘道位址。
GATEWAY_ADDRESS=$(kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}")
建立觸發條件。
gcloud eventarc triggers create my-trigger \ --location=us-central1 \ --destination-http-endpoint-uri="http://$GATEWAY_ADDRESS:80/" \ --network-attachment="projects/PROJECT_ID/regions/us-central1/networkAttachments/my-network-attachment" \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
將
PROJECT_NUMBER
替換為專案編號。 Google Cloud您可以在 Google Cloud 控制台的「歡迎」頁面找到專案編號,也可以執行下列指令:gcloud projects describe PROJECT_ID --format='value(projectNumber)'
如要進一步瞭解如何設定觸發條件,請參閱將事件路由至虛擬私有雲網路中的內部 HTTP 端點。
產生及查看 Pub/Sub 主題事件
您可以將訊息發布至 Pub/Sub 主題,藉此產生事件。
找出 Pub/Sub 主題並設為環境變數。
export MY_TOPIC=$(gcloud eventarc triggers describe my-trigger \ --location=us-central1 \ --format='value(transport.pubsub.topic)')
將訊息發布至 Pub/Sub 主題,產生事件。
gcloud pubsub topics publish $MY_TOPIC --message "Hello World"
Eventarc 觸發條件會將事件轉送至私有 GKE 叢集中的內部 HTTP 端點。
檢查應用程式 Pod 記錄,並確認事件傳送情形。
POD_NAME=$(kubectl get pod --selector app=hello-app --output=name) kubectl logs $POD_NAME
事件主體應類似於下列內容:
2024/04/18 20:31:43 Hello from Cloud Run! The container started successfully and is listening for HTTP requests on $PORT {"severity":"INFO","eventType":"google.cloud.pubsub.topic.v1.messagePublished","message":"Received event of type google.cloud.pubsub.topic.v1.messagePublished. Event data: Hello World","event":{"specversion":"1.0","id":"10935738681111260","source":"//pubsub.googleapis.com/projects/my-project/topics/eventarc-us-central1-my-trigger-224","type":"google.cloud.pubsub.topic.v1.messagePublished","datacontenttype":"application/json","time":"2024-04-18T20:40:03Z","data": {"message":{"data":"SGVsbG8gV29ybGQ=","messageId":"10935738681111260","publishTime":"2024-04-18T20:40:03Z"}}}}
您已成功將事件接收者服務部署至私人 GKE 叢集中的內部 HTTP 端點、建立 Eventarc 觸發條件、從 Pub/Sub 產生事件,並確認觸發條件已將事件如預期地路由至目標端點。
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。
刪除專案
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
刪除個別資源
- 刪除 Eventarc 觸發條件:
gcloud eventarc triggers delete my-trigger --location=us-central1
- 退出 VM,然後刪除 VM 執行個體:
gcloud compute instances delete my-vm --zone=us-central1-a
- 刪除網路連結:
gcloud compute network-attachments delete my-network-attachment --region=us-central1
- 刪除防火牆規則:
gcloud compute firewall-rules delete allow-proxy-connection
- 刪除叢集:
gcloud container clusters delete private-cluster --region=us-central1
- Delete the subnet:
gcloud compute networks subnets delete proxy-only-subnet --region=us-central1