以無伺服器Cloud Run Job服務,進行Batch程式自動化 (以自動化Shell腳本為例)

Jason Peng
google-cloud-apac
Published in
8 min readApr 10, 2023

在以下文章,我將以一個常見的資料交換流程(FTP to GCS to BQ)為例,展示Cloud Run Job與Cloud Workflow結合的方便與彈性。

原始來源:https://gitlab.com/holodragon/gcp-howto/-/tree/master/serverless-shell-run

於此範例,你將能參考與學習

  • 建構簡單FTP伺服器。
  • 配置Cloud Run存取VPC中擁有私有IP的FTP伺服器。
  • 打包Shell Script成容器服務。
  • 以Cloud Run JOB發布Shell Script器服務。
  • 安全配置帳號密碼(Secret)在Cloud Run上。
  • 以Cloud Workflow多步驟驅動Cloud Run Job服務。
  • 透過Cloud Run存取Cloud Storage, BigQuery等服務。

為何採用無伺服器Cloud Run Job

針對批次程式運行,於Google Cloud Platform上提供了Cloud Run Job無伺服器的方案,它提供了以下好處:

  • 方便:無需準備跟管理任何機器與OS
  • 經濟:資源為按需計費,無batch運作時不收任何運算(compute)費用
  • 安全:可包含各種安全機制,如:私有網路存取、密碼管理、存取權限控制等。
  • 快速:自開發到上線所需時間短。

關於此範例

此範例展示了:整合傳統以FTP為主的資料交換機制,將資料轉進BigQuery現代化資料倉儲之自動化流程。

流程與架構:

如圖示,整體流程自動化了以下兩步驟:

  1. 透過私有IP訪問FTP Server,取得資料壓縮檔後:1.傳送到GCS做備份。2.解壓縮資料並上傳GCS作後續作業準備。
  2. 呼叫BigQuery命令,進行讀取GCS內之csv檔案,轉存至BigQuery資料表內。

開始動手

前置準備

1. 以GCE部署一台FTP server。確認FTP服務正常,並記錄帳號與密碼。

sudo apt-get install vsftpd -y
## 以sudo編輯 /etc/vsftpd.conf
## listen_address=0.0.0.0
## local_root=/home/ftpuser/FTP
sudo systemctl restart vsftpd
sudo systemctl status vsftpd
## 確認ftp服務正常
sudo apt-get install wget -y
sudo apt-get install unzip -y

## 設定FTP user
sudo adduser ftpuser
su ftpuser
mkdir -p /home/ftpuser/FTP/data
wget -O /home/ftpuser/FTP/data/TX_$(date +%Y%m%d).zip https://gitlab.com/holodragon/gcp-howto/-/raw/master/serverless-shell-run/sample/TX_20230424.zip

2. 開通所需要服務API。

gcloud services enable cloudbuild.googleapis.com \
secretmanager.googleapis.com \
vpcaccess.googleapis.com \
run.googleapis.com \
workflows.googleapis.com

3. 設定Cloud Build所需IAM (置換你的[專案ID與number])

gcloud projects add-iam-policy-binding [專案ID] \
--member=serviceAccount:[專案Number]@cloudbuild.gserviceaccount.com \
--role=roles/storage.admin

部署環境與程式

為求步驟單純,compute運算皆以預設專案service account。

Step0: 給予預設Service Account以下角色:

專案層級

  • BigQuery Data Editor
  • BigQuery Job User
  • Cloud Run Invoker
  • Cloud Run Viewer
  • Secret Manager Secret Accessor
  • Logs Writer

GCS Bucket層級

  • Storage Admin

運行指令:設定預設專案service account所需IAM (置換你的[專案ID與number])

gcloud projects add-iam-policy-binding [專案ID] \
--member=serviceAccount:[專案Number]-compute@developer.gserviceaccount.com \
--role=roles/storage.admin \
--role=roles/logging.logWriter \
--role=roles/run.admin \
--role=roles/bigquery.admin \
--role=roles/secretmanager.secretAccessor

Step1: 在 Cloud Shell 下載本源代碼目錄。

git clone https://gitlab.com/holodragon/gcp-howto.git
cd serverless-shell-run

Step2: 在 Artifact Registry 中創建一個容器庫。並記錄容器庫路徑

Step3: 編輯 build.sh 文件中的容器庫路徑,然後執行它。舉例:

GOOGLE_CLOUD_PROJECT=[YOUR GOOGLE PROJECT ID]
REGION="us-central1"
IMAGE_URI="$REGION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/[repo name]/shell-jobs:latest"

Step4: 確認容器映像已成功構建並推送到容器庫中。

Step5: 在 GCS 中創建一個存儲桶並創建以下文件夾:

  • /source_zip (用於組合BACKUP_BUCKET_URI參數)
  • /unzip_files (用於組合UNZIP_BUCKET_URI參數)

Step6: 在 BigQuery 中為 BQ_DATASET 環境變量創建一個數據集,然後使用 CSV 模式在該數據集中創建表格(例如本範例為store_m)。

Step7: 編輯 deploy.sh,配置系統必要環境參數,確認參數設定後執行

## 必要設定參數
GOOGLE_CLOUD_PROJECT=[YOUR GOOGLE PROJECT ID]
REGION="us-central1"
JOB_IMAGE="[DOCKER IMAGE URL]"
FTP_HOST="[FTP PRIVATE IP]"
FTP_UID="[YOUR FTP USER ID]"
FTP_PWD="[YOUR FTP PASSWORD]"
FILE_PREFIX="[FTP FILE NAME PREFIX]"
FOLDER_PREFIX="[FTP FOLDER PREFIX]"
BACKUP_BUCKET_URI="gs://[GCS BUCKET & FOLDER PATH]/"
UNZIP_BUCKET_URI="gs://[GCS BUCKET & FOLDER PATH]/"
BQ_PROJECT="[YOUR BQ PROJECT ID]"
BQ_DATASET="[YOUR BQ DATESET ID]"

Step8: 以下步驟已由deploy.sh腳本涵蓋建置(也可在GCP Console上手動建置):

  • 為 Cloud Run Job 作業創建一個無服務器 VPC 訪問連接器,以使用私有 IP 訪問 FTP。
  • 在 Secret Manager 中為 FTP_UID, FTP_PWD 環境變量個別創建密鑰。
  • 以workflow-cloudrun.yaml建立一Cloud Workflow服務設定。

Step9: 於GCP Console上,至Cloud Workflow頁面手動執行流程。

結果檢視

至以下位置確認Cloud Run Job與Cloud Workflow皆正確執行完畢

結語

上面步驟是手動執行Cloud Workflow流程。它可以很輕易的在介面上設置觸發條件,透過定期排程(Scheduler)或是事件驅動(Eventarc)。

此外進行類似批次作業在Google Cloud上的方案,可能還有其他組合方式(如:Cloud Batch、GKE、Cloud Task等),端看要運用的場景決定。不過在通用性、彈性、與易用性上的平衡來說,我認為Cloud Run Job與Cloud Workflow的組合也它的優勢在。

--

--

Jason Peng
google-cloud-apac

A cloud engineer who love creative ideas. All views and opinions are my own. 所有文章是我的個人觀點,並不代表任何公司組織