如果架構使用多項服務,這些服務可能需要以非同步或同步方式互相通訊。其中許多服務可能不公開,因此需要憑證才能存取。
如要進行非同步通訊,可以使用下列 Google Cloud 服務:
- Cloud Tasks:適用於一對一非同步通訊
- Pub/Sub:用於一對多、一對一和多對一非同步通訊
- Cloud Scheduler:用於定期排定的非同步通訊
- Eventarc:用於事件型通訊
在上述所有情況下,所使用的服務會根據您設定的配置,管理與接收服務的互動。
但如果是「同步」通訊,服務會使用端點網址,透過 HTTP 直接呼叫其他服務。在這種情況下,您應確保每項服務只能向特定服務提出要求。舉例來說,如果您有 login 服務,則應該可以存取 user-profiles 服務,但無法存取 search 服務。
在這種情況下,Google 建議您使用 IAM 和服務身分,並根據各項服務的使用者自行管理服務帳戶,授予執行工作所需的最低權限。
此外,要求必須提供呼叫服務的身分證明。如要這麼做,請設定呼叫服務,在要求中加入 Google 簽署的 OpenID Connect ID 權杖。
設定服務帳戶
如要設定服務帳戶,請將呼叫服務的服務帳戶設為接收服務的主體,藉此設定接收服務接受來自呼叫服務的要求。接著,您會將 Cloud Run 叫用者 (roles/run.invoker) 角色授予該服務帳戶。如要執行這兩項工作,請按照適當分頁中的指示操作:
主控台使用者介面
前往 Google Cloud 控制台
選取接收的服務。
按一下右上角的 [Show Info Panel] (顯示資訊面板),顯示「Permissions」(權限) 分頁。
按一下「Add principal」(新增主體)。
輸入呼叫服務的身分。這通常是電子郵件地址,預設為
PROJECT_NUMBER-compute@developer.gserviceaccount.com。從「Select a role」(選取角色) 下拉式選單中選取「
Cloud Run Invoker」角色。按一下 [儲存]。
gcloud
使用 gcloud run services add-iam-policy-binding 指令:
gcloud run services add-iam-policy-binding RECEIVING_SERVICE \ --member='serviceAccount:CALLING_SERVICE_IDENTITY' \ --role='roles/run.invoker'
其中 RECEIVING_SERVICE 是接收服務的名稱,CALLING_SERVICE_IDENTITY 則是服務帳戶的電子郵件地址,預設為 PROJECT_NUMBER-compute@developer.gserviceaccount.com。
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
在 Terraform 設定中,將下列內容新增至google_cloud_run_v2_service 資源:將 us-docker.pkg.dev/cloudrun/container/hello 替換為容器映像檔的參照。
下列 Terraform 程式碼會將初始服務設為公開。
下列 Terraform 程式碼會建立第二個 Cloud Run 服務,並設為私人。
將 us-docker.pkg.dev/cloudrun/container/hello 替換為容器映像檔的參照。
下列 Terraform 程式碼會建立服務帳戶。
下列 Terraform 程式碼只會將叫用權限授予呼叫服務帳戶,讓第二項服務成為私人服務。
取得並設定 ID 權杖
將適當角色授予呼叫服務帳戶後,請按照下列步驟操作:
使用下列任一方法,擷取 Google 簽署的 ID 權杖。將目標對象宣告 (
aud) 設為接收服務的網址或設定的自訂目標對象。如果您未使用自訂目標對象,即使向特定流量標記提出要求,aud值也必須維持服務網址。在向接收服務發出的要求中,將上一步擷取的 ID 權杖新增至下列其中一個標頭:
Authorization: Bearer ID_TOKEN標頭。X-Serverless-Authorization: Bearer ID_TOKEN標頭。如果應用程式已使用Authorization標頭進行自訂授權,則可使用這個標頭。這會在將權杖傳遞至使用者容器之前移除簽章。
如要瞭解本頁未說明的其他 ID 權杖取得方式,請參閱「取得 ID 權杖的方法」。
使用驗證程式庫
取得及設定 ID 權杖程序的方法之一,是使用驗證程式庫。只要程式庫可以取得服務帳戶的驗證憑證,這段程式碼就能在任何環境中運作,包括 Google Cloud以外的環境。如要使用這個方法,請下載服務帳戶金鑰檔案,並將環境變數 GOOGLE_APPLICATION_CREDENTIALS 設為服務帳戶金鑰檔案的路徑。詳情請參閱「服務帳戶金鑰」。
這段程式碼不接受使用者帳戶的驗證憑證。
Node.js
Python
Go
Java
使用中繼資料伺服器
如果因故無法使用驗證程式庫,您可以在容器於 Cloud Run 執行時,從 Compute 中繼資料伺服器擷取 ID 權杖。請注意,這個方法不適用於 Google Cloud以外的環境,包括本機。
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=[AUDIENCE]" \
-H "Metadata-Flavor: Google"
其中 AUDIENCE 是您叫用的服務網址,或設定的自訂目標對象。
下表摘要說明中繼資料查詢要求的主要部分:
| 元件 | 說明 |
|---|---|
| 根網址 | 所有中繼資料值都定義為下列根網址下方的子路徑: http://metadata.google.internal/computeMetadata/v1 |
| 要求標頭 | 每項要求都必須包含下列標頭: Metadata-Flavor: Google 此標頭指示是在擷取中繼資料值的意圖之下傳送要求,而非隨意從不安全的來源傳送,並允許中繼資料伺服器傳回您要求的資料。如未提供這個標頭,中繼資料伺服器會拒絕要求。 |
如要瞭解使用這項服務對服務驗證技術的應用程式端對端逐步操作說明,請參閱保護 Cloud Run 服務教學課程。
從 Google Cloud外部使用 Workload Identity Federation
如果環境使用的識別資訊提供者支援Workload Identity Federation,您可以使用下列方法,從 Google Cloud外部安全地向 Cloud Run 服務進行驗證:
按照本頁「設定服務帳戶」一節的說明設定服務帳戶。
按照「設定 Workload Identity Federation」一文所述,為識別資訊提供者設定 Workload Identity Federation。
請按照「授予外部身分模擬服務帳戶的權限」一節的操作說明操作。
使用 REST API 取得短期權杖,但不要呼叫
generateAccessToken來取得存取權杖,而是呼叫generateIdToken來取得 ID 權杖。例如,使用 cURL:
ID_TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT:generateIdToken \ -H "Content-Type: text/json; charset=utf-8" \ -H "Authorization: Bearer $STS_TOKEN" \ -d @- <<EOF | jq -r .token { "audience": "SERVICE_URL" } EOF ) echo $ID_TOKEN
其中
SERVICE_ACCOUNT是 workload identity pool 設定存取的服務帳戶電子郵件地址,SERVICE_URL則是您叫用的 Cloud Run 服務網址。即使向特定流量標記提出要求,這個值仍應保持為服務的網址。$STS_TOKEN是您在 Workload Identity Federation 操作說明中,上一個步驟收到的 Security Token Service 權杖。
您可以使用 Authorization: Bearer ID_TOKEN 標頭或 X-Serverless-Authorization: Bearer ID_TOKEN 標頭,在向服務提出的要求中加入上一個步驟的 ID 權杖。如果同時提供這兩個標頭,系統只會檢查 X-Serverless-Authorization 標頭。
從 Google Cloud外部使用下載的服務帳戶金鑰
如果 Workload Identity Federation 不適用於您的環境,可以使用下載的服務帳戶金鑰,從Google Cloud外部進行驗證。請按照前文所述,更新用戶端程式碼,改用驗證程式庫。詳情請參閱「服務帳戶金鑰」。
您可以使用自行簽署的 JWT 取得 Google 簽署的 ID 權杖,但這個方法相當複雜,且可能容易出錯。基本步驟如下:
自行簽署服務帳戶 JWT,並將
target_audience宣告設為接收服務的網址或設定的自訂目標對象。如果不使用自訂網域,即使向特定流量標記提出要求,target_audience值也應維持服務網址。將自行簽署的 JWT 換成 Google 簽署的 ID 權杖,其中
aud宣告應設為上述網址。使用
Authorization: Bearer ID_TOKEN標頭或X-Serverless-Authorization: Bearer ID_TOKEN標頭,在向服務提出的要求中加入 ID 權杖。如果同時提供這兩個標頭,系統只會檢查X-Serverless-Authorization標頭。
接收已驗證的要求
在接收私人服務中,您可以剖析授權標頭,接收不記名權杖傳送的資訊。
Python
Java
後續步驟
- 進一步瞭解 ID 權杖驗證