By Yuan Yi, Senior Development Engineer at Alibaba Cloud
Event-based driving is one of the core functions of Serverless computing. The event-driven service is ideal to meet the Pay-As-You-Go demand of users. The previous article in this series introduced three essential parts of Knative Eventing - Event Source, Event Processing Model, and Event Consumption.
Moving ahead, it is imperative to understand how events are generated, processed, and consumed through these three components. Using the Kubernetes Event Source example, this article demonstrates how to obtain events in Knative Eventing and pass them to Knative Serving for consumption. It employs the Broker/Trigger model for event processing.
First, let's take a look at the Broker/Trigger event processing model. Starting with v0.5, Knative Eventing defines the Broker and Trigger objects to facilitate easy event filtering.
The process of Broker/Trigger model is as shown in the following figure.
Following is the list of requirements to implement the model:
To begin with, let's look at the process of the Kubernetes Event Source sample, as shown in the following figure.
Next, let's see how to process operations at various stages.
Create a service account for ApiServerSource
. This account authorizes ApiServerSource to obtain Kubernetes events.
The serviceaccount.yaml
is as follows.
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
Perform the following operations.
kubectl apply --filename serviceaccount.yaml
In Knative Eventing, a unified event type is generated by connecting the event source to a third-party system. Currently, multiple data sources, such as ApiServerSource and GitHub, are supported. Here, let's create an ApiServerSource event source to receive and forward Kubernetes events. The k8s-events.yaml
is as follows.
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
The "sink" parameter is used here to specify the event receiver. The Broker and K8S services are supported.
Run the following command.
kubectl apply --filename k8s-events.yaml
First, create an event processing service.
Here, the service only prints the received events. The following snippet shows the processing logic.
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))
}
With the above code, easily build your own image. After the image is built, create a simple Knative service to consume events generated by ApiServerSource.
The service.yaml
example is shown below.
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: event-display
namespace: default
spec:
template:
spec:
containers:
- image: {yourrepo}/{yournamespace}/event-display:latest
Run the following command.
kubectl apply --filename service.yaml
Under the selected namespace, create the default
Broker. If you select the default
namespace, perform the following operations.
kubectl label namespace default knative-eventing-injection=enabled
Here, the Eventing Controller automatically creates a Broker based on the namespace that sets the knative-eventing-injection=enabled
tag. In addition, the default ClusterChannelProvisioner (in-memory) configured by default in the Web hook is used.
A Trigger works as a filter between the Broker and the Service. Set some filtering rules for events.
Now, let's create a simple Trigger for the default Broker, and use the Service for the subscription. The trigger.yaml
example is given below.
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
Run the following command.
kubectl apply --filename trigger.yaml
Note: If the default Broker is not used, specify the Broker name in the Trigger through spec.broker
.
Run the following command to generate a K8S event.
kubectl run busybox --image=busybox --restart=Never -- ls
kubectl delete pod busybox
Now, execute the following command to check whether the Knative service receives the event.
kubectl get pods
kubectl logs -l serving.knative.dev/service=event-display -c user-container
The log output is similar to the following and indicates that the event is successfully received.
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"
}
The above examples show how Knative Eventing generates, handles and consumes events. These illustrations also provide a preliminary understanding of the event handling model in Eventing. This article serves as the reference to define an event consumer service for handling events.
If you are you interested in Knative Eventing and want to know more, then stay tuned to Alibaba Cloud's Blog Channel as we continue our in-depth analysis of Knative Eventing. Upcoming articles include:
Stay tuned to explore Knative Eventing.
How to Monitor and Autoscale Cloud Native Applications in Kubernetes
507 posts | 48 followers
FollowAlibaba Container Service - July 22, 2021
Alibaba Developer - March 3, 2020
Alibaba Container Service - July 19, 2021
Alibaba Developer - September 7, 2020
Alibaba Container Service - February 7, 2020
Alibaba Container Service - March 16, 2020
507 posts | 48 followers
FollowAccelerate and secure the development, deployment, and management of containerized applications cost-effectively.
Learn MoreAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreEventBridge is a serverless event bus service that connects to Alibaba Cloud services, custom applications, and SaaS applications as a centralized hub.
Learn MoreAlibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.
Learn MoreMore Posts by Alibaba Cloud Native Community