本教學課程將逐步說明如何建立在 Cloud Run 上執行的安全雙服務應用程式。這個應用程式是 Markdown 編輯器,包含公開的「前端」服務 (任何人都能用來撰寫 Markdown 文字),以及私人的「後端」服務 (可將 Markdown 文字轉譯為 HTML)。
後端服務會使用 Cloud Run 內建的 IAM 服務對服務驗證功能,限制可呼叫服務的使用者,這兩項服務都採用最低權限原則,除非必要,否則無法存取 Google Cloud 的其餘部分。
本教學課程的限制或非目標
本教學課程不會說明使用者驗證,這類驗證會使用 Identity Platform 或 Firebase 驗證產生使用者 ID 權杖,並手動驗證使用者身分。如要進一步瞭解使用者驗證,請參閱使用者驗證的 Cloud Run 教學課程。
本教學課程不會說明如何合併使用 IAM 驗證和 ID 權杖方法,因為系統不支援這類做法。
目標
- 建立專屬服務帳戶,並授予最低權限,用於服務對服務驗證,以及服務存取 Google Cloud的其餘部分。
- 撰寫、建構及部署兩個會互動的 Cloud Run 服務。
- 在公開和私人的 Cloud Run 服務之間提出要求。
費用
在本文件中,您會使用 Google Cloud的下列計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
事前準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run API.
- 安裝並初始化 gcloud CLI。
- 安裝 curl 以便試用服務
-
Cloud Build 編輯器 (
roles/cloudbuild.builds.editor
) -
Cloud Run Admin (
roles/run.admin
) -
建立服務帳戶 (
roles/iam.serviceAccountCreator
) -
專案 IAM 管理員 (
roles/resourcemanager.projectIamAdmin
) -
服務帳戶使用者 (
roles/iam.serviceAccountUser
) -
服務用量消費者 (
roles/serviceusage.serviceUsageConsumer
) -
儲存空間管理員 (
roles/storage.admin
) -
Artifact Registry 存放區管理員 (
roles/artifactregistry.repoAdmin
)
必要的角色
如要取得完成本教學課程所需的權限,請要求管理員為您授予專案的下列 IAM 角色:
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
設定 gcloud 預設值
如要針對 Cloud Run 服務設定 gcloud 的預設值:
設定您的預設專案:
gcloud config set project PROJECT_ID
將 PROJECT_ID 改為您為本教學課程建立的專案名稱。
為所選區域設定 gcloud:
gcloud config set run/region REGION
將 REGION 改為您所選擇的支援 Cloud Run 地區。
Cloud Run 位置
Cloud Run 具有「地區性」,這表示執行 Cloud Run 服務的基礎架構位於特定地區,並由 Google 代管,可為該地區內所有區域提供備援功能。
選擇 Cloud Run 服務的執行地區時,請將延遲時間、可用性或耐用性需求做為主要考量。一般而言,您可以選擇最靠近使用者的地區,但您應考量 Cloud Run 服務所使用的其他 Google Cloud
產品位置。使用分散在不同位置的 Google Cloud 產品,可能會影響服務的延遲時間和費用。
Cloud Run 可在下列地區使用:
採用級別 1 定價
asia-east1
(臺灣)asia-northeast1
(東京)asia-northeast2
(大阪)asia-south1
(印度孟買)europe-north1
(芬蘭)二氧化碳排放量低
europe-north2
(斯德哥爾摩)二氧化碳排放量低2
europe-southwest1
(馬德里)二氧化碳排放量低
europe-west1
(比利時)二氧化碳排放量低
europe-west4
(荷蘭)二氧化碳排放量低
europe-west8
(米蘭)europe-west9
(巴黎)二氧化碳排放量低
me-west1
(特拉維夫)northamerica-south1
(墨西哥)us-central1
(愛荷華州)二氧化碳排放量低
us-east1
(南卡羅來納州)us-east4
(北維吉尼亞州)us-east5
(哥倫布)us-south1
(達拉斯)二氧化碳排放量低
us-west1
(奧勒岡州)二氧化碳排放量低
採用級別 2 定價
africa-south1
(約翰尼斯堡)asia-east2
(香港)asia-northeast3
(韓國首爾)asia-southeast1
(新加坡)asia-southeast2
(雅加達)asia-south2
(印度德里)australia-southeast1
(雪梨)australia-southeast2
(墨爾本)europe-central2
(波蘭華沙)europe-west10
(柏林)二氧化碳排放量低
europe-west12
(杜林)europe-west2
(英國倫敦)二氧化碳排放量低
europe-west3
(德國法蘭克福)二氧化碳排放量低
europe-west6
(瑞士蘇黎世)二氧化碳排放量低
me-central1
(杜哈)me-central2
(達曼)northamerica-northeast1
(蒙特婁)二氧化碳排放量低
northamerica-northeast2
(多倫多)二氧化碳排放量低
southamerica-east1
(巴西聖保羅)二氧化碳排放量低
southamerica-west1
(智利聖地牙哥)二氧化碳排放量低
us-west2
(洛杉磯)us-west3
(鹽湖城)us-west4
(拉斯維加斯)
如果您已建立 Cloud Run 服務,即可在 Google Cloud 控制台的 Cloud Run 資訊主頁中查看地區。
擷取程式碼範例
如要擷取要使用的程式碼範例:
將範例應用程式存放區複製到 Cloud Shell 或本機電腦:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
您也可以 下載 zip 格式的範例,然後解壓縮該檔案。
Python
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
您也可以 下載 zip 格式的範例,然後解壓縮該檔案。
Go
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
您也可以 下載 zip 格式的範例,然後解壓縮該檔案。
Java
git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
您也可以 下載 zip 格式的範例,然後解壓縮該檔案。
C#
git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
您也可以 下載 zip 格式的範例,然後解壓縮該檔案。
變更為包含 Cloud Run 程式碼範例的目錄:
Node.js
cd nodejs-docs-samples/run/markdown-preview/
Python
cd python-docs-samples/run/markdown-preview/
Go
cd golang-samples/run/markdown-preview/
Java
cd java-docs-samples/run/markdown-preview/
C#
cd dotnet-docs-samples/run/markdown-preview/
查看私有 Markdown 算繪服務
從前端的角度來看,Markdown 服務的 API 規格很簡單:
- 一個端點,位於
/
- 預期會收到 POST 要求
- POST 要求內文為 Markdown 文字
您可能想檢查所有程式碼,瞭解是否有安全疑慮,或只是想透過探索 ./renderer/
目錄進一步瞭解程式碼。請注意,本教學課程不會說明 Markdown 轉換程式碼。
發布私有 Markdown 顯示服務
如要推送您的程式碼,請使用 Cloud Build 建構程式碼,並上傳至 Artifact Registry,然後部署到 Cloud Run:
切換至
renderer
目錄:Node.js
cd renderer/
Python
cd renderer/
Go
cd renderer/
Java
cd renderer/
C#
cd Samples.Run.MarkdownPreview.Renderer/
建立 Artifact Registry:
gcloud artifacts repositories create REPOSITORY \ --repository-format docker \ --location REGION
取代:
- REPOSITORY,並為存放區指定專屬名稱。專案中每個存放區位置的存放區名稱不得重複。
- REGION 改成要用於 Artifact Registry 存放區的 Google Cloud 地區。
執行下列指令以建構您的容器,然後發布到 Artifact Registry。
Node.js
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
renderer
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
Python
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
renderer
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
Go
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
renderer
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
Java
本範例使用 Jib,透過常見的 Java 工具建構 Docker 映像檔。Jib 可最佳化容器建構作業,不需要 Dockerfile,也不必安裝 Docker。進一步瞭解如何使用 Jib 建構 Java 容器。
使用 gcloud 憑證輔助程式授權 Docker 推送至 Artifact Registry。
gcloud auth configure-docker
使用 Jib Maven 外掛程式建構容器,並推送至 Artifact Registry。
mvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
renderer
則是您要給予服務的名稱。若成功執行,您會看到「BUILD SUCCESS」(建構成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
C#
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
renderer
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
以存取權受限的私人服務形式部署。
Cloud Run 提供開箱即用的存取權控管和服務身分功能。存取權控管機制提供驗證層,可限制使用者和其他服務叫用服務。服務身分可建立權限受限的專屬服務帳戶,限制服務存取其他Google Cloud 資源。
建立服務帳戶,做為算繪服務的「運算身分」。根據預設,除了專案成員資格外,這項角色沒有其他權限。
指令列
gcloud iam service-accounts create renderer-identity
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
Markdown 算繪服務不會直接與 Google Cloud中的任何其他項目整合。不需要其他權限。
使用
renderer-identity
服務帳戶部署,並拒絕未經驗證的存取要求。指令列
gcloud run deploy renderer \ --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/renderer \ --service-account renderer-identity \ --no-allow-unauthenticated
如果服務帳戶屬於同一個專案,Cloud Run 可以使用簡短形式的服務帳戶名稱,而非完整電子郵件地址。
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
試用私人 Markdown 算繪服務
網頁瀏覽器無法直接載入私有服務。請改用 curl
或類似的 HTTP 要求 CLI 工具,以便插入 Authorization
標頭。
如要將一些粗體文字傳送至服務,並查看服務如何將 Markdown 星號轉換為 HTML <strong>
標記,請按照下列步驟操作:
從部署輸出內容取得網址。
使用
gcloud
衍生專屬的開發專用身分權杖,以進行驗證:TOKEN=$(gcloud auth print-identity-token)
建立 curl 要求,將原始 Markdown 文字做為經過網址逸出的查詢字串參數傳遞:
curl -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: text/plain' \ -d '**Hello Bold Text**' \ SERVICE_URL
將 SERVICE_URL 替換為部署 Markdown 轉譯服務後提供的網址。
回應應為 HTML 程式碼片段:
<strong>Hello Bold Text</strong>
查看編輯器與算繪服務之間的整合
編輯器服務提供簡單的文字輸入 UI,以及可查看 HTML 預覽的空間。請先開啟 ./editor/
目錄,檢查先前擷取的程式碼,再繼續操作。
接著,請探索下列幾節程式碼,瞭解如何安全地整合這兩項服務。
Node.js
render.js
模組會向私有轉譯器服務建立已驗證的要求。這項服務會使用 Cloud Run 環境中的 Google Cloud 中繼資料伺服器建立身分識別權杖,並將權杖新增至 HTTP 要求,做為 Authorization
標頭的一部分。
在其他環境中,render.js
會使用應用程式預設憑證向 Google 伺服器要求權杖。
從 JSON 剖析 Markdown,並傳送至 Renderer 服務,轉換為 HTML。
Python
new_request
方法會建立對私人服務的已驗證要求。這個函式會在 Cloud Run 環境中使用 Google Cloud 中繼資料伺服器建立身分符記,並將該符記新增至 HTTP 要求,做為 Authorization
標頭的一部分。
在其他環境中,new_request
會透過應用程式預設憑證進行驗證,並向 Google 伺服器要求身分識別權杖。
從 JSON 剖析 Markdown,並傳送至 Renderer 服務,轉換為 HTML。
Go
RenderService
會建立對私有服務的已驗證要求。這個函式會使用 Cloud Run 環境中的 Google Cloud 中繼資料伺服器建立身分識別權杖,並將權杖新增至 HTTP 要求,做為 Authorization
標頭的一部分。
在其他環境中,RenderService
會透過應用程式預設憑證進行驗證,並向 Google 伺服器要求身分識別權杖。
將要轉換為 HTML 的 Markdown 文字加入要求後,要求會傳送至 Renderer 服務。系統會處理回應錯誤,以區分通訊問題和算繪功能。
Java
makeAuthenticatedRequest
會建立對私有服務的已驗證要求。這項服務會使用 Cloud Run 環境中的 Google Cloud 中繼資料伺服器建立身分識別權杖,並將其新增至 HTTP 要求,做為 Authorization
標頭的一部分。
在其他環境中,makeAuthenticatedRequest
會透過應用程式預設憑證進行驗證,並向 Google 伺服器要求身分識別權杖。
從 JSON 剖析 Markdown,並傳送至 Renderer 服務,轉換為 HTML。
C#
GetAuthenticatedPostResponse
會建立對私有服務的已驗證要求。這項服務會使用 Cloud Run 環境中的 Google Cloud 中繼資料伺服器建立身分識別權杖,並將其新增至 HTTP 要求,做為 Authorization
標頭的一部分。
在其他環境中,GetAuthenticatedPostResponse
會透過應用程式預設憑證進行驗證,並向 Google 伺服器要求身分識別權杖。
從 JSON 剖析 Markdown,並傳送至 Renderer 服務,轉換為 HTML。
發布公開編輯器服務
如要建構及部署程式碼:
切換至
editor
目錄:Node.js
cd ../editor
Python
cd ../editor
Go
cd ../editor
Java
cd ../editor
C#
cd ../Samples.Run.MarkdownPreview.Editor/
執行下列指令以建構您的容器,然後發布到 Artifact Registry。
Node.js
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
editor
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔儲存在 Container Registry 中,日後如有需要,可以重複使用。
Python
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
editor
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
Go
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
editor
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
Java
本範例使用 Jib,透過常見的 Java 工具建構 Docker 映像檔。Jib 可最佳化容器建構作業,不需要 Dockerfile,也不必安裝 Docker。進一步瞭解如何使用 Jib 建構 Java 容器。mvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
editor
則是您要給予服務的名稱。若成功執行,您會看到「BUILD SUCCESS」(建構成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
C#
gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor
其中 PROJECT_ID 是您的 Google Cloud 專案 ID,
editor
則是您要給予服務的名稱。若成功執行,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」(成功) 訊息。映像檔會儲存在 Artifact Registry 中,日後如有需要,可以重複使用。
以私人服務形式部署,並取得算繪服務的特殊存取權。
建立服務帳戶,做為私有服務的「運算身分」。根據預設,除了專案成員資格外,這項角色沒有其他權限。
指令列
gcloud iam service-accounts create editor-identity
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
Editor 服務不需要與 Markdown 算繪服務以外的任何項目互動。 Google Cloud
授予
editor-identity
計算身分存取權,以便叫用 Markdown 算繪服務。凡是將此做為運算身分的服務,都會擁有這項權限。指令列
gcloud run services add-iam-policy-binding renderer \ --member serviceAccount:editor-identity@PROJECT_ID.iam.gserviceaccount.com \ --role roles/run.invoker
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
由於這項服務在算繪服務的環境中獲得叫用者角色,因此編輯器只能叫用算繪服務這個私有 Cloud Run 服務。
使用
editor-identity
服務帳戶部署,並允許公開存取,不必驗證。指令列
gcloud run deploy editor --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/editor \ --service-account editor-identity \ --set-env-vars EDITOR_UPSTREAM_RENDER_URL=SERVICE_URL \ --allow-unauthenticated
取代:
- 將 PROJECT_ID 改成您的專案 ID
- SERVICE_URL,並將其替換為部署 Markdown 轉譯服務後提供的網址。
Terraform
如要瞭解如何套用或移除 Terraform 設定,請參閱「基本 Terraform 指令」。
部署編輯器服務:
授予
allUsers
權限來叫用服務:
瞭解 HTTPS 流量
使用這些服務算繪 Markdown 時,會涉及三項 HTTP 要求。
editor-identity
叫用算繪服務。「editor-identity
」和「renderer-identity
」的權限有限,因此任何安全性漏洞或程式碼注入行為,都只能存取有限的 Google Cloud 資源。立即體驗
如要試用完整的雙服務應用程式,請按照下列步驟操作:
在瀏覽器中前往上述部署步驟提供的網址。
嘗試編輯左側的 Markdown 文字,然後按一下按鈕,即可在右側預覽。
內容應該會類似這樣:
如果您選擇繼續開發這些服務,請注意,這些服務對其餘服務的存取權受到身分與存取權管理 (IAM) 限制,且需要額外指派 IAM 角色,才能存取許多其他服務。 Google Cloud
清除所用資源
如果您是為了這個教學課程建立新專案,請刪除專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源。
刪除專案
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。
如要刪除專案:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
刪除教學課程資源
刪除您在本教學課程中部署的 Cloud Run 服務:
gcloud
gcloud run services delete editor gcloud run services delete renderer
您也可以從Google Cloud 控制台刪除 Cloud Run 服務。
移除您在教學課程設定期間新增的 gcloud 預設設定。
gcloud config unset run/region
移除專案設定:
gcloud config unset project
刪除在本教學課程中建立的其他 Google Cloud 資源:
後續步驟
- 如要進一步保護專案,請完成「安全使用 IAM」檢查清單
- 擴充這個範例應用程式,使用 Cloud Monitoring 自訂指標追蹤 Markdown 用量
- 請參閱 Pub/Sub 教學課程,瞭解如何保護非同步微服務