为第三方服务配置集群通知


本教程介绍如何配置第三方消息传递服务以接收 Google Kubernetes Engine (GKE) 集群通知

Slack 等服务提供传入的 webhook,这是将应用中的消息发布到 Slack 的简单方法。Cloud Functions 是一个轻量级 Compute Engine 解决方案,可用于创建单一用途的独立函数,这样无需管理服务器或运行时环境即可对 Google Cloud 事件(例如集群通知)作出响应。当 GKE 使用 Pub/Sub 发送集群通知时,触发器会通过执行操作(例如,发送 Slack 通知)来作出响应。

目前有很多使用跨应用消息传递功能构建的第三方服务,例如 IFTTT。您可以将本教程用作与这些服务建立连接的模板。

在本教程中,您将使用 Cloud Functions 和 Pub/Sub 将有关 GKE 集群事件的通知发送到 Slack。

目标

  • 部署 Slack 应用以接收来自 GKE 的外部通知。
  • 编写用于将 Pub/Sub 通知发送到 Slack 的 Cloud Functions 函数。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 GKE, Cloud Functions, Cloud Build, Eventarc and Pub/Sub API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 更新并安装 gcloud 组件:
    gcloud components update
    gcloud components install alpha beta
  8. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  9. 确保您的 Google Cloud 项目已启用结算功能

  10. 启用 GKE, Cloud Functions, Cloud Build, Eventarc and Pub/Sub API。

    启用 API

  11. 安装 Google Cloud CLI。
  12. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  13. 更新并安装 gcloud 组件:
    gcloud components update
    gcloud components install alpha beta
  14. 启用 GKE 集群通知。

所需的角色

如需获得为集群通知设置 Slack 通知所需的权限,请让管理员向您授予项目的以下 IAM 角色:

如需确保 Compute Engine 默认服务账号具有调用 Cloud Functions 函数所需的权限,请让您的管理员向 Compute Engine 默认服务账号授予以下权限:Cloud Functions 函数调用者 roles/cloudfunctions.invoker)项目的 IAM 角色。

Slack 通知

如需设置 Slack 通知,您必须创建 Slack 应用,为应用激活传入的网络钩子,并将应用安装到 Slack 工作区。

创建 Slack 应用

  1. 加入 Slack 工作区,方法是使用您的电子邮件地址注册或使用工作区管理员发送的邀请。

  2. 使用您的工作区名称和 Slack 账号凭据登录到 Slack

  3. 创建一个新的 Slack 应用

    1. 创建应用对话框中,点击从头开始
    2. 指定应用名称,然后选择您的 Slack 工作区。
    3. 点击创建应用
    4. 添加特性和功能下,点击传入的网络钩子
    5. 点击激活传入的网络钩子切换开关。
    6. 工作区的网络钩子网址部分中,点击将新网络钩子添加到工作区
    7. 在打开的授权页面上,选择一个渠道来接收通知。
    8. 点击允许
    9. Slack 应用的网络钩子显示在工作区的网络钩子网址部分中。保存网址以备后用。

编写 Cloud Functions 函数

当 GKE 将集群通知发布到 Pub/Sub 主题时,该事件会触发 Cloud Functions 以发送 Slack 通知。

  1. 创建名为 gke_slack 的新目录,并转到此目录中:

    mkdir ~/gke_slack && cd $_
    
  2. 在 gke_slack 目录中创建以下文件:

    index.js

    const functions = require('@google-cloud/functions-framework');
    const { IncomingWebhook } = require('@slack/webhook');
    
    const url = process.env.SLACK_WEBHOOK;
    
    const webhook = new IncomingWebhook(url);
    
    // Optionally filter what notification types to forward to Slack.
    // If empty, all types will be allowed.
    const allowedTypeURLs = [];
    
    // Register a CloudEvent callback with the Functions Framework that will
    // be executed when the Pub/Sub trigger topic receives a message.
    functions.cloudEvent('slackNotifier', pubSubEvent => {
        const data = decode(pubSubEvent.data.message.data);
    
        // Send message to Slack.
        if (isAllowedType(pubSubEvent.data.message.attributes)) {
            const message = createSlackMessage(data, pubSubEvent.data.message.attributes);
            webhook.send(message);
        }
    });
    
    // decode decodes a pubsub event message from base64.
    const decode = (data) => {
        return Buffer.from(data, 'base64').toString();
    }
    
    // isAllowedType can be used to filter out messages that don't match the
    // allowed type URLs. If allowedTypeURLs is empty, it allows all types.
    const isAllowedType = (attributes) => {
        if (allowedTypeURLs.length == 0) {
            return true;
        }
        for (var x in allowedTypeURLs) {
            if (attributes['type_url'] == allowedTypeURLs[x]) {
                return true;
            }
        }
        return false;
    }
    
    // createSlackMessage creates a message from a data object.
    const createSlackMessage = (data, attributes) => {
        // Write the message data and attributes.
        text = `${data}`
        for (var key in attributes) {
            if (attributes.hasOwnProperty(key)) {
                text = text + `\n\t\`${key}: ${attributes[key]}\``
            }
        }
        const message = {
            text: text,
            mrkdwn: true,
        };
        return message;
    }
    

    SLACK_WEBHOOK 是一个 Cloud Functions 环境变量,用于指定为 Slack 应用创建的网络钩子网址。您可以在部署函数时定义环境变量。

    该网络钩子会监听和接收 Cloud Functions 中的消息。当 GKE 向 Pub/Sub(事件)发送集群通知时,函数会向网络钩子网址发送消息(触发器),而网络钩子网址又会将消息发送到已配置的 Slack 工作区。

    您可以展开 createSlackMessage 函数中的消息以包含更多内容,包括文本格式和图片。isAllowedType 函数用于按类型网址启用通知的基本过滤功能。您可以在 allowedTypeURLs 中指定允许哪种类型的网址。如果您已在 GKE 或 Pub/Sub 订阅中过滤通知,则不需要此函数。

    package.json

    {
      "name": "gke-slack",
      "version": "0.0.1",
      "description": "Slack integration for GKE, using Cloud Functions",
      "main": "index.js",
      "dependencies": {
        "@slack/webhook": "6.1.0",
        "@google-cloud/functions-framework": "^3.0.0"
      }
    }
    

    package.json 描述此程序的以下特性:

    • 名称、版本和说明
    • 主要运行时文件
    • 依赖项

    您可以根据需要添加更多依赖项、要求和其他信息。

您现在应该在 gke_slack 目录中包含 index.jspackage.json 文件。

部署 Cloud Functions 函数

您可以使用 Google Cloud CLI 或 Google Cloud 控制台部署 Cloud Functions 函数。

gcloud

如需部署该函数,请在 gke_slack 目录中运行以下命令:

gcloud functions deploy slackNotifier \
  --gen2 \
  --trigger-topic=TOPIC_NAME \
  --runtime=nodejs14 \
  --entry-point=slackNotifier \
  --region=REGION \
  --source=. \
  --set-env-vars="SLACK_WEBHOOK=WEBHOOK_URL"

替换以下内容:

  • TOPIC_NAME:您在启用集群通知时创建的 Pub/Sub 主题的名称。
  • REGION:函数的 Compute Engine 区域。
  • WEBHOOK_URL:在创建 Slack 应用中为 Slack 应用创建的网络钩子网址。

输出内容类似如下:

Deploying function…
availableMemoryMb: 256
entryPoint: slackNotifier
environmentVariables:
  SLACK_WEBHOOK: https://hooks.slack.com/services/…
eventTrigger:
  eventType: google.pubsub.topic.publish
  failurePolicy: {}
  resource: projects/PROJECT_ID/topics/TOPIC_NAME
  service: pubsub.googleapis.com
labels:
  deployment-tool: cli-gcloud
name: projects/PROJECT_ID/locations/us-central1/functions/slackNotifier
runtime: nodejs10
serviceAccountEmail: PROJECT_ID@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/…
status: ACTIVE
timeout: 60s
updateTime: 'YYYY-MM-DDThh:mm:ssZ'
versionId: '1'

控制台

  1. 进入 Google Cloud 控制台中的 Cloud Functions 页面。

    转到 Cloud Functions

  2. 点击 创建函数

  3. 配置页面上,执行以下步骤:

    1. 环境下拉列表中,选择第 2 代
    2. 对于函数名称,指定 slackNotifier
    3. 对于区域,指定一个 Compute Engine 区域。
    4. 触发器部分中,点击 添加 Eventarc 触发器
    5. 在打开的窗口中,查看事件提供方下拉列表,并选择 Cloud Pub/Sub
    6. 选择您在启用集群通知时创建的 Pub/Sub 主题。
    7. 对于区域,请指定与该函数相同的 Compute Engine 区域。
    8. 点击保存触发器
    9. 展开运行时、构建、连接和安全设置部分。
    10. 运行时环境变量下,点击 添加变量
    11. 对于名称,指定 SLACK_WEBHOOK
    12. 对于,指定在创建 Slack 应用中创建的内部网络钩子的网址。
    13. 点击下一步
  4. 代码页面上,执行以下步骤:

    1. 运行时下拉列表中选择 Node.js 14
    2. 对于入口点,指定 slackNotifier
    3. 在导航窗格中,选择 index.js 并将代码替换为编写 Cloud Functions 函数中的示例代码。
    4. 在导航窗格中,选择 package.json 并将代码替换为编写 Cloud Functions 函数中的示例代码。
    5. 点击部署

完成 Cloud Functions 函数的部署后,每当 GKE 发送集群通知时,您都会收到 Slack 通知。

验证 Slack 通知

如果您使用的是 Autopilot 集群,请按如下所示验证通知:

  1. 启动控制平面升级
  2. 等待 GKE 将您的节点自动升级到新版本。升级所用时间可能会因配置的维护窗口和排除项而异。
  3. GKE 升级节点后,检查 Slack 以查看消息。

如果您使用的是 Standard 集群,请按如下所示验证通知:

  1. 将特定节点池升级到新版本。如果您不想更改节点上的 GKE 版本,则可以升级到与当前节点相同的 GKE 版本。

  2. GKE 升级节点后,检查 Slack 以查看消息。

Slack 通知类似于以下内容:

Master is upgrading to version 1.20.10-gke.301.
    cluster_location: us-central1
    cluster_name: pubsub-cluster
    payload: {"resourceType":"MASTER", "operation":"operation-1632775054313-45128f4f", "operationStartTime":"2021-09-27T20:37:34.313742491Z", "currentVersion":"1.20.9-gke.1001", "targetVersion":"1.20.10-gke.301"}
    project_id: 729788050015
    type_url: type.googleapis.com/google.container.v1beta1.UpgradeEvent

清理

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

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除各个资源

  1. 删除您在本教程中部署的 Cloud Functions 函数:

    gcloud functions delete slackNotifier
    

    您也可以通过 Google Cloud 控制台删除 Cloud Functions 函数。

  2. 删除 Pub/Sub 主题

  3. 删除 Slack 应用

后续步骤