目標
- 建立 Cloud DNS 代管區域,用於代管工作站集區的記錄。
- 建立 Node.js 應用程式,處理虛擬私有雲網路的輸入流量。
- 部署具有直接虛擬私有雲連入流量的 worker 集區,將子網路中的私人 IP 位址指派給 worker 執行個體。
- 測試應用程式,從相同虛擬私有雲網路中的虛擬機器 (VM) 執行個體存取私人 IP 位址。
費用
在本文件中,您會使用下列 Google Cloud的計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
事前準備
- 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
-
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 role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
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 role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
啟用 Cloud DNS、Cloud Run、Compute Engine、Artifact Registry 和 Cloud Build API。
啟用 API 時所需的角色
如要啟用 API,您需要服務使用情形管理員 IAM 角色 (
roles/serviceusage.serviceUsageAdmin),其中包含serviceusage.services.enable權限。瞭解如何授予角色。- 安裝並初始化 gcloud CLI。
- 更新元件:
gcloud components update
- 執行下列指令來設定專案 ID:
將 PROJECT_ID 替換為專案 ID。 Google Cloudgcloud config set project PROJECT_ID
必要的角色
如要取得完成本教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:
-
Artifact Registry 存放區管理員 (
roles/artifactregistry.repoAdmin) -
Cloud Build 編輯者 (
roles/cloudbuild.builds.editor) - Cloud Run 管理員 (
roles/run.admin) -
建立服務帳戶 (
roles/iam.serviceAccountCreator) -
Cloud DNS 管理員 (
roles/dns.admin) -
服務帳戶使用者 (
roles/iam.serviceAccountUser) -
服務使用情形消費者 (
roles/serviceusage.serviceUsageConsumer)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
建立自訂服務帳戶
建立自訂服務帳戶,並授予註冊 DNS 記錄所需的最低權限。如要設定服務帳戶,請按照下列步驟操作:
執行下列指令,建立服務帳戶:
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \ --display-name="DNS Worker Pool Service Account"
將 SERVICE_ACCOUNT_NAME 替換為自訂服務帳戶的名稱,例如
dns-worker-sa。將 Cloud DNS 管理員角色授予服務帳戶:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/dns.admin"
建立 Cloud DNS 區域
建立名為 test-wp 的私人 Cloud DNS 代管區域,註冊工作站集區的執行個體 IP。
gcloud dns managed-zones create test-wp --description="new DNS zone for worker pools" --dns-name="workerpools.example.com." --visibility="private" --networks=default
建立 Node.js 應用程式
建立 Node.js 應用程式,使用中繼資料伺服器擷取工作站集區執行個體的 IP 位址,然後向 Cloud DNS 註冊。
建立名為
worker的資料夾,然後將目錄變更為該資料夾:mkdir worker cd worker建立名為
setup_dns.sh的檔案,並新增下列指令碼,在工作站集區執行個體啟動時執行。這個指令碼會使用執行個體主機名稱產生 DNS 記錄名稱。如果有多個執行個體,多個執行個體可能會使用相同的主機名稱,導致建立重疊的 DNS 記錄。#!/bin/bash # --- Variables --- # The name of your Cloud DNS managed zone. ZONE_NAME="test-wp" # The base domain suffix for the DNS entry. Use the part *after* the hostname. # For example, for "testinstance.workerpools.example.com.", the suffix is ".workerpools.example.com." DNS_SUFFIX=".workerpools.example.com." # The Time-To-Live (TTL) in seconds. TTL="300" # The record type (A for IPv4). RECORD_TYPE="A" # ----------------- # 1. Dynamically generate DNS_NAME # Get the simple hostname (e.g., "testinstance") and append the defined suffix. # We use 'hostname -s' to get the short hostname. SHORT_HOSTNAME=$(hostname -s) DNS_NAME="${SHORT_HOSTNAME}${DNS_SUFFIX}" # 2. Dynamically assign NEW_IP # Get the IP address from metadata server using predefined key. NEW_IP=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip" -H "Metadata-Flavor: Google") # --- Input Validation --- if [ -z "$NEW_IP" ]; then echo "❌ ERROR: Could not obtain a valid IP address from metadata server. Aborting." exit 1 fi echo "Starting DNS record update for ${DNS_NAME} in zone ${ZONE_NAME}..." echo "New IP detected on this instance: ${NEW_IP}" # 3. Get the current existing IP address (if any) # This is required to know what to put in the --rrdatas for the delete command. EXISTING_IP=$(gcloud dns record-sets list \ --zone="${ZONE_NAME}" \ --name="${DNS_NAME}" \ --type="${RECORD_TYPE}" \ --format="value(rrdatas[0])" 2>/dev/null) # --- Conditional Deletion/Skip Check --- if [ -n "$EXISTING_IP" ] && [ "$EXISTING_IP" != "$NEW_IP" ]; then echo "Found existing IP: ${EXISTING_IP}. It is different from the new IP." # Delete the existing record echo "Deleting old record..." gcloud dns record-sets delete "${DNS_NAME}" \ --zone="${ZONE_NAME}" \ --type="${RECORD_TYPE}" \ --quiet if [ $? -ne 0 ]; then echo "❌ ERROR: Failed to delete existing record. Aborting." exit 1 fi elif [ -n "$EXISTING_IP" ] && [ "$EXISTING_IP" == "$NEW_IP" ]; then echo "Existing IP (${EXISTING_IP}) matches the new IP. Skipping update." exit 0 else echo "No existing record found for ${DNS_NAME}. Proceeding with creation." fi # ---------------------------------------- # 4. Add the new record echo "Creating new record with IP: ${NEW_IP}..." gcloud dns record-sets create "${DNS_NAME}" \ --zone="${ZONE_NAME}" \ --type="${RECORD_TYPE}" \ --ttl="${TTL}" \ --rrdatas="${NEW_IP}" # Final status check if [ $? -eq 0 ]; then echo "✅ Successfully created/updated DNS record for ${DNS_NAME} to ${NEW_IP}." else echo "❌ ERROR: Failed to create the new DNS record." exit 1 fi建立
server.js檔案,並加入下列程式碼來處理私人 IP 位址連入:// server.js // 1. Import the built-in 'http' module console.log("hello from worker pool") const http = require('http'); // Define the port the server will listen on const PORT = 3000; // 2. Create the server instance const server = http.createServer((req, res) => { // Set the response HTTP header with status and type of content res.writeHead(200, {'Content-Type': 'text/plain'}); // Write the response body res.end('Hello World!\n'); }); // 3. Start the server and listen on the specified port server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}/`); });建立
start.sh指令碼,內含下列程式碼,先執行 DNS 設定,再執行 Node.js 應用程式:#!/bin/bash set -e # 1. Execute the setup script echo "Running setup_dns.sh..." /app/setup_dns.sh # 2. Run the main application echo "Starting server.js..." exec node /app/server.js建立下列 Dockerfile,將應用程式封裝至映像檔中:
# Choose a base image. This image includes gcloud, kubectl, etc. FROM google/cloud-sdk:latest # Install Node.js on top of the Cloud SDK image. RUN apt-get update && \ apt-get install -y curl && \ curl -sL https://deb.nodesource.com/setup_lts.x | bash - && \ apt-get install -y nodejs && \ # Clean up to reduce image size apt-get clean && \ rm -rf /var/lib/apt/lists/* # Set the working directory inside the container. WORKDIR /app # Copy the application and scripts into the container. COPY setup_dns.sh . COPY server.js . COPY start.sh . # Make both scripts executable. RUN chmod +x setup_dns.sh start.sh # Define the entrypoint and default command. ENTRYPOINT ["/app/start.sh"] CMD []
部署具有直接虛擬私有雲連入流量的工作站集區
部署名為 test-cli-dns 的工作站集區,並將其附加至虛擬私有雲網路。
gcloud beta run worker-pools deploy test-cli-dns \ --network default \ --subnet default \ --region us-central1 \ --source . \ --service-account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com \ --project PROJECT_ID
將 PROJECT_ID 替換為 Google Cloud 專案 ID,並將 SERVICE_ACCOUNT_NAME 替換為您建立的服務帳戶名稱。
測試應用程式
Cloud Run worker 集區搭配直接虛擬私有雲輸入流量,專為僅限內部流量設計。沒有公開 IP。如要驗證 Ingress 功能,請按照下列步驟,使用 curl 從託管在相同 VPC 網路和子網路的 Compute Engine VM 執行要求:
在與工作站集區相同的網路和區域中,建立測試 VM:
gcloud compute instances create wp-test-vm \ --zone=us-central1-a \ --network=default \ --subnet=default執行下列指令,透過 SSH 連線至測試 VM:
gcloud compute ssh wp-test-vm --zone=us-central1-a在 VM 終端機中,透過向 Cloud DNS 註冊的工作站集區執行個體私人 IP 位址,叫用您的服務:
curl http://localhost.workerpools.example.com:3000您應該會看到以下輸出內容:
Hello World!
大功告成!您已使用私人 IP 位址和 Cloud DNS,透過直接虛擬私有雲連入功能,成功設定 Cloud Run 工作站集區。
清除所用資源
為避免系統向您的 Google Cloud 帳戶收取額外費用,請刪除您在本教學課程中部署的所有資源。
刪除專案
如果您是為了這個教學課程建立新專案,請刪除該專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源。
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。
刪除專案的方法如下:
- 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。
- 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。
刪除教學課程資源
刪除您在本教學課程中部署的 Cloud Run 服務。Cloud Run 服務收到要求後才會開始計費。
如要刪除 Cloud Run 服務,請執行下列指令:
gcloud run services delete SERVICE-NAME
將 SERVICE-NAME 改為您的服務名稱。
您也可以從Google Cloud 控制台刪除 Cloud Run 服務。
移除您在教學課程設定期間新增的
gcloud預設區域設定:gcloud config unset run/region移除專案設定:
gcloud config unset project刪除在本教學課程中建立的其他 Google Cloud 資源:
- 刪除 Cloud Run 工作站集區。
- 從 Artifact Registry 刪除工作站集區容器映像檔。
- 刪除 Cloud DNS 代管區域。
後續步驟
- 進一步瞭解如何透過虛擬私有雲網路設定直接虛擬私有雲。
- 進一步瞭解 Cloud Run 工作站集區。
- 探索其他 Cloud Run 示範、教學課程和範例。