1. 簡介
總覽
Cloud Run 函式是輕量運算解決方案,可讓開發人員建立可使用 HTTPS 觸發或回應 CloudEvents 的單一用途獨立函式,不必管理伺服器或執行階段環境。如要進一步瞭解 Cloud Run 函式,請參閱我們的網誌文章。
控制 Cloud Run 函式叫用有兩種主要方法:根據身分保護存取權,以及使用網路式存取權控管保護存取權。本程式碼研究室著重於第一種方法,並逐步說明下列 3 種情境,以依據身分叫用函式:
- 使用 gcloud 身分權杖,針對本機開發和測試目的叫用函式
- 在本機開發及測試時,模擬服務帳戶,以便使用與正式版相同的憑證
- 使用 Google 用戶端程式庫處理 Google Cloud API 的驗證作業,例如當服務需要叫用函式時
課程內容
- 如何設定 Cloud Run 函式的驗證機制,並確認驗證機制已正確設定
- 提供 gcloud 身分識別碼,從本機開發環境叫用已驗證的函式
- 如何建立服務帳戶,並授予適當的角色以叫用函式
- 如何從具有適當函式叫用角色的本機開發環境,模擬服務
2. 設定和需求
必要條件
- 您已登入 Cloud Console
- 您之前已部署由 HTTP 觸發的 Cloud Run 函式。查看快速入門導覽課程範例。
- (選用) 在第 3 種情況下,本程式碼研究室使用 Node.js 和 npm 做為範例,但您可以使用 Google Auth 用戶端程式庫支援的任何執行階段。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」 圖示
。
如果這是您首次啟動 Cloud Shell,系統會顯示中介畫面,說明 Cloud Shell 的功能。如果您看到中介畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 的作業只需幾分鐘的時間。
這個虛擬機器會載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,可大幅提升網路效能和驗證功能。您可以在瀏覽器中完成本程式碼研究室的大部分工作,甚至是全部工作。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 Cloud Shell 中執行下列指令,確認您已通過驗證:
gcloud auth list
指令輸出
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如未設定,請輸入下列指令設定專案:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
3. 建立及測試經過驗證的 Cloud Run 函式
要求驗證機制,表示叫用函式的原則必須具有 Cloud Run 叫用者角色;否則,函式會傳回 403 Forbidden 錯誤。本程式碼研究室會說明如何依據原則授予適當的叫用者角色。
設定本機環境變數,簡化 gcloud 指令
首先,您將建立一些環境變數,以便提高本程式碼研究室中所用 gcloud
指令的可讀性。
REGION=us-central1 PROJECT_ID=$(gcloud config get-value project)
建立函式原始碼
雖然本程式碼研究室使用 Node.js,但您可以使用 Google 驗證用戶端程式庫支援的任何執行階段。
首先,請建立目錄並使用 cd 指令前往該目錄。
mkdir auth-function-codelab && cd $_
接著建立 package.json 檔案。
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" } } ' > package.json
接著,建立 index.js 來源檔案。
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
建立已驗證的函式
以下是為 nodejs20 執行階段建立已驗證函式的步驟。不過,您可以使用 Google Auth 用戶端程式庫支援的任何執行階段。
FUNCTION_NAME=authenticated-function-codelab ENTRY_POINT=helloWorld
如要將 Cloud Run 函式直接部署至 Cloud Run,請執行下列指令:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function helloWorld \ --region $REGION \ --no-allow-unauthenticated
然後將函式網址儲存為環境變數,以供日後使用。
FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"
如果您想部署 Cloud Functions 第 2 代,請使用下列指令:
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime=nodejs20 \ --region=$REGION \ --source=. \ --entry-point=helloWorld \ --trigger-http \ --no-allow-unauthenticated
然後將函式網址儲存為環境變數,以供日後使用。
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
嘗試以匿名呼叫端的身份叫用函式,驗證函式是否需要驗證
您將在不驗證的情況下叫用函式,確認您收到預期的 403 錯誤。
在指令列中執行下列 curl
指令:
curl -i $FUNCTION_URL
您會看到以下結果:
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/</code> from this server.</h2> <h2></h2> </body></html>
您現在可以逐步瞭解 3 種情境,瞭解如何透過提供驗證資訊來叫用函式。
4. 情境 1:使用 gcloud 身分權杖
開發人員需要在本機開發函式時測試函式。在本節中,您將執行快速測試,驗證函式是否能使用您自己的身分進行適當驗證。
執行下列指令,確認是否使用 gcloud
進行驗證:
gcloud auth list
活躍身分旁會顯示星號,例如:
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
如要進一步瞭解如何設定 gcloud init 和 gcloud auth login,請參閱說明文件。
接下來,請叫用函式並傳遞您的身分識別碼。
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
您現在會看到結果:
Hello World!
疑難排解
如果您收到 403 Forbidden 錯誤,請確認您的身分具有 Cloud Run 叫用者角色。您可以使用 IAM 控制台驗證指派給主體的角色。
儘管在開發期間使用自己的識別憑證可讓您快速測試函式,但已驗證函式的呼叫端需要適當的角色,否則呼叫端會收到 403 禁止錯誤。
您應該遵循最小權限原則,限制具有可叫用函式的角色身分和服務帳戶數量。在下一個情境中,您將瞭解如何建立新的服務帳戶,並授予適當的角色以叫用函式。
5. 情境 2:模擬服務帳戶
在這種情況下,您會冒用 (即假設服務帳戶的權限) 服務帳戶,在本機開發及測試時叫用函式。您可以模擬服務帳戶,以正式版相同的憑證測試函式。
這樣一來,您不但可以驗證角色,還能遵循最小權限原則,不必為了本機測試目的,將 Cloud Functions 叫用者角色授予其他身分。
為了完成這個程式碼研究室,您將建立一個新的服務帳戶,該帳戶只具備用於叫用您在這個程式碼研究室中建立的函式的角色。
建立新的服務帳戶
首先,您將建立幾個額外的環境變數,用來代表 gcloud 指令中使用的服務帳戶。
SERVICE_ACCOUNT_NAME="invoke-functions-codelab" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
接下來,您將建立服務帳戶。
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \ --display-name="Cloud Run function Authentication codelab"
並授予服務帳戶 Cloud Run 叫用者角色:
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --region=us-central1 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/run.invoker'
模擬服務帳戶以叫用函式
為此,您必須取得新建立的服務帳戶的 ID 權杖,以便冒用該帳戶。
新增模擬所需的角色
如要冒用服務帳戶,您的使用者帳戶必須具備服務帳戶憑證建立者 (roles/iam.serviceAccountTokenCreator) 角色,才能為服務帳戶產生 ID 權杖。
您可以執行下列指令,為有效使用者帳戶授予這個角色:
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS \ --member user:$ACCOUNT_EMAIL \ --role='roles/iam.serviceAccountTokenCreator'
使用服務帳戶的 ID 權杖
請稍候幾分鐘,讓權限生效。您現在可以傳遞服務帳戶的 ID 權杖來叫用函式。
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)"
您會看到以下畫面:
WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com]. Hello World!
6. 情境 3:使用 Google 用戶端程式庫
在本程式碼研究室的最後部分,您將在本機執行小型服務,為服務帳戶產生 ID 權杖,然後使用 Google Auth 用戶端程式庫和應用程式預設憑證 (ADC),以程式輔助方式呼叫該函式。如要進一步瞭解 Google 用戶端程式庫,請參閱文件的用戶端程式庫說明一節。
如果您想在本機 (例如筆電、Cloud Shell 等) 編寫及測試函式,同時與其他 Google Cloud 資源 (例如 Cloud Storage、Vision API 等) 互動,使用 ADC 就特別重要。在此範例中,您將瞭解如何讓服務叫用另一個需要驗證的函式。如要進一步瞭解 ADC 和本機開發作業,請參閱這篇網誌文章:如何在本機開發及測試 Cloud Functions | Google Cloud 網誌
執行 gcloud 指令,模擬服務帳戶
ADC 會根據應用程式環境自動尋找憑證,並使用這些憑證向 Google Cloud API 進行驗證。您可以使用 –impersonate-service-account 標記,透過服務帳戶的身分模擬 Google Cloud API 的驗證。
如要冒用服務帳戶,您可以執行下列指令:
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
您現在是以該服務帳戶的身分,而非自己的身分執行 gcloud 指令。
建立並執行服務以叫用已驗證的函式
每個執行階段都有可安裝的 Google 驗證用戶端程式庫。本程式碼研究室會引導您逐步完成在本機建立及執行 Node.js 應用程式的程序。
以下是 Node.js 的步驟:
- 建立新目錄
mkdir local-dev && cd $_
- 建立新的 Node.js 應用程式
npm init -y
- 安裝 Google 驗證用戶端程式庫
npm install google-auth-library
- 建立
index.js
檔案 - 擷取 Cloud Run 函式的網址,您將在後續步驟中新增至程式碼。
echo $FUNCTION_URL
- 將下列程式碼加入 index.js。請務必將 targetAudience 變數變更為 Cloud Run 函式網址。
index.js
// Cloud Functions uses your function's url as the `targetAudience` value
const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';
// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal
const url = targetAudience;
const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();
async function request() {
console.info(`request ${url} with target audience ${targetAudience}`);
// this call retrieves the ID token for the impersonated service account
const client = await auth.getIdTokenClient(targetAudience);
const res = await client.request({ url });
console.info(res.data);
}
request().catch(err => {
console.error(err.message);
process.exitCode = 1;
});
- 執行應用程式
node index.js
此時畫面會顯示「Hello World!」
疑難排解
如果系統在資源中顯示「iam.serviceAccounts.getOpenIdToken」錯誤 (或該權杖可能不存在),請稍候幾分鐘,等待服務帳戶權杖建立者角色生效。
如果在這個環境中收到「無法擷取 ID 權杖」錯誤訊息,請使用 GCE,或是將 GOOGLE_APPLICATION_CREDENTIALS 環境變數設為服務帳戶憑證 JSON 檔案,可能忘記執行指令
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. 恭喜!
恭喜您完成程式碼研究室!
建議您參閱說明文件,瞭解如何保護 Cloud Run 函式。
另外,也建議您參閱這篇有關使用 Cloud Run 函式本機開發作業的網誌文章,瞭解如何在本機開發人員環境中開發及測試 Cloud Run 函式。
涵蓋內容
- 如何設定 Cloud Run 函式的驗證機制,並確認驗證機制已正確設定
- 提供 gcloud 身分識別碼,從本機開發環境叫用已驗證的函式
- 如何建立服務帳戶,並授予適當的角色以叫用函式
- 如何從具有適當函式叫用角色的本機開發環境,模擬服務
8. 清理
為避免產生意外費用 (例如,這個 Cloud 函式不小心叫用次數超過 免費等級的 Cloud Run 函式叫用次數配額),您可以刪除 Cloud 函式,或是刪除在步驟 2 中建立的專案。
如要停止冒用服務帳戶,您可以使用自己的身分重新登入:
gcloud auth application-default login
如要刪除 Cloud Run 函式,請前往 Cloud Run 函式 Cloud 控制台 (https://console.cloud.google.com/functions/)。請確認目前選取的專案是您在步驟 2 中建立的專案。
選取先前部署的 my-authenticated-function。然後按一下「刪除」。
如果您選擇刪除整個專案,可以前往 https://console.cloud.google.com/cloud-resource-manager,選取您在步驟 2 中建立的專案,然後選擇「Delete」(刪除)。如果您刪除專案,就必須在 Cloud SDK 中變更專案。您可以執行 gcloud projects list
來查看所有可用專案的清單。