GCP Cloud Build + Cloud Run + Cloud Scheduler

2022/09/22

 

使用Cloud Build建立docker image並存放在GCP上

docker image可放在GCP以下兩種服務上

 

Artifact Registry

首先前往Artifact Registry建立一個Docker類型的Repository(加密方式使用Google-managed即可)

接著在要發布的原始碼路徑下

執行以下格式的指令

gcloud builds submit --tag [repo-region]-docker.pkg.dev/[project-id]/[repo-name]/[image-name]:[tag-name]

# example
gcloud builds submit --tag us-docker.pkg.dev/project-foobar/repository-foobar/image-foobar:latest

 

原始碼將透過Cloud Build進行Image打包並存放至Artifact Registry中

想查看可用region可使用gcloud artifacts locations list指令查看

 

Container Registry

也可透過以下指令將原始碼打包為Image至Container Registry中

此種方式不需要事先在GCP上建立Repository

gcloud builds submit \
  --tag gcr.io/[project-id]/[repo-name]/[image-name]:[tag-name] \
  --region [region]

# example
gcloud builds submit \
  --tag gcr.io/project-foobar/repository-foobar/image-foobar:latest \
  --region us-central1

 

透過Cloud Build Confirguration File佈署

ref

gloud build command可透過一個指定的Yaml Configruation File來進行佈署

在這個Confirguration File內可設計更複雜的Build Step

並可透過Substituting variable在Confirguration File中使用變數

包含預設變數(例如: PROJECT_ID)

或是自訂變數

 

cloudbuild.yml

以下自訂變數為_TAG及_PROJECT_ID

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', 'gcr.io/${_PROJECT_ID}/some-repo/image-name:${_TAG}', '.' ]
images:
- 'gcr.io/${_PROJECT_ID}/some-repo/image-name:${_TAG}'

 

執行Cloud Build

透過--substitutions option可將自訂變數帶入Configuration File中

格式為: --substitutions=[KEY=VALUE,…]

使用逗號可區隔多個變數

gcloud builds submit \
 --region us-central1 \
 --config cloudbuild.yml \
 --substitutions _PROJECT_ID=foobar-project-id,_TAG=stable

 

建立Cloud Run Service

 

建立Cloud Run Service

以下為佈署指令(亦可透過Console UI建立)

另外注意的是

若不使用service-account參數

GCP將會自動使用預設的Compute Engine Service Account來綁定該Service

gcloud run deploy [cloud-run-service-name] \
  --image gcr.io/[project-id]/[repo-name]/[image-name]:[tag-name] \
  --region [region] \
  --service-account [service-account]

 

gcloud run deploy command其他常用選項

  • allow-unauthenticated / no-allow-unauthenticated: 設定允許/不允許未經允許的存取,若不使用這兩個選項,則CLI會跳出詢問提示
  • set-env-vars: 設定Container環境變數(list variable), 例如--set-env-vars MODE=PRODUCTION --set-env-vars LIMIT=1000
  • cpu: CPU核心數, 預設為1
  • memory: 容器記憶體大小, 預設為512Mi

 

首次建立Not allow unauthenticated service注意事項

若將Service設定為Not allow unauthenticated必須注意以下事項

首次建立完Service之後

必須手動調整該Service Permisson設定

使用ADD PRINCIPAL功能加入允許存取的Service Account

並賦予Cloud Run Invoker權限

否則即使其他服務(例如Cloud Scheduler Job)使用該Service建立時綁定的Service Account

也無法存取該Cloud Run Service

 

或是透過以下指令直接設定關聯Cloud Run Service的Service Account

gcloud run services add-iam-policy-binding {CLOUD_RUN_SERVICE_NAME} \
    --role "roles/run.invoker" \
    --region us-central1 \
    --member serviceAccount:{SERVICE_ACCOUNT}

# example
gcloud run services add-iam-policy-binding some-service \
    --role "roles/run.invoker" \
    --region us-central1 \
    --member serviceAccount:foobar@my-project.iam.gserviceaccount.com

 

透過Cloud Scheduler觸發Cloud Run Service

Job設定

  • Target Type: HTTP
  • Auth Header: Add OIDC token(Cloud Run Service需要驗證的話)
    • Service Account: 選擇上述建立Cloud Run Service關聯的Service Account

 

跨專案存取Container Registry Image建立Cloud Run Service

有的時候可能會需要使用別的GCP Project的Container Registry Image來建立Cloud Run Service

這時候必須在主專案GCS的artifacts.<PROJECT_ID>.appspot.com Bucket中(此Bucket會在Registry建立成功後自動建立)

允許以下Cloud Run Service Agent擁有Storage Object Viewer權限

service-<PROJECT_NUMBER>@serverless-robot-prod.iam.gserviceaccount.com

bucket-grant-access-cross-project.png

 

Project Number取得方式

前往專案的Dashboard中即可查看Project ID及Project Number

 

設定完成後

即可正常Pull Image來建立Cloud Run Service

 

跨專案存取Artifact Registry Image建立Cloud Run Service

跟上方跨專案存取Container Registry的設定方式雷同

在Artifact Registry頁面點擊要設定的Repositroy

在Info Panel點擊ADD PRINCIPAL按鈕

Pincipal一樣設定令一個專案的Cloud Run Service Agent(service-<PROJECT_NUMBER>@serverless-robot-prod.iam.gserviceaccount.com)

Role選擇Cloud Run Service Agent

artifact-registry-allow-cross-project-access.png

 

artifact-registry-allow-cross-project-access-2.png

 

測試Cloud Run Private Service

ref: https://cloud.google.com/run/docs/authenticating/developers#testing

 

透過此方式就可以直接測試Cloud Run Private Service

# bash
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  https://cloud-run-service-url

# fish shell
curl -H "Authorization: Bearer "(gcloud auth print-identity-token) \
  https://cloud-run-service-url