目标
- 创建 Cloud DNS 托管地区,以托管工作池的记录。
- 创建 Node.js 应用,以处理 VPC 网络上的入站流量。
- 部署具有直接 VPC 入站流量的工作器池,以便将子网中的专用 IP 地址分配给工作器实例。
- 测试您的应用,以从同一 VPC 网络中的虚拟机 (VM) 实例访问专用 IP 地址。
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
如需根据您的预计使用情况来估算费用,请使用价格计算器。
准备工作
- 登录您的 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 API、Cloud Run API、Compute Engine API、Artifact Registry API 和 Cloud Build API。
启用 API 所需的角色
如需启用 API,您需要拥有 Service Usage Admin IAM 角色 (
roles/serviceusage.serviceUsageAdmin),该角色包含serviceusage.services.enable权限。了解如何授予角色。- 安装并初始化 gcloud CLI。
- 更新组件:
gcloud components update
- 运行以下命令来设置项目 ID:
将 PROJECT_ID 替换为您的 Google Cloud 项目的 ID。gcloud config set project PROJECT_ID
所需的角色
如需获得完成本教程所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:
-
Artifact Registry Repository Administrator (
roles/artifactregistry.repoAdmin) -
Cloud Build Editor (
roles/cloudbuild.builds.editor) -
Cloud Run Admin (
roles/run.admin) -
Create Service Accounts (
roles/iam.serviceAccountCreator) -
Cloud DNS Admin (
roles/dns.admin) -
Service Account User (
roles/iam.serviceAccountUser) -
Service Usage Consumer (
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 Admin 角色授予服务账号:
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脚本,以便在运行 Node.js 应用之前先执行 DNS 设置:#!/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 []
部署使用直接 VPC 入站流量的工作器池
部署名为 test-cli-dns 的工作器池,并将其附加到 VPC 网络。
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 替换为您创建的服务账号的名称。
测试您的应用
采用直接 VPC 入站流量的 Cloud Run 工作器池专为仅限内部的流量而设计。它们没有公共 IP。如需验证入站流量功能,请按照以下步骤操作,从托管在同一 VPC 网络和子网中的 Compute Engine 虚拟机使用 curl 运行请求:
在与工作器池相同的网络和区域中创建测试虚拟机:
gcloud compute instances create wp-test-vm \ --zone=us-central1-a \ --network=default \ --subnet=default运行以下命令,通过 SSH 连接到测试虚拟机:
gcloud compute ssh wp-test-vm --zone=us-central1-a在虚拟机终端中,通过在 Cloud DNS 中注册的工作池实例的专用 IP 地址调用您的服务:
curl http://localhost.workerpools.example.com:3000您应该会看到以下输出:
Hello World!
大功告成!您已成功使用专用 IP 地址和 Cloud DNS 配置了具有直接 VPC 入站流量的 Cloud Run 工作池。
清理
为避免您的 Google Cloud 账号产生额外费用,请删除您在本教程中部署的所有资源。
删除项目
如果您为本教程创建了一个新项目,请删除项目。 如果您使用的是某个现有项目,并且需要保留此项目但不保留在本教程中所做的更改,请删除为本教程创建的资源。
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
要删除项目,请执行以下操作:
- 在 Google Cloud 控制台中,前往管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
删除教程资源
删除您在本教程中部署的 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 代管式区域。
后续步骤
- 详细了解如何通过 VPC 网络配置直接 VPC。
- 详细了解 Cloud Run 工作器池。
- 探索其他 Cloud Run 演示、教程和示例。