使用 Eventarc 為 Knative 服務建立 BigQuery 處理管道

本教學課程說明如何使用 Eventarc 建構處理管道,排定查詢公開 BigQuery 資料集的作業、根據資料產生圖表,以及透過電子郵件分享圖表連結。

建立 SendGrid API 金鑰

SendGrid 是一項雲端電子郵件服務,可讓您傳送電子郵件,不必維護電子郵件伺服器。

  1. 登入 SendGrid,然後前往「Settings」>「API Keys」
  2. 按一下「建立 API 金鑰」
  3. 選取金鑰的權限。至少必須具備「郵件傳送」權限,才能傳送電子郵件。
  4. 按一下 [Save] 建立金鑰。
  5. SendGrid 會產生一個新金鑰。此為唯一一份金鑰,因此請務必複製並儲存金鑰,以供日後使用。

建立 GKE 叢集

建立啟用 Workload Identity Federation for GKE 的叢集,以便從 GKE 執行的應用程式存取 Google Cloud 服務。您也需要 Workload Identity Federation for GKE,才能使用 Eventarc 轉送事件。

  1. 建立啟用 CloudRunHttpLoadBalancingHorizontalPodAutoscaling 外掛程式的 Knative 服務 GKE 叢集:

    gcloud beta container clusters create $CLUSTER_NAME \
        --addons=HttpLoadBalancing,HorizontalPodAutoscaling,CloudRun \
        --machine-type=n1-standard-4 \
        --enable-autoscaling --min-nodes=2 --max-nodes=10 \
        --no-issue-client-certificate --num-nodes=2  \
        --logging=SYSTEM,WORKLOAD \
        --monitoring=SYSTEM \
        --scopes=cloud-platform,logging-write,monitoring-write,pubsub \
        --zone us-central1 \
        --release-channel=rapid \
        --workload-pool=$PROJECT_ID.svc.id.goog
    
  2. 請稍候幾分鐘,等待叢集建立完成。在過程中,您可能會看到一些警告,但可以放心忽略。叢集建立完成後,輸出內容會類似如下:

    Creating cluster ...done.
    Created [https://container.googleapis.com/v1beta1/projects/my-project/zones/us-central1/clusters/events-cluster].
    
  3. 建立 Artifact Registry 標準存放區,用於儲存 Docker 容器映像檔:

    gcloud artifacts repositories create REPOSITORY \
        --repository-format=docker \
        --location=$CLUSTER_LOCATION

    REPOSITORY 替換成存放區的專屬名稱。

設定 GKE 服務帳戶

設定 GKE 服務帳戶,做為預設的運算服務帳戶。

  1. 在服務帳戶之間建立身分與存取權管理 (IAM) 繫結:

    PROJECT_NUMBER="$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')"
    
    gcloud iam service-accounts add-iam-policy-binding \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:$PROJECT_ID.svc.id.goog[default/default]" \
        $PROJECT_NUMBER-compute@developer.gserviceaccount.com
  2. 使用運算服務帳戶的電子郵件地址,將 iam.gke.io/gcp-service-account 註解新增至 GKE 服務帳戶:

    kubectl annotate serviceaccount \
        --namespace default \
        default \
        iam.gke.io/gcp-service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

啟用 GKE 目的地

如要允許 Eventarc 管理 GKE 叢集中的資源,請啟用 GKE 目的地,並將 Eventarc 服務帳戶繫結至必要角色。

  1. 為 Eventarc 啟用 GKE 目的地:

    gcloud eventarc gke-destinations init
  2. 系統提示繫結必要角色時,請輸入 y

    已繫結下列角色:

    • roles/compute.viewer
    • roles/container.developer
    • roles/iam.serviceAccountAdmin

建立服務帳戶並繫結存取角色

建立 Eventarc 觸發條件前,請先設定使用者管理的服務帳戶,並授予特定角色,讓 Eventarc 可以轉送 Pub/Sub 事件。

  1. 建立名為 TRIGGER_GSA 的服務帳戶:

    TRIGGER_GSA=eventarc-bigquery-triggers
    gcloud iam service-accounts create $TRIGGER_GSA
  2. pubsub.subscribermonitoring.metricWritereventarc.eventReceiver 角色指派給服務帳戶:

    PROJECT_ID=$(gcloud config get-value project)
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/pubsub.subscriber"
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/monitoring.metricWriter"
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/eventarc.eventReceiver"

建立 Cloud Storage 值區

建立 Cloud Storage bucket 來儲存圖表。請確認值區和圖表可公開存取,且與 GKE 服務位於相同區域:

export BUCKET="$(gcloud config get-value core/project)-charts"
gcloud storage buckets create gs://${BUCKET} --location=$(gcloud config get-value run/region)
gcloud storage buckets update gs://${BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} --member=allUsers --role=roles/storage.objectViewer

複製存放區

複製 GitHub 存放區。

git clone https://github.com/GoogleCloudPlatform/eventarc-samples
cd eventarc-samples/processing-pipelines

部署通知器服務

bigquery/notifier/python 目錄部署 Knative serving 服務,接收圖表建立者事件,並使用 SendGrid 透過電子郵件傳送所產生圖表的連結。

  1. 建構及推送容器映像檔:

    pushd bigquery/notifier/python
    export SERVICE_NAME=notifier
    docker build -t $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 .
    docker push $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1
    popd
  2. 將容器映像檔部署到 Knative serving,並傳遞要傳送電子郵件的地址和 SendGrid API 金鑰:

    export TO_EMAILS=EMAIL_ADDRESS
    export SENDGRID_API_KEY=YOUR_SENDGRID_API_KEY
    gcloud run deploy ${SERVICE_NAME} \
        --image $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 \
        --update-env-vars TO_EMAILS=${TO_EMAILS},SENDGRID_API_KEY=${SENDGRID_API_KEY},BUCKET=${BUCKET}

    更改下列內容:

    • EMAIL_ADDRESS:要傳送所產生圖表連結的電子郵件地址
    • YOUR_SENDGRID_API_KEY:先前記下的 SendGrid API 金鑰

看到服務網址時,表示部署作業已完成。

為通知程式服務建立觸發條件

部署在 Knative 服務上的通知程式服務的 Eventarc 觸發條件,會針對 methodName 為 storage.objects.create 的 Cloud Storage 稽核記錄進行篩選。

  1. 建立觸發條件:

    gcloud eventarc triggers create trigger-${SERVICE_NAME}-gke \
        --destination-gke-cluster=$CLUSTER_NAME \
        --destination-gke-location=$CLUSTER_LOCATION \
        --destination-gke-namespace=default \
        --destination-gke-service=$SERVICE_NAME \
        --destination-gke-path=/ \
        --event-filters="type=google.cloud.audit.log.v1.written" \
        --event-filters="serviceName=storage.googleapis.com" \
        --event-filters="methodName=storage.objects.create" \
        --service-account=$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com

    這項操作會建立名為 trigger-notifier-gke 的觸發條件。

部署圖表建立服務

bigquery/chart-creator/python 目錄部署 Knative 服務,接收查詢執行器事件、從特定國家/地區的 BigQuery 資料表擷取資料,然後使用 Matplotlib 從資料產生圖表。圖表會上傳至 Cloud Storage bucket。

  1. 建構及推送容器映像檔:

    pushd bigquery/chart-creator/python
    export SERVICE_NAME=chart-creator
    docker build -t $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 .
    docker push $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1
    popd
  2. 將容器映像檔部署至 Knative serving,並傳遞 BUCKET

    gcloud run deploy ${SERVICE_NAME} \
        --image $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 \
        --update-env-vars BUCKET=${BUCKET}

看到服務網址時,表示部署作業已完成。

為圖表建立服務建立觸發條件

部署在 Knative 服務上的圖表建立服務的 Eventarc 觸發程序,會篩選發布至 Pub/Sub 主題的訊息。

  1. 建立觸發條件:

    gcloud eventarc triggers create trigger-${SERVICE_NAME}-gke \
        --destination-gke-cluster=$CLUSTER_NAME \
        --destination-gke-location=$CLUSTER_LOCATION \
        --destination-gke-namespace=default \
        --destination-gke-service=$SERVICE_NAME \
        --destination-gke-path=/ \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --service-account=$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com

    這項操作會建立名為 trigger-chart-creator-gke 的觸發條件。

  2. 設定 Pub/Sub 主題環境變數。

    export TOPIC_QUERY_COMPLETED=$(basename $(gcloud eventarc triggers describe trigger-${SERVICE_NAME}-gke --format='value(transport.pubsub.topic)'))

部署查詢執行器服務

processing-pipelines 目錄部署 Knative 服務,接收 Cloud Scheduler 事件、從公開的 COVID-19 資料集擷取資料,並將結果儲存至新的 BigQuery 資料表。

  1. 建構及推送容器映像檔:

    export SERVICE_NAME=query-runner
    docker build -t $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 -f Dockerfile .
    docker push $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1
  2. 將容器映像檔部署至 Knative serving,並傳遞 PROJECT_IDTOPIC_QUERY_COMPLETED

    gcloud run deploy ${SERVICE_NAME} \
        --image $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 \
        --update-env-vars PROJECT_ID=$(gcloud config get-value project),TOPIC_ID=${TOPIC_QUERY_COMPLETED}

看到服務網址時,表示部署作業已完成。

為查詢執行器服務建立觸發條件

部署在 Knative 服務上的查詢執行器服務的 Eventarc 觸發程序,會篩選發布至 Pub/Sub 主題的訊息。

  1. 建立觸發條件:

    gcloud eventarc triggers create trigger-${SERVICE_NAME}-gke \
        --destination-gke-cluster=$CLUSTER_NAME \
        --destination-gke-location=$CLUSTER_LOCATION \
        --destination-gke-namespace=default \
        --destination-gke-service=$SERVICE_NAME \
        --destination-gke-path=/ \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --service-account=$TRIGGER_GSA@$PROJECT_ID.iam.gserviceaccount.com

    這項操作會建立名為 trigger-query-runner-gke 的觸發條件。

  2. 設定 Pub/Sub 主題的環境變數。

    export TOPIC_QUERY_SCHEDULED=$(gcloud eventarc triggers describe trigger-${SERVICE_NAME}-gke --format='value(transport.pubsub.topic)')

排定工作

處理管道是由兩項 Cloud Scheduler 工作觸發。

  1. 建立 Cloud Scheduler 必須使用的 App Engine 應用程式,並指定適當的 位置 (例如 europe-west):

    export APP_ENGINE_LOCATION=LOCATION
    gcloud app create --region=${APP_ENGINE_LOCATION}
  2. 建立兩項 Cloud Scheduler 工作,每天發布至 Pub/Sub 主題一次:

    gcloud scheduler jobs create pubsub cre-scheduler-uk \
        --schedule="0 16 * * *" \
        --topic=${TOPIC_QUERY_SCHEDULED} \
        --message-body="United Kingdom"
    gcloud scheduler jobs create pubsub cre-scheduler-cy \
        --schedule="0 17 * * *" \
        --topic=${TOPIC_QUERY_SCHEDULED} \
        --message-body="Cyprus"

    排程以 Unix-Cron 格式指定。 舉例來說,0 16 * * * 表示工作每天會在世界標準時間下午 4 點執行。

執行管道

  1. 確認所有觸發條件都已建立成功:

    gcloud eventarc triggers list

    畫面會顯示如下的輸出內容:

    NAME                       TYPE                                            DESTINATION         ACTIVE  LOCATION
    trigger-chart-creator-gke  google.cloud.pubsub.topic.v1.messagePublished   GKE:chart-creator   Yes     us-central1
    trigger-notifier-gke       google.cloud.audit.log.v1.written               GKE:notifier        Yes     us-central1
    trigger-query-runner-gke   google.cloud.pubsub.topic.v1.messagePublished   GKE:query-runner    Yes     us-central1
    
  2. 擷取 Cloud Scheduler 工作 ID:

    gcloud scheduler jobs list

    畫面會顯示如下的輸出內容:

    ID                LOCATION      SCHEDULE (TZ)         TARGET_TYPE  STATE
    cre-scheduler-cy  us-central1   0 17 * * * (Etc/UTC)  Pub/Sub      ENABLED
    cre-scheduler-uk  us-central1   0 16 * * * (Etc/UTC)  Pub/Sub      ENABLED
    
  3. 雖然系統已排定工作在每天下午 4 點和 5 點執行,您也可以手動執行 Cloud Scheduler 工作:

    gcloud scheduler jobs run cre-scheduler-cy
    gcloud scheduler jobs run cre-scheduler-uk
  4. 幾分鐘後,確認 Cloud Storage bucket 中有兩張圖表:

    gcloud storage ls gs://${BUCKET}

    畫面會顯示如下的輸出內容:

    gs://PROJECT_ID-charts/chart-cyprus.png
    gs://PROJECT_ID-charts/chart-unitedkingdom.png
    

恭喜!您也會收到兩封電子郵件,內含圖表連結。