本教程介绍如何使用 Eventarc 构建处理流水线,该流水线安排对公共 BigQuery 数据集的查询,根据数据生成图表,并通过电子邮件分享图表链接。
目标
在本教程中,您将构建和部署三项在 GKE 集群中运行并使用 Eventarc 接收事件的 Google Kubernetes Engine (GKE) 服务:
- Query Runner - 当 Cloud Scheduler 作业向 Pub/Sub 主题发布消息时触发,此服务使用 BigQuery API 从公共 COVID-19 数据集中检索数据,并将结果保存到新的 BigQuery 表中。
- Chart Creator - 在 Query Runner 服务向 Pub/Sub 主题发布消息时触发,此服务使用 Python 绘图库 Matplotlib 生成图表,并将图表保存到 Cloud Storage 存储桶。
- 通知程序 - 当图表创建程序服务将图表存储在 Cloud Storage 存储桶中时,由审核日志触发;此服务使用电子邮件服务 SendGrid 将图表的链接发送到某个电子邮件地址。
下图展示了高级别的基础架构:
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
- Artifact Registry
- BigQuery
- Cloud Build
- Cloud Scheduler
- Cloud Storage
- Eventarc
- Google Kubernetes Engine
- Pub/Sub
如需根据您的预计使用量来估算费用,请使用价格计算器。
准备工作
-
安装 Google Cloud CLI。
-
配置 gcloud CLI 以使用您的联合身份。
如需了解详情,请参阅 使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init -
选择或创建项目所需的角色
- 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
-
创建项目:如需创建项目,您需要拥有 Project Creator 角色 (
roles/resourcemanager.projectCreator),该角色包含resourcemanager.projects.create权限。了解如何授予角色。
-
创建 Google Cloud 项目:
gcloud projects create PROJECT_ID
将
PROJECT_ID替换为您要创建的 Google Cloud 项目的名称。 -
选择您创建的 Google Cloud 项目:
gcloud config set project PROJECT_ID
将
PROJECT_ID替换为您的 Google Cloud 项目名称。
启用 Artifact Registry API、BigQuery API、Cloud Build API、Cloud Logging API、Cloud Scheduler API、Eventarc API、GKE API、Pub/Sub API 和 Resource Manager API(如果尚未启用):
启用 API 所需的角色
如需启用 API,您需要拥有
serviceusage.services.enable权限。如果您创建了项目,则可能已经通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色。gcloud services enable artifactregistry.googleapis.com
bigquery.googleapis.com cloudbuild.googleapis.com cloudresourcemanager.googleapis.com cloudscheduler.googleapis.com container.googleapis.com eventarc.googleapis.com pubsub.googleapis.com logging.googleapis.com - 对于 Cloud Storage,为
ADMIN_READ、DATA_WRITE和DATA_READ数据访问类型启用审核日志记录。- 读取与您的 Google Cloud 项目、文件夹或组织关联的 Identity and Access Management (IAM) 政策,并将其存储在临时文件中:
gcloud projects get-iam-policy PROJECT_ID > /tmp/policy.yaml
- 在文本编辑器中,打开
/tmp/policy.yaml,然后仅在auditConfigs部分中添加或更改审核日志配置:auditConfigs: - auditLogConfigs: - logType: ADMIN_READ - logType: DATA_WRITE - logType: DATA_READ service: storage.googleapis.com bindings: - members: [...] etag: BwW_bHKTV5U= version: 1
- 写入新的 IAM 政策:
gcloud projects set-iam-policy PROJECT_ID /tmp/policy.yaml
如果上述命令报告与其他更改发生冲突,请重复以上步骤(从读取 IAM 政策开始)。如需了解详情,请参阅使用 API 配置数据访问审核日志。
- 读取与您的 Google Cloud 项目、文件夹或组织关联的 Identity and Access Management (IAM) 政策,并将其存储在临时文件中:
- 设置本教程中使用的默认值:
CLUSTER_NAME=events-cluster CLUSTER_LOCATION=us-central1 PROJECT_ID=PROJECT_ID gcloud config set project $PROJECT_ID gcloud config set eventarc/location $CLUSTER_LOCATION
将
PROJECT_ID替换为您的项目 ID。
创建 SendGrid API 密钥
SendGrid 是云端电子邮件服务提供商,让您无需维护电子邮件服务器即可发送电子邮件。
- 登录到 SendGrid 并转到 Settings > API 密钥。
- 点击创建 API 密钥。
- 为该密钥选择权限。该密钥必须至少具有 Mail Send 权限才能发送电子邮件。
- 点击保存以创建密钥。
- SendGrid 会生成一个新的密钥。这是该密钥的唯一副本,因此请务必复制并保存该密钥以供日后使用。
创建 GKE 集群
创建一个启用了 Workload Identity Federation for GKE 的集群,以便它可以从 GKE 中运行的应用访问 Google Cloud 服务。使用 Eventarc 转发事件也需要 Workload Identity Federation for GKE。
创建启用了
HttpLoadBalancing和HorizontalPodAutoscaling插件的 GKE 集群:gcloud container clusters create $CLUSTER_NAME \ --addons=HttpLoadBalancing,HorizontalPodAutoscaling \ --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 \ --region=$CLUSTER_LOCATION \ --release-channel=rapid \ --workload-pool=$PROJECT_ID.等待几分钟,让创建集群的过程完成。在该过程中,您可能会看到一些可以放心忽略的警告。创建集群后,输出类似于以下内容:
Creating cluster ...done. Created [https://container.googleapis.com/v1/projects/my-project/zones/us-central1/clusters/events-cluster].
使用凭据和端点信息更新
kubeconfig文件,以将kubectl指向 GKE 集群:gcloud container clusters get-credentials $CLUSTER_NAME \ --region=$CLUSTER_LOCATION
创建 Artifact Registry 标准制品库以存储您的 Docker 容器映像:
gcloud artifacts repositories create REPOSITORY \ --repository-format=docker \ --location=$CLUSTER_LOCATION
将
REPOSITORY替换为制品库的唯一名称。
配置服务账号
如需允许 GKE 节点从 Artifact Registry 拉取容器映像,请向集群节点使用的 Compute Engine 默认服务账号授予项目的 Artifact Registry Reader (
roles/artifactregistry.reader) 角色:PROJECT_NUMBER="$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:$PROJECT_NUMBER-compute@" \ --condition=None \ --role "roles/artifactregistry.reader"
为了允许 GKE 服务查询和写入 BigQuery、发布到 Pub/Sub 以及将图表上传到 Cloud Storage,请向
default命名空间中的defaultKubernetes ServiceAccount 授予项目的 BigQuery Data Editor (roles/bigquery.dataEditor)、BigQuery Job User (roles/bigquery.jobUser)、Pub/Sub Publisher (roles/pubsub.publisher) 和 Storage Object Admin (roles/storage.objectAdmin) 角色:gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID./subject/ns/default/sa/default" \ --condition=None \ --role "roles/bigquery.dataEditor" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID./subject/ns/default/sa/default" \ --condition=None \ --role "roles/bigquery.jobUser" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID./subject/ns/default/sa/default" \ --condition=None \ --role "roles/pubsub.publisher" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID./subject/ns/default/sa/default" \ --condition=None \ --role "roles/storage.objectAdmin"
启用 GKE 目标
如需允许 Eventarc 管理 GKE 集群中的资源,请启用 GKE 目标,并将 Eventarc 服务账号绑定到所需的角色。
为 Eventarc 启用 GKE 目标:
gcloud eventarc gke-destinations init
在系统提示绑定所需角色时,输入
y。绑定以下角色:
roles/compute.viewerroles/container.developerroles/iam.serviceAccountAdmin
创建 Cloud Storage 存储桶
在 GKE 服务所在的同一区域中创建一个 Cloud Storage 存储桶以保存图表,并授予您的账号读取权限 (roles/storage.objectViewer),以便查看生成的图表:
export BUCKET="$(gcloud config get-value core/project)-charts" gcloud storage buckets create gs://${BUCKET} --location=$CLUSTER_LOCATION gcloud storage buckets update gs://${BUCKET} --uniform-bucket-level-access gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \ --member="user:$(gcloud config get-value core/account)" \ --role=roles/storage.objectViewer
克隆存储库
克隆 GitHub 代码库。
git clone https://github.com/GoogleCloudPlatform/eventarc-samples cd eventarc-samples/processing-pipelines
创建服务账号并绑定访问角色
在创建 Eventarc 触发器之前,请先设置用户管理的服务账号,并为其授予特定的角色,以便 Eventarc 可以转发 Pub/Sub 事件。
创建名为
eventarc-triggers-test-sa的服务账号:TRIGGER_GSA=eventarc-triggers-test-sa gcloud iam service-accounts create $TRIGGER_GSA
向该服务账号授予
pubsub.subscriber、monitoring.metricWriter和eventarc.eventReceiver角色:PROJECT_ID=$(gcloud config get-value project) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID." \ --condition=None \ --role "roles/pubsub.subscriber" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID." \ --condition=None \ --role "roles/monitoring.metricWriter" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:$TRIGGER_GSA@$PROJECT_ID." \ --condition=None \ --role "roles/eventarc.eventReceiver"
部署通知程序服务
在 bigquery/notifier/python 目录中,部署一项 GKE 服务,用于接收图表创建程序事件并使用 SendGrid 通过电子邮件发送所生成图表的链接。
构建并推送容器映像:
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
为容器映像创建 Kubernetes 部署,并设置所需的环境变量,包括电子邮件发送到的地址以及 SendGrid API 密钥:
export TO_EMAILS=EMAIL_ADDRESS export SENDGRID_API_KEY=YOUR_SENDGRID_API_KEY kubectl create deployment ${SERVICE_NAME} \ --image=$CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 kubectl set env deployment/${SERVICE_NAME} \ TO_EMAILS=${TO_EMAILS} \ SENDGRID_API_KEY=${SENDGRID_API_KEY} \ BUCKET=${BUCKET}
替换以下内容:
EMAIL_ADDRESS:所生成图表的链接发送到的电子邮件地址YOUR_SENDGRID_API_KEY:您之前记下的 SendGrid API 密钥REPOSITORY:您的 Artifact Registry 代码库的名称
将部署公开为 Kubernetes Service:
kubectl expose deployment ${SERVICE_NAME} \ --type=ClusterIP --port=80 --target-port=8080
为通知程序服务创建触发器
为部署在 GKE 上的通知程序服务创建 Eventarc 触发器,该触发器会过滤指定 Cloud Storage 存储桶的 Cloud Storage 审核日志,其中 methodName 为 storage.objects.create:
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" \ --event-filters-path-pattern="resourceName=/projects/_/buckets/$BUCKET/objects/*" \ --service-account=$TRIGGER_GSA@$PROJECT_ID.
这将创建一个名为 trigger-notifier-gke 的触发器。
部署图表创建程序服务
在 bigquery/chart-creator/python 目录中,部署一项 GKE 服务,用于接收查询运行程序事件,从 BigQuery 表中检索特定国家/地区的数据,然后使用 Matplotlib 根据数据生成图表。图表将上传到 Cloud Storage 存储桶。
构建并推送容器映像:
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
为容器映像创建 Kubernetes 部署,并设置
BUCKET环境变量:kubectl create deployment ${SERVICE_NAME} \ --image=$CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 kubectl set env deployment/${SERVICE_NAME} \ BUCKET=${BUCKET}
将部署公开为 Kubernetes 服务:
kubectl expose deployment ${SERVICE_NAME} \ --type=ClusterIP --port=80 --target-port=8080
为图表创建程序服务创建触发器
为部署在 GKE 上的图表创建程序服务创建 Eventarc 触发器,用于过滤发布到某个 Pub/Sub 主题的消息。
创建触发器:
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.
这将创建一个名为
trigger-chart-creator-gke的触发器。设置 Pub/Sub 主题环境变量。
export TOPIC_QUERY_COMPLETED=$(basename $(gcloud eventarc triggers describe trigger-${SERVICE_NAME}-gke --format='value(transport.pubsub.topic)'))
部署查询运行程序服务
在 processing-pipelines 目录中,部署一项 GKE 服务,用于接收 Cloud Scheduler 事件,从公共 COVID-19 数据集中检索数据,并将结果保存在新的 BigQuery 表中。
构建并推送容器映像:
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
为容器映像创建 Kubernetes 部署,并设置
PROJECT_ID和TOPIC_ID环境变量:kubectl create deployment ${SERVICE_NAME} \ --image=$CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/${SERVICE_NAME}:v1 kubectl set env deployment/${SERVICE_NAME} \ PROJECT_ID=$(gcloud config get-value project) \ TOPIC_ID=${TOPIC_QUERY_COMPLETED}
将部署公开为 Kubernetes Service:
kubectl expose deployment ${SERVICE_NAME} \ --type=ClusterIP --port=80 --target-port=8080
为查询运行程序服务创建触发器
为部署在 GKE 上的查询运行程序服务创建一个 Eventarc 触发器,该触发器可过滤发布到某个 Pub/Sub 主题的消息。
创建触发器:
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.
这将创建一个名为
trigger-query-runner-gke的触发器。为 Pub/Sub 主题设置环境变量。
export TOPIC_QUERY_SCHEDULED=$(basename $(gcloud eventarc triggers describe trigger-${SERVICE_NAME}-gke --format='value(transport.pubsub.topic)'))
安排作业
处理流水线由两个 Cloud Scheduler 作业触发。 创建两个 Cloud Scheduler 作业,这些作业每天发布到 Pub/Sub 主题一次:
gcloud scheduler jobs create pubsub cre-scheduler-uk \ --location=$CLUSTER_LOCATION \ --schedule="0 16 * * *" \ --topic=${TOPIC_QUERY_SCHEDULED} \ --message-body="United Kingdom"
gcloud scheduler jobs create pubsub cre-scheduler-cy \ --location=$CLUSTER_LOCATION \ --schedule="0 17 * * *" \ --topic=${TOPIC_QUERY_SCHEDULED} \ --message-body="Cyprus"
时间表以 unix-cron 格式指定。例如,0 16 * * * 表示作业在世界协调时间 (UTC) 每天 16:00(下午 4 点)运行。
运行流水线
确认所有触发器已成功创建:
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检索 Cloud Scheduler 作业 ID:
gcloud scheduler jobs list --location=$CLUSTER_LOCATION
输出应类似如下所示:
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这些作业安排在每天下午 4 点和 5 点运行,但您也可以手动运行 Cloud Scheduler 作业:
gcloud scheduler jobs run cre-scheduler-cy --location=$CLUSTER_LOCATION
gcloud scheduler jobs run cre-scheduler-uk --location=$CLUSTER_LOCATION
几分钟后,确认 Cloud Storage 存储桶中有两个图表:
gcloud storage ls gs://${BUCKET}
输出应类似如下所示:
gs://PROJECT_ID-charts/chart-cyprus.png gs://PROJECT_ID-charts/chart-unitedkingdom.png
恭喜!您应该还会收到两封电子邮件,其中包含图表链接。
清理
如果您为本教程创建了一个新项目,请删除项目。如果您使用的是现有项目,希望保留此项目且不保留本教程中添加的任何更改,请删除为教程创建的资源。
删除 Google Cloud 项目:
gcloud projects delete PROJECT_ID
删除教程资源
删除您在本教程中部署的 Kubernetes 服务和部署,并删除 GKE 集群:
kubectl delete service notifier chart-creator query-runner kubectl delete deployment notifier chart-creator query-runner gcloud container clusters delete $CLUSTER_NAME --region=$CLUSTER_LOCATION
删除您在本教程中创建的所有 Eventarc 触发器:
gcloud eventarc triggers delete TRIGGER_NAME
将
TRIGGER_NAME替换为您的触发器的名称。从 Artifact Registry 中删除映像:
gcloud artifacts docker images delete $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/notifier:v1 gcloud artifacts docker images delete $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/chart-creator:v1 gcloud artifacts docker images delete $CLUSTER_LOCATION-docker.pkg.dev/$(gcloud config get-value project)/REPOSITORY/query-runner:v1
删除 Artifact Registry 代码库:
gcloud artifacts repositories delete REPOSITORY \ --location=$CLUSTER_LOCATION
删除存储桶以及存储桶中的所有对象:
gcloud storage rm --recursive gs://${BUCKET}/删除 Cloud Scheduler 作业:
gcloud scheduler jobs delete cre-scheduler-cy --location=$CLUSTER_LOCATION gcloud scheduler jobs delete cre-scheduler-uk --location=$CLUSTER_LOCATION
移除您在教程设置过程中添加的任何 Google Cloud CLI 默认配置:
gcloud config unset project gcloud config unset eventarc/location