為第 2 代函式設定直接虛擬私有雲輸出流量
透過直接虛擬私有雲輸出,您可以將 Cloud Run 函式 (第 2 代) 的流量直接轉送至虛擬私有雲網路。
限制
- 直接虛擬私有雲輸出功能不適用於第 1 代函式。
- 您無法同時使用直接虛擬私有雲輸出和無伺服器虛擬私有雲存取連接器。詳情請參閱「比較直接虛擬私有雲輸出和虛擬私有雲連接器」。
事前準備
- 啟用 Cloud Functions API。
- 安裝 Google Cloud CLI,然後執行
gcloud init初始化。 將
gcloud元件更新至 545.0.0 以上版本:gcloud components update
如果專案中沒有虛擬私有雲網路,請建立一個。
選用:如果函式需要使用內部 IP 位址存取 Google API 和服務,請在用於直接虛擬私有雲端輸出流量的子網路上啟用私人 Google 存取權。
設定 IAM 權限
如要授權直接 VPC 輸出,請要求管理員將 Cloud Run 叫用者 (roles/run.invoker) 角色授予函式的服務帳戶。
請使用下列其中一種方法,確保 Cloud Run 可以存取虛擬私有雲網路:
Cloud Run 服務代理程式角色:根據預設,Cloud Run 服務代理程式具有Cloud Run 服務代理程式角色 (
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 網路使用者角色,請執行下列指令:
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 函式的專案編號。
設定直接虛擬私有雲輸出
為新函式或現有第 2 代函式設定直接虛擬私有雲輸出流量。
gcloud
如要在部署函式時設定直接虛擬私有雲輸出,請使用
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,這是您虛擬私有雲網路的名稱。指定虛擬私有雲網路或子網路,或同時指定兩者。如果您只指定網路,子網路會使用與網路相同的名稱。
- 選用:SUBNET,並將其替換為子網路名稱。指定虛擬私有雲網路或子網路,或兩者皆指定。如果您只指定網路,子網路會使用與網路相同的名稱。您可以在同一個子網路上部署或執行多個函式。
- 選用:NETWORK_TAG_NAMES,並以半形逗號分隔要與函式建立關聯的網路標記名稱。每個函式可以有不同的網路標記,例如
network-tag-2。 - EGRESS_SETTING,並提供輸出設定值:
all:預設值。透過虛擬私有雲網路傳送所有輸出流量。private-ranges-only:只透過虛擬私有雲網路將流量傳送至內部位址。
選用:如要從函式中移除所有 Direct VPC 輸出設定,請使用
--clear-network和--clear-network-tags旗標重新部署函式。
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
如要設定直接虛擬私有雲輸出流量,請使用 google-beta Terraform
供應商。
以 Cloud Run 函式 (第 2 代) 直接虛擬私有雲輸出範例為起點,更新下列欄位:
service_config.network:虛擬私有雲網路的名稱。service_config.subnetwork:虛擬私有雲子網路的名稱。service_config.direct_vpc_egress:要傳送至虛擬私有雲網路的流量。VPC_EGRESS_ALL_TRAFFIC透過虛擬私有雲網路傳送所有輸出流量。VPC_EGRESS_PRIVATE_RANGES_ONLY只會將流量傳送至虛擬私有雲網路的私人 IP 位址範圍。
範例:從函式呼叫內部服務
這個範例說明如何建立內部 Cloud Run 服務,然後從使用直接虛擬私有雲輸出流量的 Cloud Run 函式 (第 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,並使用內部 Ingress:
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);部署函式並設定直接虛擬私有雲 egress,將所有流量轉送至預設虛擬私有雲網路:
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:您建立的後端服務網址。
函式部署完成後,請前往函式網址來叫用函式。函式會呼叫內部後端服務,並傳回其回應。
後續步驟
- 瞭解直接虛擬私有雲輸出和 IP 分配。
- 請參閱疑難排解提示。
- 如要比較輸出方法,請參閱「連線至虛擬私有雲網路」。
- 請參閱
gcloud beta functions deploy指令參考資料。