在虛擬私有雲網路的內部 HTTP 端點接收 Pub/Sub 事件

本教學課程說明如何在虛擬私有雲 (VPC) 網路中建立內部 HTTP 端點,透過 Eventarc 接收 Pub/Sub 訊息事件。如要進一步瞭解這個事件目的地,請參閱「將事件傳送至虛擬私有雲網路中的內部 HTTP 端點」。

您可以在終端機或 Cloud Shell 中,使用 Google Cloud CLI 執行下列指令。

目標

在這個教學課程中,您將執行下列操作:

  1. 建立虛擬私有雲網路,為雲端資源和服務提供網路。虛擬私有雲網路在邏輯上與 Google Cloud中的其他網路隔離。
  2. 建立子網路。每個虛擬私有雲網路都含有一或多個稱為「子網路」的 IP 位址範圍。子網路是區域資源,具有相關聯的 IP 位址範圍。
  3. 建立虛擬私有雲防火牆規則,允許或拒絕虛擬私有雲網路中,虛擬機器 (VM) 執行個體的往來流量。
  4. 建立網路連結,讓供應商虛擬私有雲網路啟動與用戶虛擬私有雲網路的連線。
  5. 在 VPC 網路中建立 Compute Engine VM 執行個體。
  6. 在 VM 執行個體上,將網路伺服器部署為事件接收器服務。
  7. 建立 Eventarc 觸發條件,將 Pub/Sub 事件轉送至 VM 執行個體上的事件接收器。
  8. 建立與 VM 執行個體的 SSH 連線。
  9. 將訊息發布至 Pub/Sub 主題來產生事件,並在「直接透過瀏覽器進行 SSH 連線」工具中查看事件主體。

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用 Compute Engine、Eventarc 和 Pub/Sub API:

    啟用 API 時所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com eventarc.googleapis.com pubsub.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用 Compute Engine、Eventarc 和 Pub/Sub API:

    啟用 API 時所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com eventarc.googleapis.com pubsub.googleapis.com
  14. 更新 Google Cloud CLI 元件:
    gcloud components update
  15. 登入帳戶:
    gcloud auth login
  16. 設定本快速入門導覽課程中使用的設定變數:
    REGION=us-central1
    ZONE=us-central1-a
  17. 如果您是專案建立者,系統會授予基本「擁有者」角色 (roles/owner)。根據預設,這個身分與存取權管理 (IAM) 角色包含完全存取大多數 Google Cloud資源所需的權限,因此您可以略過這個步驟。

    如果您不是專案建立者,必須在專案中將必要權限授予適當的主體。舉例來說,主體可以是 Google 帳戶 (適用於使用者) 或服務帳戶 (適用於應用程式和運算工作負載)。詳情請參閱活動目的地的「角色和權限」頁面。

    所需權限

    如要取得完成本快速入門導覽課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

    您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

  18. 如果您是在 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
    取代下列項目:
    • PROJECT_ID:您的 Google Cloud 專案 ID
    • PROJECT_NUMBER:您的 Google Cloud 專案編號。您可以在 Google Cloud 控制台的「歡迎」頁面找到專案編號,也可以執行下列指令:
      gcloud projects describe PROJECT_ID --format='value(projectNumber)'

建立自訂模式虛擬私有雲網路

虛擬私有雲網路是實體網路的虛擬版本,建構於 Google 的正式環境網路之內。並為 Compute Engine VM 執行個體提供連線。

建立自訂模式虛擬私有雲網路時,系統不會自動建立子網路。這類型網路可讓您完全控制其中的子網路和 IP 範圍。

gcloud compute networks create NETWORK_NAME \
    --subnet-mode=custom \
    --bgp-routing-mode=regional \
    --mtu=1460

NETWORK_NAME 替換為虛擬私有雲網路的名稱。

注意事項:

  • 您建立的每一個網路,在專案中的名稱均不可重複。
  • 邊界閘道通訊協定 (BGP) 轉送模式可控制網路中 Cloud Router 的行為,可以是 globalregional。預設值為 regional
  • 最大傳輸單位 (MTU) 是網路的最大封包大小。MTU 可設為 13008896 之間的任何值。預設值為 1460。將 MTU 設為大於 1460 的值之前,請先參閱「最大傳輸單位」。

詳情請參閱「建立及管理虛擬私有雲網路」。

建立僅限 IPv4 的子網路

網路至少要有一個子網路,您才能開始使用。

建立子網路時,須設定名稱、區域,以及至少一個主要 IPv4 位址範圍 (以子網路規則為準)。請注意,您無法在未定義子網路的區域中建立執行個體。

gcloud compute networks subnets create SUBNET_NAME \
    --region=$REGION \
    --network=NETWORK_NAME \
    --range=10.10.10.0/24

SUBNET_NAME 替換為新子網路的名稱。

詳情請參閱「子網路」。

建立虛擬私有雲防火牆規則

虛擬私有雲防火牆規則可讓您根據通訊埠號碼、標記或通訊協定,允許或拒絕虛擬私有雲網路中資源之間的流量。

虛擬私有雲防火牆規則是在網路層級定義,且僅會套用到規則建立時所在的網路。不過,您為規則選擇的名稱在專案內必須為專屬名稱。

  1. 為虛擬私有雲網路建立防火牆規則,允許來自任何 IPv4 位址 (0.0.0.0/0) 的輸入流量,透過通訊埠 22 傳送至網路上的任何執行個體。傳送活動時不需要這項規則。不過,在本教學課程中,請建立規則,以便使用 SSH 連線至 VM,並確認事件是否已傳送:

    gcloud compute firewall-rules create RULE_NAME_ONE \
        --network=projects/PROJECT_ID/global/networks/NETWORK_NAME \
        --direction=INGRESS \
        --priority=65534 \
        --action=ALLOW \
        --source-ranges=0.0.0.0/0 \
        --rules=tcp:22
  2. 為虛擬私有雲網路建立防火牆規則,允許來自特定 IP 位址範圍的輸入流量,透過通訊埠 80 傳送至網路上的任何執行個體 (因為您會在 VM 上部署接聽通訊埠 80 的網路伺服器):

    gcloud compute firewall-rules create RULE_NAME_TWO \
        --network=projects/PROJECT_ID/global/networks/NETWORK_NAME \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --source-ranges=10.10.10.0/24 \
        --rules=tcp:80

    RULE_NAME_ONERULE_NAME_TWO 替換為防火牆規則的專屬名稱。

    請注意,--source-ranges 為選用項目,表示允許建立連入連線的 IP 位址區塊清單,這些連線符合網路中執行個體的防火牆規則。在本例中,範圍與先前建立的子網路所用範圍相符。

    建議您使用這個標記,將防火牆規則套用至 Eventarc 流量。如未指定 --source-ranges--source-tags--source-ranges 預設為 0.0.0.0/0,表示規則會套用至網路內外所有傳入的 IPv4 連線。

詳情請參閱「使用虛擬私有雲防火牆規則」。

建立網路連結

網路連結是一種資源,可讓供應商虛擬私有雲網路透過 Private Service Connect 介面,連線至用戶虛擬私有雲網路。

發布事件時,Eventarc 會使用網路連結,與虛擬私有雲網路中託管的內部 HTTP 端點建立連線。

您可以建立網路連結,自動接受來自任何參照該網路連結的 Private Service Connect 介面連線。在包含 HTTP 目的地服務的相同網路和區域中,建立網路附件。

gcloud compute network-attachments create ATTACHMENT_NAME \
    --region=$REGION \
    --subnets=SUBNET_NAME \
    --connection-preference=ACCEPT_AUTOMATIC

ATTACHMENT_NAME 替換為網路附件的名稱。

詳情請參閱「關於網路連結」。

在指定子網路中建立 VM 執行個體

Compute Engine VM 執行個體是指託管在 Google 基礎架構上的虛擬機器。「Compute Engine 執行個體」、「VM 執行個體」和「VM」這幾個詞是同義詞,可以互換使用。VM 執行個體包括 Google Kubernetes Engine (GKE) 叢集、App Engine 彈性環境執行個體,以及其他 Google Cloud 以 Compute Engine VM 為基礎建構的產品。

在虛擬私有雲網路中建立 Compute Engine VM 執行個體,以便部署事件接收器服務。

gcloud compute instances create INSTANCE_NAME \
      --zone=$ZONE \
      --machine-type=e2-medium \
      --subnet=SUBNET_NAME

INSTANCE_NAME 替換為 VM 的名稱。

詳情請參閱「建立及啟動 VM 執行個體」。

在 VM 上部署事件接收器

在 VM 上部署網路伺服器,監聽通訊埠 80,並接收及記錄事件。

  1. 使用 Google Cloud 控制台中的「SSH」按鈕,建立與 VM 執行個體的 SSH 連線。

    建立與 SSH 伺服器的連線後,請使用瀏覽器中的 SSH 終端機,在 VM 執行個體上執行指令。

  2. 在瀏覽器內 SSH 終端機中,建立名為 server.py 的文字檔,其中包含下列 Python 程式碼:

    #!/usr/bin/env python3
    from http.server import BaseHTTPRequestHandler, HTTPServer
    import logging
    
    class S(BaseHTTPRequestHandler):
        def _set_response(self):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
    
        def do_GET(self):
            logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
            self._set_response()
            self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))
    
        def do_POST(self):
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
                    str(self.path), str(self.headers), post_data.decode('utf-8'))
    
            self._set_response()
            self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
    
    def run(server_class=HTTPServer, handler_class=S, port=80):
        logging.basicConfig(level=logging.INFO)
        server_address = ('', port)
        http_server = server_class(server_address, handler_class)
        logging.info('Starting HTTP Server at port %d...\n', port)
        try:
            http_server.serve_forever()
        except KeyboardInterrupt:
            pass
        http_server.server_close()
        logging.info('Stopping HTTP Server...\n')
    
    if __name__ == '__main__':
        from sys import argv
    
        if len(argv) == 2:
            run(port=int(argv[1]))
        else:
            run()
  3. 啟動伺服器,並在完成本教學課程的其餘步驟時保持伺服器運作:

    sudo python3 server.py
    

建立 Eventarc 觸發條件

建立 Eventarc 觸發條件,在訊息發布至 Pub/Sub 主題時,建立新的 Pub/Sub 主題,並將事件傳送至部署在 VM 上的事件接收器。

啟用 Compute Engine API 後,預設服務帳戶會是 Compute Engine 預設服務帳戶 (PROJECT_NUMBER-compute@developer.gserviceaccount.com)。為進行測試,觸發程序會使用這個預設服務帳戶做為身分。

gcloud eventarc triggers create TRIGGER_NAME \
    --location=$REGION \
    --destination-http-endpoint-uri=http://INSTANCE_NAME.$ZONE.c.PROJECT_ID.internal \
    --network-attachment="projects/PROJECT_ID/regions/$REGION/networkAttachments/ATTACHMENT_NAME" \
    --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 主題,即可產生事件。

  1. 找出 Pub/Sub 主題並設為環境變數:

    export MY_TOPIC=$(gcloud eventarc triggers describe TRIGGER_NAME \
        --location=$REGION \
        --format='value(transport.pubsub.topic)')
  2. 將訊息發布至 Pub/Sub 主題,產生事件:

    gcloud pubsub topics publish $MY_TOPIC --message "Hello World"

    Eventarc 觸發條件會將事件轉送至虛擬私有雲網路中的內部 HTTP 端點。在瀏覽器中的 SSH 終端機中,系統會輸出事件主體。內容應如下所示:

    Body:
    {
        "message": {
            "data": "SGVsbG8gV29ybGQ=",
            "messageId": "8795720366614192",
            "publishTime": "2023-08-26T13:09:48Z"
        }
    }
    
    10.10.10.3 - - [26/Aug/2023 13:09:49] "POST / HTTP/1.1" 200 -
    

    請注意,如果從 Base64 格式解碼 SGVsbG8gV29ybGQ=data 值,系統會傳回「Hello World」。

您已成功將事件接收者服務部署至虛擬私有雲網路的內部 HTTP 端點、建立 Eventarc 觸發條件、從 Pub/Sub 產生事件,並確認觸發條件已將事件如預期地路由至目標端點。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

    刪除 Google Cloud 專案:

    gcloud projects delete PROJECT_ID

刪除個別資源

  1. 刪除 Eventarc 觸發條件:
    gcloud eventarc triggers delete TRIGGER_NAME --location=$REGION
  2. 刪除執行個體:
    gcloud compute instances delete INSTANCE_NAME
  3. 刪除網路連結:
    gcloud compute network-attachments delete ATTACHMENT_NAME --region=$REGION
  4. 刪除防火牆規則:
    gcloud compute firewall-rules delete RULE_NAME_ONE
    gcloud compute firewall-rules delete RULE_NAME_TWO
  5. 刪除子網路:
    gcloud compute networks subnets delete SUBNET_NAME --region=$REGION
  6. 刪除虛擬私有雲網路:
    gcloud compute networks delete NETWORK_NAME

後續步驟