建構程序總覽

本指南將概略介紹使用 gcloud functions 指令部署的函式適用的建構程序。如要瞭解使用 gcloud run 指令部署的函式適用的建構程序,請參閱下列文章:

使用 gcloud functions deploy 指令部署函式原始碼時,該原始碼會儲存在 Cloud Storage bucket 中。Cloud Build 接著會自動在容器映像檔中建構原始碼,並將該映像檔推送至映像檔註冊資料庫

建構映像檔的程序為全自動進行,您不需要直接輸入任何內容。建構程序中使用的所有資源都會在您的使用者專案中執行。

在專案中執行建構程序即表示:

  • 您可以直接存取所有建構記錄。

  • Cloud Build 沒有預設的建構時間配額,但是有預設並行配額

  • 您可以查看目前的容器映像檔和先前部署的容器映像檔,這兩者都儲存在 Artifact Registry 中。

  • 專案會使用 Cloud Storage 儲存函式的原始碼目錄。請注意:

    • 如果您使用 Google Cloud CLI 建立函式,系統會建立上傳 bucket 來存放原始碼。這個上傳 bucket 名為 gcf-v2-uploads-PROJECT_NUMBER-REGION.cloudfunctions.appspot.com
    • 上傳程式碼後,函式程式碼會儲存在另一個來源 bucket 中:
      • 如果您使用預設加密機制,系統會將這個 bucket 命名為 gcf-v2-sources-PROJECT_NUMBER-REGION
      • 如果您使用 CMEK 保護資料,則系統會將 bucket 命名為 gcf-v2-sources-PROJECT_NUMBER-REGION-CMEK_KEY_HASH
    • 來源和上傳 bucket 皆無保留期限。

建構程序的特性

建構程序具有下列特性:

  • 您必須為專案啟用 Cloud Build API

    如要手動啟用 API,請按一下先前的連結,從下拉式選單中選取專案,然後按照提示啟用 UI。

  • 由於整個建構程序都是在專案環境中進行,因此專案會受到納入資源的價格影響:

    • 如要瞭解 Cloud Build 定價,請參閱「定價」頁面。這個程序會使用 Cloud Build 的預設執行個體大小,因為這些執行個體已預先暖機,因此會更快可供使用。Cloud Build 提供免費方案,詳情請參閱定價說明文件。

    • 如要瞭解 Cloud Storage 定價,請參閱「定價」頁面。 Cloud Storage 提供免費方案,詳情請參閱定價說明文件。

    • 如要瞭解 Artifact Registry 定價,請參閱「定價」頁面。

  • 由於建構程序會產生費用,因此專案必須附加 Cloud Billing 帳戶

查看建構映像檔記錄

在使用者專案中執行建構映像檔程序的主要優點是可以存取建構記錄。您可以使用 gcloud CLI 或 Google Cloud 控制台存取記錄,這些記錄可透過 Cloud Logging 取得。

gcloud

  1. 使用 gcloud functions deploy 指令部署函式。

  2. 記錄的網址會顯示在終端機視窗的回覆中,例如:

    Deploying function (may take a while - up to 2 minutes)...⠹
    **For Cloud Build Stackdriver Logs**, visit:
    https://console.cloud.google.com/logs/viewer?project=&advancedFilter=resource.type%
    3Dbuild%0Aresource.labels.build_id%3D38d5b662-2315-45dd-8aa2-
    380d50d4f5e8%0AlogName%3Dprojects%2F%
    2Flogs%2Fcloudbuild
    Deploying function (may take a while - up to 2 minutes)...done.

Google Cloud 控制台

按照下列步驟操作,即可在 Cloud Run 頁面查看函式記錄:

  1. 前往 Cloud Run

  2. 在顯示的清單中,點按所選函式。

  3. 點按「LOGS」(記錄) 分頁標籤,取得此函式所有修訂版本的要求和容器記錄。您可以依記錄的嚴重性等級進行篩選。

映像檔登錄

Artifact Registry 用於儲存從函式原始碼建構的映像檔。映像檔會儲存在名為 REGION-docker.pkg.dev/PROJECT_ID/gcf-artifacts 的存放區中,該存放區與建立的函式屬於相同專案。

如要指定自行管理的 Artifact Registry 存放區,請執行下列指令:

gcloud functions deploy FUNCTION_NAME \
   --docker-repository=REPOSITORY \
   [FLAGS...]

修改下列項目的值:

  • FUNCTION_NAME:函式的名稱。
  • REPOSITORY:Artifact Registry 存放區的完整名稱,格式如下: projects/PROJECT_NAME/locations/LOCATION/repositories/REPOSITORY

指定位於不同專案或區域的 Artifact Registry 存放區時,可能需要考量其他設定:

IAM 設定:

  • IAM 設定:請確認建構服務帳戶已獲得授權,可讀取及寫入 REPOSITORY
  • 網路設定:請確認目標 REPOSITORY 可從目前的專案設定連線。
  • VPC Service Controls 設定:請確認建構服務帳戶可以連線至 VPC-SC perimeter 內的目標 REPOSITORY
  • 資料落地限制條件:在函式所處區域以外的區域指定 REPOSITORY,會導致資料跨區域傳輸。

使用私人集區保護建構作業

為了讓函式使用依附元件 (例如 npm 套件),Cloud Build 預設會在建構程序中提供無限制的網際網路存取權。如果您已設定 VPC Service Controls (VPC SC) perimeter,並想限制建構作業只能存取儲存在 perimeter 中的依附元件,可以使用 Cloud Build 私人 worker 集區功能。

一般情況下,請按照下列步驟設定私人集區:

  1. 建立私人 worker 集區。詳情請參閱「建立及管理私人集區」一文。
  2. 設定 VPC Service Controls perimeter。詳情請參閱「使用 VPC Service Controls」一文。

  3. 如果您的私人 worker 集區與函式位於不同專案,您需要將 cloudbuild.workerPoolUser 角色授予 Cloud Functions 服務代理服務帳戶 (service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com),Cloud Build 服務才能存取 worker 集區。

    gcloud projects add-iam-policy-binding PRIVATE_POOL_PROJECT_ID \
        --member serviceAccount:service-FUNCTION_PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com
        --role roles/cloudbuild.workerPoolUser

    FUNCTION_PROJECT_NUMBER 替換為執行函式的專案「編號」,並將 PRIVATE_POOL_PROJECT_ID 替換為 worker 集區所在的專案「ID」。詳情請參閱「在私人集區中執行建構作業」一文。

  4. 使用私人集區部署函式進行建構:

    gcloud functions deploy FUNCTION_NAME \
       --runtime RUNTIME \
       --build-worker-pool PRIVATE_POOL_NAME
       [FLAGS...]

    FUNCTION_NAME 替換為函式名稱,RUNTIME 替換為您使用的執行階段,PRIVATE_POOL_NAME 則替換為集區名稱。

如要停止使用指定私人集區,改用預設的 Cloud Build 集區,請在重新部署時使用 --clear-build-worker-pool 旗標。

gcloud functions deploy FUNCTION_NAME \
   --runtime RUNTIME \
   --clear-build-worker-pool
   [FLAGS...]

FUNCTION_NAME 替換為函式名稱,並將 RUNTIME 替換為您使用的執行階段。

使用自訂服務帳戶保護建構作業

函式的原始碼會傳送至 Cloud Build,進行容器化。容器化函式會儲存在 Artifact Registry 中,並以服務的形式部署至 Cloud Run。建構及部署 Cloud Run 函式時,Cloud Run functions 會運用 Cloud Build。根據預設,Cloud Run functions 會在執行建構作業時,使用預設的 Cloud Build 服務帳戶做為主體。Cloud Build 自 2024 年 7 月起,變更了新專案中服務帳戶的預設使用方式。這項異動會導致新專案首次部署函式時,可能使用權限不足的預設 Cloud Build 服務帳戶來建構函式。

如果是 2024 年 7 月前建立的 Google Cloud 專案,Cloud Build 會使用舊版 Cloud Build 服務帳戶。這個服務帳戶旨在協助使用者執行各種用途,但對專案需求而言,權限可能過於寬鬆。如要將現有專案從這個服務帳戶移出,可以採取下列步驟,進一步保護函式建構環境:

禁止使用舊版 Cloud Build 服務帳戶進行建構作業

您可以檢查函式建構作業的詳細資料,確認專案是否使用舊版 Cloud Build 服務帳戶。預設建構服務帳戶的格式如下:

PROJECT_NUMBER@cloudbuild.gserviceaccount.com

您可以將組織政策限制條件 cloudbuild.useBuildServiceAccount 設為 Not Enforced,強制停用這個服務帳戶,也可以移除所有角色授權,限制服務帳戶存取 Google Cloud資源。

禁止使用預設的運算服務帳戶進行建構作業

預設的運算服務帳戶格式為 PROJECT_NUMBER-compute@developer.gserviceaccount.com。如要停用這項功能,請將組織政策 cloudbuild.useComputeServiceAccount 設為 Not Enforced,這樣系統就不會預設使用這項功能。 或者,您也可以停用這個服務帳戶,防止系統使用該帳戶存取 Google Cloud 資源。

提供用於建構函式的服務帳戶

在函式設定中,您可以在部署函式時指定建構服務帳戶。如果禁止使用舊版 Cloud Build 服務帳戶和預設運算服務帳戶進行建構作業,您必須指定建構服務帳戶才能部署函式,如本節所述。

如果您受到這篇文章所述異動的影響,可以採取下列任一做法:

  • 參閱 Cloud Build 指南,瞭解預設服務帳戶異動,並選擇不套用這些異動

  • 將 Cloud Build 帳戶角色 (roles/cloudbuild.builds.builder) 新增至預設的 Compute Engine 服務帳戶。

  • 為函式部署作業建立自訂 Cloud Build 服務帳戶。

如果您遇到下列情況,就可能需要提供其他服務帳戶,供 Cloud Build 建構函式時使用:

  • 您希望進一步控管要新增至 VPC-SC perimeter 的服務帳戶。

  • 您希望 Cloud Build 使用與預設服務帳戶不同的權限執行作業,而不必個別撤銷每項權限。

  • 您想為函式設定精細的 Cloud Build 權限,而不是共用依據其他用途最佳化的 Cloud Build 服務帳戶。

  • 貴組織已停用預設服務帳戶。

以下各節說明如何為函式部署作業建立自訂 Cloud Build 服務帳戶。

建立服務帳戶

按照「建立服務帳戶」一文中的說明,建立新的服務帳戶。

授予權限

您使用的服務帳戶必須具備下列角色:

  • roles/logging.logWriter:將建構記錄儲存在 Cloud Logging 時需要這個角色。
  • roles/artifactregistry.writer:將建構映像檔儲存至 Artifact Registry 時需要這個角色。如要使用預設行為,服務帳戶必須有權存取名為「gcf-artifacts」和「cloud-run-source-deploy」的存放區。您可以在存放區的 IAM 政策中設定存放區的存取權,也可以透過 dockerRepository 欄位提供自己的構件存放區。
  • roles/storage.objectViewer:從 Cloud Storage bucket 擷取函式原始碼,以及在 Container Registry 中儲存建構映像檔時,需要這個角色。如要使用預設行為,服務帳戶必須有權存取名為「run-sources-*」、「gcf-v2-sources-*」和「gcf-v2-uploads-*」的 bucket。如要達成這個要求,請在角色授權中新增 IAM 條件,例如 (resource.type == "storage.googleapis.com/Object" && (resource.name.startsWith("projects/_/buckets/gcf-v2-sources-") || resource.name.startsWith("projects/_/buckets/gcf-v2-uploads-") || resource.name.startsWith("projects/_/buckets/run-sources-")))

使用 Google Cloud CLI 授予下列角色權限,或使用 Google Cloud 控制台

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
    --role=roles/logging.logWriter

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/artifactregistry.writer

gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SA_EMAIL \
--role=roles/storage.objectViewer

修改下列項目的值:

VPC Service Controls 注意事項

如果您有 VPC Service Controls perimeter,可同時保護專案和 Cloud Run Functions API,且您使用 Compute Engine 預設服務帳戶做為 Cloud Run Functions 的 Cloud Build 服務帳戶角色,則必須建立下列輸入規則:

  • 允許 Compute Engine 預設服務帳戶對 Cloud Storage 和 Cloud Logging API 的所有方法進行輸入。
  • 允許服務帳戶 service-[PROJECT_NUMBER]@gcf-admin-robot.iam.gserviceaccount.com 對 Cloud Storage 和 Cloud Logging API 的所有方法進行輸入。

使用自訂服務帳戶部署函式

如要在部署函式時傳入使用者建立的服務帳戶,供 Cloud Build 使用,請執行下列 gcloud 指令:

  • --build-service-account 旗標會指定 IAM 服務帳戶,並在建構步驟使用該帳戶的憑證。如未提供自訂服務帳戶,函式會使用專案的 Cloud Build 預設服務帳戶。
  • 您可以選擇使用私人集區,如要這麼做,請用 --build-worker-pool 旗標指定。

gcloud functions deploy FUNCTION_NAME \
   --gen2 \
   --region=REGION \
   --project=PROJECT_ID \
   --runtime=RUNTIME \
   --entry-point=CODE_ENTRYPOINT \
   --build-service-account=projects/PROJECT_ID/serviceAccounts/SA_EMAIL \
   --memory=256Mi \
   --trigger-http \
   --source=.

修改下列項目的值:

授予 Cloud Build 服務帳戶 VPC Service Controls perimeter 存取權

Cloud Run functions 會使用 Cloud Build 將原始碼建構為可執行的容器。如要搭配 VPC Service Controls 使用 Cloud Run functions,請將 Cloud Build 服務帳戶設為預設或自訂,將 service perimeter 存取權授予該帳戶。

找出服務帳戶名稱

如果您使用預設的 Cloud Build 服務帳戶,可以按照下列步驟找出該帳戶的名稱:

  1. 在 Google Cloud 控制台中前往「IAM」頁面,找出 Cloud Build 服務帳戶。

    開啟 IAM

  2. 確認專案下拉式選單中顯示的專案正確無誤。

  3. 搜尋 cloudbuild.gserviceaccount.com。表單 PROJECT_NUMBER@cloudbuild.gserviceaccount.com 中顯示的電子郵件地址即為服務帳戶名稱。

如果您使用自訂 Cloud Build 服務帳戶,請改用該名稱。

授予服務帳戶 service perimeter 存取權

取得服務帳戶名稱後,請按照這篇文章的指示,為服務帳戶建立存取層級。接著,按照「為現有 perimeter 新增存取層級」一節的說明,在 service perimeter 中新增存取層級。