为第 2 代函数配置直接 VPC 出站流量
借助直接 VPC 出站流量,您可以将 Cloud Run functions 函数(第 2 代)的流量直接路由到 VPC 网络。
限制
- 直接 VPC 出站流量不适用于第 1 代函数。
- 您无法同时使用直接 VPC 出站流量和无服务器 VPC 访问通道连接器。如需了解详情,请参阅比较直接 VPC 出站流量和 VPC 连接器。
准备工作
- 启用 Cloud Functions API。
- 安装 Google Cloud CLI,然后通过运行
gcloud init对其进行初始化。 将
gcloud组件更新到 545.0.0 版或更高版本:gcloud components update
如果您的项目中还没有 VPC 网络,请创建一个 VPC 网络。
可选:如果您的函数需要使用 Google API 和服务的内部 IP 地址来访问它们,请在您用于直接 VPC 出站流量的子网上启用专用 Google 访问通道。
设置 IAM 权限
如需授权直连 VPC 出站流量,请让您的管理员向函数的服务账号授予 Cloud Run Invoker (roles/run.invoker) 角色。
使用以下方法之一确保 Cloud Run 可以访问 VPC 网络:
Cloud Run Service Agent 角色:默认情况下,Cloud Run 服务代理具有 Cloud Run Service Agent 角色 (
roles/run.serviceAgent),该角色含有必要的权限。自定义权限:如需进行更精细的控制,请向 Cloud Run 服务代理授予对项目的以下额外权限:
compute.networks.getcompute.subnetworks.get- 项目或特定子网的
compute.subnetworks.use权限 compute.addresses.getcompute.addresses.listcompute.addresses.create(仅对具有外部 IPv6 的双栈子网是必需的)compute.addresses.delete(仅对具有外部 IPv6 的双栈子网是必需的)compute.addresses.createInternalcompute.addresses.deleteInternalcompute.regionOperations.get
Compute Network User 角色:如果您不使用默认 Cloud Run Service Agent 角色或自定义权限,请授予 Cloud Run Service Agent 服务账号的 Compute Network User 角色 (
roles/compute.networkUser)。具有外部 IPv6 的子网还需要 Compute Public IP Admin 角色 (roles/compute.publicIpAdmin)。例如,如需授予 Compute Network User 角色,请运行以下命令:
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com" \ --role "roles/compute.networkUser"
替换以下内容:
- PROJECT_ID:您的项目的 ID。
- PROJECT_NUMBER:您在其中部署 Cloud Run 函数的项目编号。
配置直接 VPC 出站流量
为新的或现有的第 2 代函数配置直接 VPC 出站流量。
gcloud
如需在部署函数时配置直接 VPC 出站流量,请使用
gcloud beta functions deploy命令并添加网络设置标志。gcloud beta functions deploy FUNCTION_NAME \ --source . \ --runtime RUNTIME \ --trigger-http \ --region REGION \ --network=NETWORK \ --subnet=SUBNET \ --network-tags=NETWORK_TAG_NAMES \ --direct-vpc-egress=EGRESS_SETTING替换以下内容:
- FUNCTION_NAME:函数的名称。
- RUNTIME:函数的运行时,例如
nodejs20。 - REGION:部署函数的区域。
- 可选:将 NETWORK 替换为 VPC 网络的名称。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。
- 可选:将 SUBNET 替换为子网的名称。指定 VPC 网络或子网,或同时指定两者。如果您仅指定网络,则子网会使用与网络相同的名称。您可以在同一子网上部署或执行多个函数。
- 可选:将 NETWORK_TAG_NAMES 替换为要与函数关联的网络标记的名称。每个函数都可以有不同的网络标记,例如
network-tag-2。 - 将 EGRESS_SETTING 替换为出站流量设置值:
all:默认值。通过 VPC 网络发送所有出站流量。private-ranges-only:仅发送通过 VPC 网络发送到内部地址的流量。
可选:如需从函数中移除所有直接 VPC 出站流量设置,请使用
--clear-network和--clear-network-tags标志重新部署函数。
Terraform
如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。
如需配置直接 VPC 出站流量,请使用 google-beta Terraform 提供程序。
以 Cloud Run functions(第 2 代)直接 VPC 出站流量示例为起点,更新以下字段:
service_config.network:您的 VPC 网络的名称。service_config.subnetwork:您的 VPC 子网的名称。service_config.direct_vpc_egress:要将哪些流量发送到 VPC 网络。VPC_EGRESS_ALL_TRAFFIC通过 VPC 网络发送所有出站流量。VPC_EGRESS_PRIVATE_RANGES_ONLY仅将流量发送到 VPC 网络的专用 IP 地址范围。
示例:从函数调用内部服务
此示例展示了如何创建内部 Cloud Run 服务,然后通过使用直接 VPC 出站流量的 Cloud Run functions(第 2 代)函数调用该服务。
创建内部后端服务
为后端服务创建一个新目录,并切换到该目录:
mkdir backend-service cd backend-service创建一个包含以下内容的
package.json文件:{ "name": "backend-service", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.1" } }创建一个包含以下内容的
index.js文件:const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send("hello world"); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`helloworld: listening on port ${port}`); });将服务部署到 Cloud Run,并使用内部入站流量:
gcloud run deploy backend \ --source . \ --no-allow-unauthenticated \ --region=REGION \ --ingress internal将
REGION替换为您的区域,例如us-west1。保存新服务的网址。您将在下一部分中用到该地址。
创建和部署函数
为函数创建新目录,并转到该目录:
cd .. mkdir dvpc-function cd dvpc-function创建一个包含以下内容的
package.json文件:{ "name": "sample-http", "version": "0.0.1", "dependencies": { "axios": "0.21.1", "@google-cloud/functions-framework": "^3.0.0" } }创建一个包含以下内容的
index.js文件。此代码向内部后端服务发出经过身份验证的请求。const axios = require('axios'); const functions = require('@google-cloud/functions-framework'); const callVPCService = async (req, res) => { const backendUrl = process.env.BACKEND_URL; if (!backendUrl) { console.error('BACKEND_URL environment variable not set.'); res.status(500).send('BACKEND_URL not configured.'); return; } try { const metadataServerURL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience='; const tokenUrl = metadataServerURL + backendUrl; const tokenResponse = await axios.get(tokenUrl, { headers: { 'Metadata-Flavor': 'Google', }, }); const token = tokenResponse.data; const response = await axios.get(backendUrl, { headers: { Authorization: `bearer ${token}`, }, }); res.status(200).send(`Response from backend: ${response.data}`); } catch (error) { console.error(`Error calling backend service: ${error.message}`); res.status(500).send(`Error calling backend: ${error.message}`); } }; functions.http('callVPCService', callVPCService);部署配置了直接 VPC 出站流量的函数,以将所有流量路由到您的默认 VPC 网络:
gcloud beta functions deploy my-2ndgen-function \ --source . \ --runtime nodejs20 \ --trigger-http \ --entry-point callVPCService \ --network=default \ --subnet=default \ --direct-vpc-egress=all \ --region=REGION \ --allow-unauthenticated \ --set-env-vars BACKEND_URL=BACKEND_URL替换以下内容:
REGION:您部署后端服务的区域。BACKEND_URL:您创建的后端服务的网址。
函数部署后,访问其网址即可调用该函数。该函数会调用内部后端服务并返回其响应。
后续步骤
- 了解直接 VPC 出站流量和 IP 分配。
- 请参阅问题排查提示。
- 如需比较出站流量方法,请参阅连接到 VPC 网络。
- 请参阅
gcloud beta functions deploy命令参考。