Knative 初体验:Eventing Hello World
作者 | 阿里云智能事业群高级开发工程师 元毅
基于事件驱动是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 模型流程处理如图所示:
前置准备
- Knative 版本 >= 0.5
- 安装完成 Knative Serving
- 安装完成 Knative Eventing
操作步骤
先看一下 Kubernetes Event Source 示例处理流程,如图所示:
接下来介绍一下各个阶段如何进行操作处理。
创建 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,欢迎持续关注。
本文作者:jessie筱姜
本文为云栖社区原创内容,未经允许不得转载。
Knative 初体验:Eventing Hello World的更多相关文章
- Knative 初体验:CICD 极速入门
Knative 社区很早就在讨论用 Tekton 替换 Build 模块的相关事宜.Knative Build 官方已经正式说明不再建议使用 Knative Build 了. 如果你知道 Knativ ...
- Knative 初体验:Build Hello World
作者 | 阿里云智能事业群技术专家 冬岛 Build 模块提供了一套 Pipeline 机制.Pipeline 的每一个步骤都可以执行一个动作,这个动作可以是把源码编译成二进制.可以是编译镜像也可以是 ...
- .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
- Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
- 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
随机推荐
- webstorm 2017.3.5之后 激活
选择"license server" 输入:http://idea.codebeta.cn
- poj 1679 The Unique MST 判断最小生成树是否唯一(图论)
借用的是Kruskal的并查集,算法中的一点添加和改动. 通过判定其中有多少条可选的边,然后跟最小生成树所需边做比较,可选的边多于所选边,那么肯定方案不唯一. 如果不知道这个最小生成树的算法,还是先去 ...
- win10 基础上装一个 ubuntu 双系统
1.准备一个空闲的分区: 1)确定每个磁盘都已经是 EFI 分区格式,如果不是,可以使用分区工具,将分区都转成EFI (例如 DiskGenius 工具挺好) 2)选择一个剩余空间较大的压缩空间,压 ...
- js 禁止复制粘贴
1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键,其实是禁止快捷菜单,因为不光右键可以弹出这个菜单,键盘上空格 ...
- MySQL笔记<一>创建数据库和表
参考博客 https://www.cnblogs.com/sqbk/p/5806797.html https://www.cnblogs.com/tomasman/p/7151962.html
- 轮播图js版&jQ版
JS版轮播图 html部分和css部分自己任意定 主要构成: 1,一个固定的框 超出框的部分隐藏 2,几张图片float:left 3,下部下原点,点击切换,切换到不同的张都有红色显示 4,左右两个大 ...
- 洛谷P1968 美元汇率[2017年4月计划 动态规划02]
P1968 美元汇率 题目背景 此处省略maxint+1个数 题目描述 在以后的若干天里戴维将学习美元与德国马克的汇率.编写程序帮助戴维何时应买或卖马克或美元,使他从100美元开始,最后能获得最高可能 ...
- Leetcode566.Reshape the Matrix重塑矩阵
在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据. 给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重构的矩阵的 ...
- HR招聘_(九)_招聘方法论(面试环节·薪资谈判和心理把控)
.薪资谈判 薪资谈判在整个过程中非常重要,如果这一环出现问题前期的所有付出都功亏一篑,无法达成招聘目标. 谈判过程中需要遵循以下原则: 明确 通过面试后需要再次确认候选人的目前薪资和期望,虽然第一次电 ...
- vue学习之组件(component)(二)
自定义事件 父组件使用 prop 传递数据给子组件.但子组件怎么跟父组件通信呢?这个时候 Vue 的自定义事件系统就派得上用场了. 1. 使用 v-on 绑定自定义事件 每个vue实例都实现了事件接口 ...