排解 Cloud Run functions (第 1 代) 問題

本文說明如何排解使用 Cloud Run functions (第 1 代) 時出現的錯誤訊息,並解決相關問題。

部署作業

本節列出部署時可能會遇到的問題,並提供相應的修正建議。部署期間可能遇到的許多問題,都與角色和權限或設定錯誤有關。

部署事件導向函式時,部署作業服務帳戶缺少 Pub/Sub 權限

Cloud Functions 服務會使用 Cloud Functions 服務代理服務帳戶 (service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) 執行管理動作。根據預設,系統會將 Cloud Functions cloudfunctions.serviceAgent 角色指派給這個帳戶。如要部署事件導向函式,Cloud Functions 服務必須存取 Pub/Sub,才能設定主題和訂閱項目。如果指派給服務帳戶的角色有所變更,但未更新適當權限,Cloud Functions 服務就無法存取 Pub/Sub,部署作業也會失敗。

錯誤訊息

控制台

Failed to configure trigger PubSub projects/PROJECT_ID/topics/FUNCTION_NAME

gcloud

ERROR: (gcloud.functions.deploy) OperationError: code=13, message=Failed to configure trigger PubSub projects/PROJECT_ID/topics/FUNCTION_NAME

解決方法

您可以將服務帳戶重設為預設的 cloudfunctions.serviceAgent 角色。

預設執行階段服務帳戶不存在

如未指定使用者自行管理的服務帳戶,Cloud Run functions (第 1 代) 預設會使用 App Engine 服務帳戶。如果刪除預設帳戶,但未指定使用者自行管理的服務帳戶,部署作業就會失敗。

錯誤訊息

gcloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[400], code=[Ok], message=[Default service account 'test-project-356312@appspot.gserviceaccount.com' doesn't exist. Please recreate this account or specify a different account. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation.]

解決方法

如要解決這個問題,請採用下列任一解決方法:

部署函式時,使用者缺少執行階段服務帳戶的權限

每個函式都與一個服務帳戶相關聯,在函式存取其他資源時,該帳戶則用於識別身分。這個執行階段服務帳戶可以是預設服務帳戶,也可以是使用者自行管理的服務帳戶。如要讓 Cloud Functions 使用執行階段服務帳戶,部署者必須擁有該服務帳戶的 iam.serviceAccounts.actAs 權限。建立非預設執行階段服務帳戶的使用者會自動獲得這項權限,但其他部署者必須由具備正確權限的使用者授予這項權限。

如果使用者已獲派專案檢視者、Cloud Functions 開發人員或 Cloud Functions 管理員角色,則必須額外取得執行階段服務帳戶的 iam.serviceAccounts.actAs 權限。

錯誤訊息

控制台

You must have the iam.serviceAccounts.actAs permission on the selected service account. To obtain this permission, you can grant a role that includes it like the Service Account User role, on the project.

gcloud

預設服務帳戶發生下列錯誤:

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Caller USER is missing permission 'iam.serviceaccounts.actAs' on service account PROJECT_ID@appspot.gserviceaccount.com. Grant the role 'roles/iam.serviceAccountUser' to the caller on the service account PROJECT_ID@appspot.gserviceaccount.com. You can do that by running 'gcloud iam service-accounts add-iam-policy-binding
PROJECT_ID@appspot.gserviceaccount.com --member MEMBER --role roles/iam.serviceAccountUser' where MEMBER has a prefix like 'user:' or 'serviceAccount:'.

非預設服務帳戶發生下列錯誤:

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Ok], message=[Caller USER is missing permission 'iam.serviceaccounts.actAs' on service account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com. Grant the role 'roles/iam.serviceAccountUser' to the caller on the service account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com. You can do that by running 'gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com --member MEMBER --role roles/iam.serviceAccountUser' where MEMBER has a prefix like 'user:' or 'serviceAccount:'.

解決方法

在預設或使用者自行管理的服務帳戶中,將 roles/iam.serviceAccountUser 角色指派給使用者。這個角色包含 iam.serviceAccounts.actAs 權限。

部署函式時,Cloud Run functions 服務代理服務帳戶缺少專案 bucket 權限

Cloud Run functions 只能由同一個 Google Cloud 專案中的 Cloud Storage bucket 事件觸發。此外,Cloud Functions 服務代理服務帳戶 (service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com) 需具備專案的 cloudfunctions.serviceAgent 角色。

錯誤訊息

控制台

Deployment failure: Insufficient permissions to (re)configure a trigger
(permission denied for bucket BUCKET_ID). Please, give owner permissions
to the editor role of the bucket and try again.

gcloud

ERROR: (gcloud.functions.deploy) OperationError: code=7, message=Insufficient
permissions to (re)configure a trigger (permission denied for bucket BUCKET_ID).
Please, give owner permissions to the editor role of the bucket and try again.

解決方法

如要解決這項錯誤,請將服務代理服務帳戶重設為預設角色。

具備「專案編輯者」角色的使用者無法將函式設為公開

專案編輯者角色擁有廣泛權限,可以管理專案中的資源,但不會自動授予公開 Cloud Run functions 的權限。您必須將 cloudfunctions.functions.setIamPolicy 權限授予部署函式的使用者或服務。

錯誤訊息

gcloud

 ERROR: (gcloud.functions.add-iam-policy-binding) ResponseError: status=[403], code=[Forbidden], message=[Permission 'cloudfunctions.functions.setIamPolicy' denied on resource 'projects/PROJECT_ID/locations/LOCATION/functions/FUNCTION_NAME (or resource may not exist).]

解決方法

如要解決這項錯誤,請採用下列任一解決方法:

使用「資源位置限制」組織政策時,函式部署作業失敗

如果貴組織採用資源位置限制政策,系統會禁止在該政策限制的區域部署函式。在 Google Cloud 控制台中部署函式時,受限制的區域不會顯示在區域下拉式選單中。

錯誤訊息

gcloud

  ERROR: (gcloud.functions.deploy) ResponseError: status=[400], code=[Ok], message=[The request has violated one or more Org Policies. Please refer to the respective violations for more information. violations {
    type: "constraints/gcp.resourceLocations"
    subject: "orgpolicy:projects/PROJECT_ID"
    description: "Constraint constraints/gcp.resourceLocations violated for projects/PROJECT_ID attempting GenerateUploadUrlActionV1 with location set to RESTRICTED_LOCATION. See https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints for more information."
  }

解決方法

請從資源位置限制的 allowed_valuesdenied_values 清單新增或移除位置,以順利完成部署作業。

執行函式的全域範圍時,函式部署作業失敗

這個錯誤表示程式碼有問題。部署管道已完成函式部署作業,但在最後一個步驟 (將健康狀態檢查傳送至函式) 失敗。這項健康狀態檢查旨在執行函式的全域範圍,可能會擲回例外狀況、當機或逾時情形。通常會在全域範圍載入程式庫並初始化用戶端。

錯誤訊息

控制台

Deployment failure: Function failed on loading user code. This is likely due to a bug in the user code.

gcloud

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function
failed on loading user code. This is likely due to a bug in the user code.

在 Cloud Logging 記錄中:

  "Function failed on loading user code. This is likely due to a bug in the user code."

解決方法

如要解決這個問題,請採用下列任一解決方法:

  • 如要進一步瞭解錯誤訊息,請查看函式的建構記錄

  • 如果不清楚函式無法執行全域範圍的原因,請考慮暫時將程式碼移至要求叫用中,並對全域變數使用延遲初始化。您可以在用戶端程式庫周圍新增額外的記錄陳述式,這些程式庫可能會在建立例項時逾時 (尤其是呼叫其他服務時)、當機或一併擲回例外狀況。

  • 延長函式逾時時間。

  • 原始碼必須包含已在部署作業中透過控制台gcloud 正確指定的進入點函式。

具備「檢視者」角色的使用者無法部署函式

具備「專案檢視者」或「Cloud Functions 檢視者」角色的使用者,擁有函式和函式詳細資料的「唯讀」存取權,但無法部署新函式。Google Cloud 控制台中的「建立函式」功能顯示為灰色,並指出下列錯誤:

錯誤訊息

gcloud

ERROR: (gcloud.functions.deploy) PERMISSION_DENIED: Permission
'cloudfunctions.functions.sourceCodeSet' denied on resource
'projects/PROJECT_ID/locations/LOCATION` (or resource may not exist)

解決方法

Cloud Functions 開發人員角色指派給使用者。

建構服務帳戶缺少權限

錯誤訊息

在函式部署錯誤或建構記錄中,可能會顯示下列其中一項錯誤:

The service account running this build does not have permission to write logs.
To fix this, grant the Logs Writer (roles/logging.logWriter) role to the service
account.
Step #0 - "fetch": failed to Fetch: failed to download archive gs://gcf-sources-PROJECT_NUMBER-LOCATION/FUNCTION_NAME/version-VERSION_NUMBER/function-source.zip: Access to bucket gcf-sources-PROJECT_NUMBER-LOCATION denied. You must grant Storage Object Viewer permission to PROJECT_NUMBER-compute@developer.gserviceaccount.com.
Step #2 - "build": ERROR: failed to create image cache: accessing cache image "LOCATION-docker.pkg.dev/PROJECT/gcf-artifacts/FUNCTION_NAME/cache:latest": connect to repo store "LOCATION-docker.pkg.dev/PROJECT/gcf-artifacts/FUNCTION_NAME/cache:latest": GET https://LOCATION-docker.pkg.dev/v2/token?scope=repository%3APROJECT%2Fgcf-artifacts%2FFUNCTION_NAME%2Fcache%3Apull&service=: DENIED: Permission "artifactregistry.repositories.downloadArtifacts" denied on resource "projects/PROJECT/locations/LOCATION/repositories/gcf-artifacts" (or it may not exist)
Could not build the function due to a missing permission on the build service account. If  you didn't revoke that permission explicitly, this could be caused by a change in the organization policies.

解決方法

建構服務帳戶需要來源 bucket 的讀取權限,以及構件部署存放區的讀取和寫入權限。這項錯誤可能是因為 Cloud Build 使用服務帳戶時的預設行為異動所導致,詳細資訊請參閱「Cloud Build 服務帳戶異動」。

如要解決這個問題,請採用下列任一解決方法:

建構服務帳戶已停用

錯誤訊息

Could not build the function due to disabled service account used by Cloud Build. Please make sure that the service account is active.

解決方法

必須啟用建構服務帳戶,才能部署函式。這項錯誤可能是因為 Cloud Build 使用服務帳戶時的預設行為異動所導致,詳細資訊請參閱「Cloud Build 服務帳戶異動」。

如要解決這個問題,請採用下列任一解決方法:

提供

本節列出可能會遇到的提供問題,並附上每項問題的修正建議。

函式需要驗證,因此發生權限提供錯誤

如果 HTTP 函式未啟用「允許未經驗證的叫用」,則只有具備適當權限的使用者和服務帳戶才能存取。

在瀏覽器中前往 Cloud Run functions 網址時,不會自動加入驗證標頭。

錯誤訊息

HTTP 錯誤回應代碼:403 Forbidden

HTTP 錯誤回應內文:

Error: Forbidden Your client does not have permission
to get URL /FUNCTION_NAME from this server.

解決方法

如要解決這項錯誤,請採用下列任一解決方法:

因設定 allow internal traffic only 而發生權限提供錯誤

輸入設定會限制 HTTP 函式是否可由 Google Cloud 專案或 VPC Service Controls service perimeter 以外的資源叫用。在指定輸入網路的「僅允許內部流量」設定時,出現這個錯誤訊息表示,系統只允許來自同一個專案或 VPC Service Controls perimeter 的虛擬私有雲網路要求。

錯誤訊息

HTTP 錯誤回應代碼:404 NOT FOUND

HTTP 錯誤回應內文:

404 Page not found

解決方法

如要解決這項錯誤,請採用下列任一解決方法:

  • 確認要求來自 Google Cloud 專案或 VPC Service Controls service perimeter。

  • 將函式的輸入設定變更為允許所有流量

  • Cloud Run functions 原始碼可能因為不正確的函式網址、HTTP 方法或邏輯錯誤,而導致 404 錯誤。

函式叫用缺少有效的驗證憑證

設有限制存取權的函式,必須使用 ID 權杖。如果使用存取權杖更新權杖,則無法叫用函式。

錯誤訊息

HTTP 錯誤回應代碼:401 Unauthorized

HTTP 錯誤回應內文:

Your client does not have permission to the requested URL </FUNCTION_NAME>

解決方法

如要解決這項錯誤,請採用下列任一解決方法:

  • 確認要求包含 Authorization: Bearer ID_TOKEN 標頭,且權杖是 ID 權杖,而非存取或更新權杖。如果您使用服務帳戶的私密金鑰手動產生這個權杖,則必須將自行簽署的 JWT 權杖換成 Google 簽署的 ID 權杖。詳情請參閱「叫用作業驗證」。

  • 使用要求標頭中的驗證憑證叫用 HTTP 函式。舉例來說,您可以使用 gcloud 取得 ID 權杖,如下所示:

    curl  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
      https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME

    詳情請參閱「叫用作業驗證」。

函式在執行作業中途停止,或在程式碼執行完畢後繼續執行

部分 Cloud Run functions 執行階段可讓使用者執行非同步任務。如果函式建立這類任務,也必須明確等待這些任務完成。否則函式可能會在錯誤的時間停止執行。

錯誤行為

函式出現下列其中一種行為:

  • 函式在非同步任務仍在執行時就已終止,但指定逾時時間尚未結束。
  • 函式不會在這些任務完成後停止執行,而是會持續執行到逾時時間結束為止。

解決方法

如果函式提早終止,請先確保函式的所有非同步任務皆已完成,再執行下列任一動作:

  • 傳回值
  • 解析或拒絕傳回的 Promise 物件 (僅限 Node.js 函式)
  • 擲回未偵測到的例外狀況和錯誤
  • 傳送 HTTP 回應
  • 呼叫回呼函式

如果函式在完成非同步任務後無法終止,請確認函式是否在任務完成後正確發出 Cloud Run functions 信號。特別是,請務必在函式完成非同步任務後,立即執行上述清單列出的任一作業。

存取受 VPC Service Controls 保護的資源時,發生執行階段錯誤

根據預設,Cloud Run functions 會使用公開 IP 位址,向其他服務發出傳出要求。如果函式不在 VPC Service Controls perimeter 內,嘗試存取受 VPC Service Controls 保護的 Google Cloud 服務時,可能會因 service perimeter 拒絕而收到 HTTP 403 回應。

錯誤訊息

在「已稽核的資源」記錄中,項目如下所示:

"protoPayload": {
  "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
  "status": {
    "code": 7,
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "VPC_SERVICE_CONTROLS",
  ...
  "authenticationInfo": {
    "principalEmail": "CLOUD_FUNCTION_RUNTIME_SERVICE_ACCOUNT",
  ...
  "metadata": {
    "violationReason": "NO_MATCHING_ACCESS_LEVEL",
    "securityPolicyInfo": {
      "organizationId": "ORGANIZATION_ID",
      "servicePerimeterName": "accessPolicies/NUMBER/servicePerimeters/SERVICE_PERIMETER_NAME"
  ...

解決方法

如要解決這項錯誤,請採用下列任一解決方法:

擴充性

本節列出擴充性問題,並提供相應的修正建議。

與待處理佇列要求中止有關的 Cloud Logging 錯誤

下列情況可能導致擴充失敗。

  • 流量突然大幅增加。
  • 冷啟動時間過長。
  • 要求處理時間過長。
  • 函式錯誤率偏高。
  • 達到執行個體數量上限
  • 歸因於 Cloud Run functions 服務的暫時性因素。

在上述任一情況下,Cloud Run functions 可能不會快速擴充,以致無法管理流量。

錯誤訊息

 The request was aborted because there was no available instance.

Cloud Run functions 具有下列嚴重性等級:

* `severity=WARNING` ( Response code: 429 ) Cloud Run functions cannot scale due
  to the [`max-instances`](/functions/docs/configuring/max-instances) limit you set
  during configuration.
* `severity=ERROR` ( Response code: 500 ) Cloud Run functions intrinsically
  cannot manage the rate of traffic.

解決方法

  • 如果是以 HTTP 觸發條件為基礎的函式,請針對不得捨棄的要求,實作指數輪詢和重試機制。如果是從 Workflows 觸發 Cloud Run functions,則可使用 try/retry 語法達成此目的。
  • 對於背景或事件導向函式,Cloud Run functions 支援至少一次傳送。即使未明確啟用重試功能,系統也會自動重新傳送事件,並重試函式執行作業。詳情請參閱「啟用事件導向函式重試功能」。
  • 如果問題的根本原因是一段時間內暫時性的錯誤增加,且完全歸因於 Cloud Run functions,或是您有問題需要協助,請與 Cloud Customer Care 團隊聯絡。

記錄

下一節將說明記錄相關問題及修正方法。

記錄項目沒有或有不正確的記錄嚴重性等級

Cloud Run functions 預設會包含執行階段記錄。寫入 stdoutstderr 的記錄會自動顯示在Google Cloud 控制台中。但根據預設,這些記錄項目只會包含字串訊息。

解決方法

如要納入記錄嚴重性,請務必傳送結構化記錄項目。

當機時,以不同方式處理或記錄例外狀況

建議自訂管理及記錄當機資訊的方式。

解決方法

將函式包裝在 try 區塊中,即可自訂例外狀況的處理方式和記錄堆疊追蹤。

在採用 retry on failure 設定的事件導向函式中加入 try 區塊,可能會導致非預期的副作用。重試失敗的事件本身也可能會失敗。

示例

import logging
import traceback
def try_catch_log(wrapped_func):
  def wrapper(*args, **kwargs):
    try:
      response = wrapped_func(*args, **kwargs)
    except Exception:
      # Replace new lines with spaces so as to prevent several entries which
      # would trigger several errors.
      error_message = traceback.format_exc().replace('\n', '  ')
      logging.error(error_message)
      return 'Error';
    return response;
  return wrapper;

#Example hello world function

@try_catch_log
def python_hello_world(request):
  request_args = request.args

  if request_args and 'name' in request_args:
    1 + 's'
  return 'Hello World!'

Node.js 10 以上版本、Python 3.8、Go 1.13 和 Java 11 的記錄檔過大

在這些執行階段中,一般記錄項目的大小上限為 105 KiB。

解決方法

請傳送小於此限制的記錄項目。

Cloud Run functions 傳回錯誤,但缺少記錄

Cloud Run functions 會將 Cloud Run 函式記錄串流至預設 bucket。建立專案時,Cloud Run functions 會建立並啟用預設 bucket。如已停用預設 bucket,或 Cloud Run 函式記錄已納入排除篩選器,Logs Explorer 就不會顯示這些記錄。

解決方法

啟用預設記錄,並確認未設定任何排除篩選器。

Logs Explorer 未顯示 Cloud Run functions 記錄

部分 Cloud Logging 用戶端程式庫會採用非同步程序寫入記錄項目。如果函式停止運作或異常終止,部分記錄項目可能尚未寫入,稍後才會顯示。此外,部分記錄也可能遺失,無法在 Logs Explorer 顯示。

解決方法

在函式結束前透過用戶端程式庫介面清除緩衝的記錄項目,或使用程式庫同步寫入記錄項目。您也可以直接將記錄同步寫入 stdoutstderr

使用記錄路由器接收器時,Cloud Run functions 記錄不會顯示

記錄路由器接收器會將記錄項目轉送至不同目的地。

控制台記錄路由器的螢幕截圖,其中醒目顯示「查看接收器詳細資料」

設定中包含「排除」篩選器,定義了可捨棄的項目。

螢幕截圖:控制台記錄路由器接收器的詳細資料對話方塊,顯示排除篩選器

解決方法

移除 resource.type="cloud_functions" 的排除篩選器組合。

資料庫連線

許多資料庫錯誤都與超出連線限制或逾時有關。如果記錄中顯示 Cloud SQL 警告訊息 (例如 Context deadline exceeded),則可能需要調整連線設定。詳情請參閱「Cloud SQL 最佳做法」。

網路

本節列出網路問題,並提供相應的修正建議。

網路連線

即使調整輸出設定後,Cloud Run 函式的所有傳出要求仍失敗,還是可以執行 Connectivity Tests,找出任何潛在的網路連線問題。詳情請參閱「建立及執行 Connectivity Tests」。

無伺服器 VPC 存取連接器未就緒或不存在

如果無伺服器 VPC 存取連接器執行失敗,可能是未依要求使用 /28 連接器專用子網路遮罩。

錯誤訊息

VPC connector projects/xxxxx/locations/REGION/connectors/xxxx
is not ready yet or does not exist.

如果 Google API 服務代理服務帳戶 PROJECT_NUMBER@cloudservices.gserviceaccount.com 缺少權限,導致連接器狀態不佳,部署 Cloud Run functions 時就會發生下列錯誤:

錯誤訊息

Failed to prepare VPC connector. Please try again later.

解決方法

列出子網路,檢查連接器是否使用 /28 子網路遮罩。如果連接器未使用 /28 子網路遮罩,請重新建立或建立新的連接器

如要解決這個問題,請採用下列任一解決方法:

  • 如果重新建立連接器,則不需要重新部署其他函式。重新建立連接器時,網路可能會中斷。

  • 如果建立新的替代連接器,請重新部署函式以使用新連接器,然後將原始連接器刪除。這個方法可避免網路中斷。

  • 確認 Cloud Run functions 和相關聯的連接器部署在相同區域。

  • Shared VPC 設定:

    • 請確認 VPC Connector 用於在專案中佈建資源的服務帳戶 SERVICE_PROJECT_NUMBER@cloudservices.gserviceaccount.comservice-SERVICE_PROJECT_NUMBER@gcp-sa-vpcaccess.iam.gserviceaccount.com 沒有缺少權限。如果連接器位於服務專案中,則上述服務帳戶須在 Shared VPC 設定的主專案中具備 roles/compute.networkUser 角色。否則就必須具備 roles/compute.networkAdmin 角色。

    • 如果連接器是在主專案中建立,請確保主專案的 Cloud Run functions Service Agent獲得 Serverless VPC Access User 角色。

    • 如果連接器狀態顯示 Connector is in a bad state, manual deletion recommended 錯誤,且 Google API 服務代理缺少在連接器專案中佈建運算資源的必要權限,請將 roles/compute.admin 授予 PROJECT_NUMBER@cloudservices.gserviceaccount.com 服務帳戶。在某些情況下,更新權限後可能需要重新建立連結器。

系統會封鎖使用 TCP 通訊埠 25 傳輸至外部目的地 IP 位址的 SMTP 流量

為提高安全性,透過 Cloud Run functions 傳送電子郵件時, Google Cloud 會封鎖與 TCP 目標通訊埠 25 的連線。

解決方法

如要解除封鎖這些連線,請選擇採用下列任一選項:

其他

本節說明不屬於上述類別的額外問題,並提供相應的解決方法。

Cloud 稽核記錄中 google.storage.buckets.testIamPermissions 方法的 VPC Service Controls 錯誤

在Google Cloud 控制台中開啟「函式詳細資料」頁面時,Cloud Run functions 會檢查您是否有權修改容器映像檔的儲存空間存放區,並公開存取該存放區。為進行驗證,Cloud Run functions 會使用 google.storage.buckets.testIamPermissions 方法將要求傳送至 Container Registry bucket,格式如下:[REGION].artifacts.[PROJECT_ID].appspot.com。這兩項檢查的唯一差異在於,一項檢查需要透過驗證機制執行,以確認使用者是否有權修改 bucket;另一項檢查則不需要驗證,即可確認 bucket 是否能公開存取。

如果 VPC Service Controls perimeter 限制 storage.googleapis.com API, Google Cloud 控制台會在 Cloud 稽核記錄的 google.storage.buckets.testIamPermissions 方法中顯示錯誤。

錯誤訊息

如果在沒有驗證資訊的情況下進行公開存取權檢查,VPC SC 拒絕政策稽核記錄會顯示類似以下項目:

"protoPayload": {
  "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
  "status": {
    "code": 7,
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "VPC_SERVICE_CONTROLS",
  ...
  "authenticationInfo": {},
  "requestMetadata": {
    "callerIp": "END_USER_IP"
  },
  "serviceName": "storage.googleapis.com",
  "methodName": "google.storage.buckets.testIamPermissions",
  "resourceName": "projects/PROJECT_NUMBER",
  "metadata": {
    "ingressViolations": [
      {
        "servicePerimeter": "accessPolicies/ACCESS_POLICY_ID/servicePerimeters/VPC_SC_PERIMETER_NAME",
        "targetResource": "projects/PROJECT_NUMBER"
      }
    ],
    "resourceNames": [
      "projects/_/buckets/REGION.artifacts.PROJECT_ID.appspot.com"
    ],
    "securityPolicyInfo": {
      "servicePerimeterName": "accessPolicies/ACCESS_POLICY_ID/servicePerimeters/VPC_SC_PERIMETER_NAME",
      "organizationId": "ORG_ID"
    },
    "violationReason": "NO_MATCHING_ACCESS_LEVEL",
  ...

如果在有驗證資訊的情況下進行公開存取權檢查,VPC SC 拒絕政策稽核記錄會顯示允許使用者修改 bucket 設定的項目,類似下列範例:

"protoPayload": {
  "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
  "status": {
    "code": 7,
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.PreconditionFailure",
        "violations": [
          {
            "type": "VPC_SERVICE_CONTROLS",
  ...
  "authenticationInfo": {
    "principalEmail": "END_USER_EMAIL"
  },
  "requestMetadata": {
    "callerIp": "END_USER_IP",
    "requestAttributes": {},
    "destinationAttributes": {}
  },
  "serviceName": "storage.googleapis.com",
  "methodName": "google.storage.buckets.testIamPermissions",
  "resourceName": "projects/PROJECT_NUMBER",
  "metadata": {
    "ingressViolations": [
      {
        "servicePerimeter": "accessPolicies/ACCESS_POLICY_ID/servicePerimeters/VPC_SC_PERIMETER_NAME",
        "targetResource": "projects/PROJECT_NUMBER"
      }
    ],
    "resourceNames": [
      "projects/_/buckets/REGION.artifacts.PROJECT_ID.appspot.com"
    ],
    "securityPolicyInfo": {
      "servicePerimeterName": "accessPolicies/ACCESS_POLICY_ID/servicePerimeters/VPC_SC_PERIMETER_NAME",
      "organizationId": "ORG_ID"
    },
    "violationReason": "NO_MATCHING_ACCESS_LEVEL",
  ...

解決方法

如果 Container Registry bucket 無法公開存取,請忽略 VPC Service Controls 錯誤。

此外,也可以新增 VPC Service Controls 輸入規則,允許使用 google.storage.buckets.testIamPermissions 方法,如下列範例所示:

ingress_from {
  sources {
    access_level: "*"
  }
  identity_type: ANY_IDENTITY
}
ingress_to {
  operations {
    service_name: "storage.googleapis.com"
    method_selectors {
      method: "google.storage.buckets.testIamPermissions"
    }
  }
  resources: "projects/PROJECT_NUMBER"
}

請盡可能透過使用者 IP 位址定義存取層級,進一步修正輸入規則。