配置 Eventarc 以触发与 GKE Autopilot 和 Pub/Sub 集成的工作流

1. 概览

在本实验中,您将创建一个 Eventarc 触发器,用于将 Pub/Sub 主题连接到 Workflows 服务。借助 Eventarc,您可以解耦服务到服务的通信,从而使解决方案更具可扩展性,并实现事件驱动型。您将创建一个包含多个步骤的工作流,以执行业务流程来计算在 Cymbal Eats 订餐的客户的奖励积分。工作流将向在 GKE Autopilot 上运行的应用发送多个请求,并向 Pub/Sub 主题发布消息,以通知订单服务应用有关计算出的奖励积分。

6c0606022b76f79d.png

什么是 GKE Autopilot?

GKE Autopilot 是 GKE 中的一种运维模式,在此模式下,Google 会管理您的集群配置,包括节点、扩缩、安全性和其他预配置的设置。Autopilot 集群经过优化,可以运行大多数生产工作负载,并可基于 Kubernetes 清单预配计算资源。此简化配置遵循集群和工作负载设置、可伸缩性以及安全性的 GKE 最佳实践和建议。如需查看内置设置的列表,请参阅 Autopilot 和 Standard 对照表

使用 GKE Standard 时,用户负责管理工作器节点和节点池配置,其余部分由 GKE 负责。

在 GKE Standard 模式下运行时的客户责任与 Google 责任

85500aad65f87437.png

使用 GKE Autopilot 时,节点池配置和管理由 Google 负责。这样,您就可以专注于在集群之上运行的应用和服务。

什么是 Eventarc?

借助 Eventarc,您可以构建事件驱动型架构,而无需实现、自定义或维护底层基础架构。Eventarc 提供了一个用于管理解耦的微服务之间的状态更改(称为“事件”)流的标准化解决方案。事件触发后,Eventarc 会通过 Pub/Sub 订阅将这些事件路由到各个目的地(例如工作流、Cloud Run),同时为您管理传送、安全、授权、可观测性和错误处理。

Google 活动提供方

  • 超过 90 个 Google Cloud 提供方。这些提供程序直接从来源(例如 Cloud Storage)发送事件,也可以通过 Cloud Audit Logs 条目发送。
  • Pub/Sub 提供程序。这些提供程序使用 Pub/Sub 消息将事件发送到 Eventarc。

第三方提供商

第三方提供方是提供 Eventarc 来源的非 Google 实体。

Eventarc 触发器

  • Cloud Pub/Sub 事件。Eventarc 可以由发布到 Pub/Sub 主题的消息触发。
  • Cloud Audit Logs (CAL) 事件。Cloud Audit Logs 会为每个云项目、文件夹和组织提供管理员活动日志和数据访问审核日志。
  • 直接事件。Eventarc 可以由各种直接事件触发,例如更新 Cloud Storage 存储分区或更新 Firebase Remote Config 模板。

活动目的地

  • Workflows
  • Cloud Run
  • GKE
  • Cloud Functions(第 2 代

c7ca054200edf1b3.png

什么是 Workflows?

Workflows 是一项全托管式服务,可让您集成微服务、任务和 API。Workflows 是一项无服务器服务,可根据您的需求进行扩缩。

工作流应用场景:

  • 事件驱动型工作流会在定义的触发器上执行。例如,当提交新订单时,您想要计算客户忠诚度积分。或者,当订单被取消时,可以发布该事件,所有感兴趣的服务都会处理该事件。
  • 批处理作业工作流使用 Cloud Scheduler 定期运行作业。例如,每晚运行一次作业,检查处于失败状态的菜单项并将其删除。

Workflows 非常适合用于编排服务的工作流。您可以自动执行包含长达一年的等待和重试过程。

Workflows 优势

  • 配置优于代码:通过将逻辑移至配置而非编写代码来减少技术债务。
  • 简化架构。有状态的工作流可让您直观呈现和监控复杂的服务集成,而无需额外的依赖项。
  • 整合可靠性和容错性。即使其他系统发生故障,也可以使用默认或自定义重试逻辑和错误处理来控制故障,通过为 Cloud Spanner 的每个步骤设置检查点,帮助您跟踪进度。
  • 零维护。按需扩缩:无需修补或维护。您只需在工作流运行时付费,等待或非活跃时无需付费。

在本实验中,您将配置一个事件驱动型工作流。

学习内容

在本实验中,您将学习如何完成以下操作:

  • 配置 Pub/Sub 主题和 Eventarc 以触发 Workflows
  • 配置工作流以向在 GKE Autopilot 上运行的应用发出 API 调用
  • 配置工作流以将消息发布到 Pub/Sub
  • 如何在 Cloud Logging 中使用 gcloud CLI 查询工作流结构化日志

前提条件

  • 本实验假设您熟悉 Cloud 控制台和 Cloud Shell 环境。
  • 具备 GKE 和 Cloud Pub/Sub 方面的经验会有所帮助,但这不是硬性要求。

2. 设置和要求

Cloud 项目设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

环境设置

点击搜索栏右侧的图标,激活 Cloud Shell。

8613854df02635a3.png

克隆代码库并导航到相应目录,将以下命令复制并粘贴到终端中,然后按 Enter 键:

git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/customer-service

运行 gke-lab-setup.sh 以部署所需的依赖项

系统将创建以下资源:

  • AlloyDB 集群和实例
  • GKE Autopilot 集群
./gke-lab-setup.sh

如果系统提示您进行授权,请点击“授权”继续。

6356559df3eccdda.png

设置过程大约需要 10 分钟。

等待脚本运行完毕并看到以下输出后,再运行其他步骤。

NAME: client-instance
ZONE: us-central1-c
MACHINE_TYPE: e2-medium
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.9
EXTERNAL_IP: 35.232.109.233
STATUS: RUNNING

3. GKE Autopilot 集群

查看 GKE Autopilot 集群

设置项目环境变量:

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')

在初始设置过程中,集群是使用以下命令创建的(您无需运行此命令):

gcloud container clusters create-auto $CLUSTER_NAME --region $REGION

运行命令以查看已创建的 GKE Autopilot 集群:

gcloud container clusters list

示例输出:

772db9dd58172e0c.png

运行命令以存储集群的凭据:

CLUSTER_NAME=rewards-cluster
REGION=us-central1

gcloud container clusters get-credentials $CLUSTER_NAME --region=$REGION

部署应用

接下来,您将部署客户服务应用。这是一个基于 Java 的微服务,使用 Quarkus 框架

前往 cymbal-eats/customer-service 文件夹,然后运行以下命令来构建和上传容器映像:

./mvnw clean package -DskipTests

export CUSTOMER_SERVICE_IMAGE=gcr.io/$PROJECT_ID/customer-service:1.0.0

gcloud builds submit --tag $CUSTOMER_SERVICE_IMAGE .

设置 AlloyDB 专用 IP 地址:

export DB_HOST=$(gcloud beta alloydb instances describe customer-instance \
    --cluster=customer-cluster \
    --region=$REGION \
    --format=json | jq \
    --raw-output ".ipAddress")

echo $DB_HOST

运行以下命令,创建 Kubernetes Secret 对象以存储客户服务应用将用于连接到数据库的数据库凭据:

DB_NAME=customers
DB_USER=postgres
DB_PASSWORD=password123

kubectl create secret generic gke-alloydb-secrets \
  --from-literal=database=$DB_NAME \
  --from-literal=username=$DB_USER \
  --from-literal=password=$DB_PASSWORD \
  --from-literal=db_host=$DB_HOST

运行命令以替换 deployment.yaml 文件中的 CUSTOMER_SERVICE_IMAGE:

sed "s@CUSTOMER_SERVICE_IMAGE@$CUSTOMER_SERVICE_IMAGE@g" deployment.yaml.tmpl > customer-service-deployment.yaml

运行命令以部署应用:

kubectl apply -f customer-service-deployment.yaml

应用需要过一段时间才能转换为 RUNNING 状态。

查看部署规范文件:

deployment.yaml.tmpl

以下是配置中用于指定运行此应用所需的资源的部分。

    spec:
      containers:
      - name: customer-service
        image: CUSTOMER_SERVICE_IMAGE
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
            ephemeral-storage: 512Mi
          limits:
            cpu: 500m
            memory: 1024Mi
            ephemeral-storage: 1Gi

运行命令以创建将在工作流中使用的外部 IP:

SERVICE_NAME=customer-service

kubectl expose deployment $SERVICE_NAME \
  --type LoadBalancer --port 80 --target-port 8080

运行命令以验证创建的资源:

kubectl get all

示例输出:

179a23bd33793924.png

4. 审核工作流程

Workflows 核心概念

工作流由使用 Workflows 语法(YAML 或 JSON)描述的一系列步骤组成。

工作流创建完毕后即会进行部署,这样工作流便可以执行。

执行是指单次运行工作流定义中包含的逻辑。尚未执行的工作流不会产生费用。所有工作流都将独立执行,并且产品的快速扩缩允许执行大量并发执行。

执行控制

  • 步骤 - 如需创建工作流,您可以使用 Workflows 语法定义所需的 steps 和执行顺序。每个工作流都必须至少有一个步骤。
  • 条件 - 您可以使用 switch 区块 作为选择机制,以允许表达式的值控制工作流的执行流。
  • 迭代 - 您可以使用 for 循环遍历一系列数字或通过列表或映射等数据集合。
  • 子工作流 - 子工作流的工作方式与编程语言的例程或函数类似,您可以封装工作流将会多次重复执行的一个步骤或一组步骤。

触发执行

  • 手动:您可以使用 Google Cloud CLI,通过 Google Cloud 控制台或命令行管理工作流。
  • 以编程方式 - Workflows API 的 Cloud 客户端库或 REST API 可用于管理工作流。
  • 已安排 - 您可以使用 Cloud Scheduler 按特定时间表运行工作流。

运行时实参

可通过在主工作流中添加 params 字段(放置在主块中)访问在运行时传递的数据。主块接受任何有效的 JSON 数据类型的单个参数。params 字段指定工作流用于存储您传入数据的变量。

工作流逻辑

如果客户不存在,工作流会先通过 API 调用创建客户,然后再更新奖励积分。工作流将根据订单总金额选择一个乘数,以计算客户的奖励积分。如需了解详情,请参阅以下示例。

    - calculate_multiplier:
        switch:
          - condition: ${totalAmount < 10}
            steps:
              - set_multiplier1:
                  assign:
                    - multiplier: 2
          - condition: ${totalAmount >= 10 and totalAmount < 25}
            steps:
              - set_multiplier2:
                  assign:
                    - multiplier: 3
          - condition: ${totalAmount >= 25}
            steps:
              - set_multiplier3:
                  assign:
                    - multiplier: 5
    - calculate_rewards:
        assign:
            - rewardPoints: ${customerRecord.rewardPoints + multiplier}

99f9cf1076c03fb6.png

5. 配置和部署工作流

运行命令以查看服务的外部 IP 地址:

kubectl get svc

示例输出:

fe5cfec2bc836a5f.png

使用上一个输出中的外部 IP 值设置以下环境变量。

CUSTOMER_SERVICE_URL=http://$(kubectl get svc customer-service -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')

替换工作流模板中的客户服务应用网址:

sed "s@CUSTOMER_SERVICE_URL@$CUSTOMER_SERVICE_URL@g" gkeRewardsWorkflow.yaml.tmpl > gkeRewardsWorkflow.yaml

为 Workflows 服务和项目环境变量设置位置:

gcloud config set workflows/location ${REGION}

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')

为工作流创建具有以下权限的自定义服务账号:

  • 调用 Logging API
  • 将消息发布到 Pub/Sub 主题
export WORKFLOW_SERVICE_ACCOUNT=workflows-sa

gcloud iam service-accounts create ${WORKFLOW_SERVICE_ACCOUNT}

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
  --role "roles/logging.logWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
  --role "roles/pubsub.publisher"

部署工作流。工作流已配置为使用在上一步中创建的服务账号:

export WORKFLOW_NAME=rewardsWorkflow

gcloud workflows deploy ${WORKFLOW_NAME} \
  --source=gkeRewardsWorkflow.yaml \
  --service-account=${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com

查看工作流来源和其他详细信息(“触发器”标签页)。目前,尚未配置任何触发器来执行此工作流。您将在下一步中进行设置。

66ba7ebbde76d5a6.png

6. 配置 Pub/Sub 主题和 Eventarc 触发器

接下来,您将创建两个 Pub/Sub 主题并配置一个 Eventarc 触发器。

订单服务应用将向 order-topic 发布有关新订单的消息。

工作流将向 order-points-topic 发布包含订单奖励积分和总金额的消息。订单服务(未部署,属于本实验的一部分)公开了一个端点,推送订阅使用该端点来更新每个订单的奖励积分和总金额。order-points-topic,

创建新的 Pub/Sub 主题:

export TOPIC_ID=order-topic
export ORDER_POINTS_TOPIC_ID=order-points-topic
gcloud pubsub topics create $TOPIC_ID --project=$PROJECT_ID
gcloud pubsub topics create $ORDER_POINTS_TOPIC_ID --project=$PROJECT_ID

为 Eventarc 服务设置位置:

gcloud config set eventarc/location ${REGION}

创建一个自定义服务账号,供 Eventarc 触发器用来执行工作流。

export TRIGGER_SERVICE_ACCOUNT=eventarc-workflow-sa

gcloud iam service-accounts create ${TRIGGER_SERVICE_ACCOUNT}

授予服务账号执行工作流的权限。

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member="serviceAccount:${TRIGGER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role="roles/workflows.invoker"

创建 Eventarc 触发器以监听 Pub/Sub 消息并将其传递给 Workflows。

gcloud eventarc triggers create new-orders-trigger \
  --destination-workflow=${WORKFLOW_NAME} \
  --destination-workflow-location=${REGION} \
  --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
  --service-account="${TRIGGER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --transport-topic=$TOPIC_ID

示例输出:

Creating trigger [new-orders-trigger] in project [qwiklabs-gcp-01-1a990bfcadb3], location [us-east1]...done.     
Publish to Pub/Sub topic [projects/qwiklabs-gcp-01-1a990bfcadb3/topics/order-topic] to receive events in Workflow [rewardsWorkflow].
WARNING: It may take up to 2 minutes for the new trigger to become active.

查看已创建的 Eventarc 触发器

bda445561ad5f4.png

查看为触发器创建的订阅

3fccdda7d5526597.png

查看工作流方面的更改。添加了新触发器。

23d338abc16eaac8.png

7. 测试工作流

6c0606022b76f79d.png

为了模拟订单服务,您将从 Cloud Shell 向 Pub/Sub 主题发送消息,并在 Cloud 控制台中验证客户服务日志。

export TOPIC_ID=order-topic

gcloud pubsub topics publish $TOPIC_ID --message '{"userId":"id1","orderNumber":123456,"name":"Angela Jensen","email":"ajensen9090+eats@gmail.com","address":"1845 Denise St","city":"Mountain View","state":"CA","zip":"94043","orderItems":[{"id":7,"createDateTime":"2022-03-17T21:51:44.968584","itemImageURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","itemName":"Curry Plate","itemPrice":12.5,"itemThumbnailURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","spiceLevel":0,"status":"Ready","tagLine":"Spicy touch for your taste buds","updateDateTime":"2022-03-18T01:30:29.340584","inventory":8,"quantity":1}]}'

示例输出:

messageIds:
- '5063709859203105'

查看工作流执行详情和日志

1e802826c700cc3e.png

57ff9705bf507fb0.png

8. 工作流结构化日志记录

工作流配置为以 JSON 格式写入结构化日志。日志使用 Cloud Logging API、workflows.googleapis.com/Workflow 资源写入,并位于日志名称 projects/${PROJECT_ID}/logs/Workflows 下。

查看下方的日志记录配置。

    - log_totalAmount:
        call: sys.log
        args:
            json:
              orderNumber: ${order.orderNumber}
              totalAmount: ${totalAmount}
              multiplier: ${multiplier}
              totalRewardPoints: ${rewardPoints}
              orderRewardPoints: ${orderRewardPoints}
            severity: INFO

在 Cloud 控制台中打开日志浏览器,然后运行查询以查找总金额超过 2 美元的已处理订单。

如需显示搜索查询字段,请点击“显示查询”。

f0a57ff3d10bad2.png

resource.type="workflows.googleapis.com/Workflow" AND 
jsonPayload.totalAmount > 2 AND 
timestamp >= "2023-01-01T00:00:00Z" AND 
timestamp <= "2024-12-31T23:59:59Z"

示例输出:

9093f87159f1b928.png

打开 Cloud Shell 并使用以下命令通过 gcloud CLI 读取日志

gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format="table(jsonPayload.orderNumber,jsonPayload.totalAmount,jsonPayload.orderRewardPoints,jsonPayload.totalRewardPoints,jsonPayload.multiplier)"

使用 table 格式的示例输出:

35d5fd851ecde60.png

运行以下命令,以 JSON 格式返回日志:

gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format=json | jq

使用 json 格式的示例输出:

ac7421548ea9a9f2.png

9. 查看客户记录

(可选步骤)

运行以下命令以设置客户服务网址环境变量。

CUSTOMER_SERVICE_URL=http://$(kubectl get svc customer-service -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')

curl $CUSTOMER_SERVICE_URL/customer | jq

示例输出:

[
  {
    "address": "1845 Denise St",
    "city": "Mountain View",
    "createDateTime": "2023-01-31T17:22:08.853644",
    "email": "ajensen9090+eats@gmail.com",
    "id": "id1",
    "name": "Angela Jensen",
    "rewardPoints": 4,
    "state": "CA",
    "updateDateTime": "2023-01-31T17:22:09.652117",
    "zip": "94043"
  }
]

多次运行命令以发布新订单,并使用 curl 命令验证客户奖励积分。

发布新订单消息:

export TOPIC_ID=order-topic
gcloud pubsub topics publish $TOPIC_ID --message '{"userId":"id1","orderNumber":123456,"name":"Angela Jensen","email":"ajensen9090+eats@gmail.com","address":"1845 Denise St","city":"Mountain View","state":"CA","zip":"94043","orderItems":[{"id":7,"createDateTime":"2022-03-17T21:51:44.968584","itemImageURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","itemName":"Curry Plate","itemPrice":12.5,"itemThumbnailURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","spiceLevel":0,"status":"Ready","tagLine":"Spicy touch for your taste buds","updateDateTime":"2022-03-18T01:30:29.340584","inventory":8,"quantity":1}]}'

验证客户奖励积分:

curl $CUSTOMER_SERVICE_URL/customer | jq

运行以下命令以检查最新日志:

gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format="table(jsonPayload.orderNumber,jsonPayload.totalAmount,jsonPayload.orderRewardPoints,jsonPayload.totalRewardPoints,jsonPayload.multiplier)"

10. 恭喜!

恭喜,您已完成此 Codelab!

所学内容:

  • 如何配置 Pub/Sub 主题和 Eventarc 以触发 Workflows
  • 如何配置工作流以向在 GKE Autopilot 上运行的应用发出 API 调用
  • 如何配置工作流以将消息发布到 Pub/Sub
  • 如何在 Cloud Logging 中使用 gcloud CLI 查询工作流结构化日志

后续步骤:

探索其他 Cymbal Eats Codelab:

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。