Knative 初体验:Eventing Hello World

简介: 作者 | 阿里云智能事业群高级开发工程师 元毅 基于事件驱动是Serveless的核心功能之一,通过事件驱动服务,满足了用户按需付费(Pay-as-you-go)的需求。在之前的文章中我们介绍过 Knative Eventing 由事件源、事件处理模型和事件消费 3 个主要部分构成,那么事件如何通过这 3 个组件产生、处理以及消费呢? 本文通过 Kubernetes Event Source 示例介绍一下 Knative Eventing 中如何获取事件,并且将事件传递给 Serving 进行消费。

作者 | 阿里云智能事业群高级开发工程师 元毅

基于事件驱动是Serveless的核心功能之一,通过事件驱动服务,满足了用户按需付费(Pay-as-you-go)的需求。在之前的文章中我们介绍过 Knative Eventing 由事件源、事件处理模型和事件消费 3 个主要部分构成,那么事件如何通过这 3 个组件产生、处理以及消费呢? 本文通过 Kubernetes Event Source 示例介绍一下 Knative Eventing 中如何获取事件,并且将事件传递给 Serving 进行消费。其中事件处理基于 Broker/Trigger 模型。

[]()

背景知识

先了解一下Broker/Trigger 事件处理模型。从 v0.5 开始,Knative Eventing 定义 Broker 和 Trigger 对象,从而能方便的对事件进行过滤。

  • Broker 提供一个事件集,可以通过属性选择该事件集。它负责接收事件并将其转发给由一个或多个匹配 Trigger 定义的订阅者。
  • Trigger 描述基于事件属性的过滤器。同时可以根据需要创建多个 Trigger。

Broker/Tiggger 模型流程处理如图所示:

30

[]()

前置准备

  • Knative 版本 >= 0.5
  • 安装完成 Knative Serving
  • 安装完成 Knative Eventing

[]()

操作步骤

先看一下 Kubernetes Event Source 示例处理流程,如图所示:

40

接下来介绍一下各个阶段如何进行操作处理。

[]()

创建 Service Account

ApiServerSource 创建 Service Account, 用于授权 ApiServerSource 获取 Kubernetes Events 。

serviceaccount.yaml 如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: events-sa
  namespace: default

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: event-watcher
rules:
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - get
  - list
  - watch

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: k8s-ra-event-watcher
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: event-watcher
subjects:
- kind: ServiceAccount
  name: events-sa
  namespace: default

执行如下操作:

kubectl apply --filename serviceaccount.yaml

[]()

创建 Event Source

Knative Eventing 中 通过 Event Source 对接第三方系统产生统一的事件类型。当前支持 ApiServerSource,GitHub 等多种数据源。这里我们创建一个 ApiServerSource 事件源用于接收 Kubernetes Events 事件并进行转发。k8s-events.yaml 如下:

apiVersion: sources.eventing.knative.dev/v1alpha1
kind: ApiServerSource
metadata:
  name: testevents
  namespace: default
spec:
  serviceAccountName: events-sa
  mode: Resource
  resources:
  - apiVersion: v1
    kind: Event
  sink:
    apiVersion: eventing.knative.dev/v1alpha1
    kind: Broker
    name: default

这里通过 sink 参数指定事件接收方,支持 Broker 和 k8s service。

执行命令:

kubectl apply --filename k8s-events.yaml

[]()

创建 Knative Service

首先构建你的事件处理服务,可以参考 knative-sample/event-display开源项目。

这里的 Service 服务仅把接收到的事件打印出来,处理逻辑如下:

package main
import (
    "context"
    "fmt"
    "log"
    cloudevents "github.com/cloudevents/sdk-go"
    "github.com/knative-sample/event-display/pkg/kncloudevents"
)
/*
Example Output:

  cloudevents.Event:
Validation: valid
Context Attributes,
  SpecVersion: 0.2
  Type: dev.knative.eventing.samples.heartbeat
  Source: https://github.com/knative/eventing-sources/cmd/heartbeats/#local/demo
  ID: 3d2b5a1f-10ca-437b-a374-9c49e43c02fb
  Time: 2019-03-14T21:21:29.366002Z
  ContentType: application/json
  Extensions:
    the: 42
    beats: true
    heart: yes
Transport Context,
  URI: /
  Host: localhost:8080
  Method: POST
Data
  {
    "id":162,
    "label":""
  }
*/

func display(event cloudevents.Event) {
    fmt.Printf("Hello World: \n")
    fmt.Printf("cloudevents.Event\n%s", event.String())
}

func main() {
    c, err := kncloudevents.NewDefaultClient()
    if err != nil {
        log.Fatal("Failed to create client, ", err)
    }
    log.Fatal(c.StartReceiver(context.Background(), display))
}

通过上面的代码,可以轻松构建你自己的镜像。镜像构建完成之后,接下来可以创建一个简单的 Knative Service, 用于消费 ApiServerSource 产生的事件。

service.yaml 示例如下:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: event-display
  namespace: default
spec:
  template:
    spec:
      containers:
      -  image: {yourrepo}/{yournamespace}/event-display:latest

执行命令:

kubectl apply --filename service.yaml

[]()

创建 Broker

在所选命名空间下,创建 default Broker。假如选择 default 命名空间, 执行操作如下。

kubectl label namespace default knative-eventing-injection=enabled

这里 Eventing Controller 会根据设置knative-eventing-injection=enabled 标签的 namepace, 自动创建 Broker。并且使用在webhook中默认配置的 ClusterChannelProvisioner(in-memory)。

[]()

创建 Trigger

Trigger 可以理解为 Broker 和Service 之间的过滤器,可以设置一些事件的过滤规则。这里为默认的 Broker 创建一个最简单的 Trigger,并且使用 Service 进行订阅。trigger.yaml 示例如下:

apiVersion: eventing.knative.dev/v1alpha1
kind: Trigger
metadata:
  name: testevents-trigger
  namespace: default
spec:
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1alpha1
      kind: Service
      name: event-display

执行命令:

kubectl apply --filename trigger.yaml

注意:如果没有使用默认的 Broker, 在 Trigger 中可以通过 spec.broker 指定 Broker 名称。

[]()

验证

执行如下命令,生成 k8s events。

kubectl run busybox --image=busybox --restart=Never -- ls
kubectl delete pod busybox

可以通过下述方式查看 Knative Service 是否接收到事件。

kubectl get pods
kubectl logs -l serving.knative.dev/service=event-display -c user-container

日志输出类似下面,说明已经成功接收事件。

Hello World:  
️  CloudEvent: valid 
Context Attributes,
  SpecVersion: 0.2
  Type: dev.knative.apiserver.resource.add
  Source: https://10.39.240.1:443
  ID: 716d4536-3b92-4fbb-98d9-14bfcf94683f
  Time: 2019-05-10T23:27:06.695575294Z
  ContentType: application/json
  Extensions:
    knativehistory: default-broker-b7k2p-channel-z7mqq.default.svc.cluster.local
    subject: /apis/v1/namespaces/default/events/busybox.159d7608e3a3572c
Transport Context,
  URI: /
  Host: auto-event-display.default.svc.cluster.local
  Method: POST
Data,
  {
    "apiVersion": "v1",
    "count": 1,
    "eventTime": null,
    "firstTimestamp": "2019-05-10T23:27:06Z",
    "involvedObject": {
      "apiVersion": "v1",
      "fieldPath": "spec.containers{busybox}",
      "kind": "Pod",
      "name": "busybox",
      "namespace": "default",
      "resourceVersion": "28987493",
      "uid": "1efb342a-737b-11e9-a6c5-42010a8a00ed"
    },
    "kind": "Event",
    "lastTimestamp": "2019-05-10T23:27:06Z",
    "message": "Started container",
    "metadata": {
      "creationTimestamp": "2019-05-10T23:27:06Z",
      "name": "busybox.159d7608e3a3572c",
      "namespace": "default",
      "resourceVersion": "506088",
      "selfLink": "/api/v1/namespaces/default/events/busybox.159d7608e3a3572c",
      "uid": "2005af47-737b-11e9-a6c5-42010a8a00ed"
    },
    "reason": "Started",
    "reportingComponent": "",
    "reportingInstance": "",
    "source": {
      "component": "kubelet",
      "host": "gke-knative-auto-cluster-default-pool-23c23c4f-xdj0"
    },
    "type": "Normal"
  }

[]()

总结

相信通过上面的例子你已经了解了 Knative Eventing 如何产生事件、处理事件以及消费事件。对 Eventing 中的事件处理模型也有了初步的了解。当然你可以自己定义一个事件消费服务,来处理事件。

Next

你是否已对 Knative Eventing 产生了兴趣,是否有点意犹未尽的样子? 别急,接下来我们会继续深入分析 Knative Eventing。包括:

  • 如何自定义数据源 Event Source?
  • 如何使用第三方消息服务?
  • 在遇到系统告警时,是否可以通过邮件、钉钉等发送消息?

让我们后续一起探索 Knative Eventing,欢迎持续关注。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
8月前
|
存储 测试技术 对象存储
使用容器服务ACK快速部署QwQ-32B模型并实现推理智能路由
阿里云最新发布的QwQ-32B模型,通过强化学习大幅度提升了模型推理能力。QwQ-32B模型拥有320亿参数,其性能可以与DeepSeek-R1 671B媲美。
|
存储 移动开发 JavaScript
React18组件一键转换Vue3组件(持续更新中)
其实现在Vue也是很火的框架随着Vue3的诞生,博主其实最终目标是想整合一套React+一套Vue组件库在一起的,但是重写一遍React的组件很费工作量也不现实,因为我是单人开发,于是就萌生了写一个React组件转换Vue组件的工具,功能性将逐步开发更新到博客,喜欢的可以关注一下
1124 1
React18组件一键转换Vue3组件(持续更新中)
|
Web App开发 缓存 监控
前端性能优化实战:从代码到部署的全面策略
前端性能优化实战:从代码到部署的全面策略
243 1
|
移动开发 前端开发
ruoyi-nbcio-plus基于vue3的flowable流程设计器组件的升级修改
ruoyi-nbcio-plus基于vue3的flowable流程设计器组件的升级修改
460 1
go配置镜像(阿里云、七牛)
go配置镜像(阿里云、七牛)
1231 1
|
数据挖掘 API PHP
Playfab开发(一)如何调用PlayFab接口
Playfab开发(一)如何调用PlayFab接口
|
Linux
CentOS yum源设置为国内aliyun yum源
CentOS yum源设置为国内aliyun yum源
8984 0
|
弹性计算 Kubernetes 测试技术
OpenKruise
OpenKruise 是一个开源的 Kubernetes 扩展框架,旨在提供一些高级的应用程序管理功能,以简化在 Kubernetes 上部署和管理应用程序的过程。它是由阿里巴巴开发并开源的,旨在帮助用户更轻松地实现应用程序的滚动更新、资源调整、批量任务等功能。
689 0
|
弹性计算 缓存 算法
阿里云服务器u12核4G配置通用算力ecs.u1-c1m2.large实例性能详解
阿里云服务器u1通用算力ecs.u1-c1m2.large实例2核4G配置性能详解
808 0
阿里云服务器u12核4G配置通用算力ecs.u1-c1m2.large实例性能详解