Author: Hitesh Jethva
Last Updated: Mon, Oct 16, 2023Knative Eventing is a standalone platform that is part of the Knative framework used to simplify the deployment and management of serverless applications on Kubernetes Clusters. It offers a set of tools for routing events that allow developers to create and deploy event-driven serverless applications on Kubernetes.
Knative Eventing offers the following components that work together to enable the development of event-driven systems:
Event Source: A Kubernetes custom resource that generates events in the system and forwards them to the broker
Broker: Acts as a central hub that receives and forwards events to the appropriate event-driven workloads
Channel: Store events in-memory for high-speed, and low-latency scenarios
Trigger: Filters events based on their content and metadata. A trigger listens to specific events and starts specific actions based on the specified conditions
Subscriptions: Define how events get delivered to the event-driven application
In this article, install Knative Eventing and implement the following event patterns on a Vultr Kubernetes Engine (VKE) cluster:
Source to Sink
Channel and Subscription
Broker and Trigger
Before you begin:
Deploy a Vultr Kubernetes Engine (VKE) cluster with at least five nodes
Deploy a Ubuntu server to use as the management machine
Using SSH, access the server as a non-root user with sudo privileges
Install and Configure Kubectl on the server to access the VKE cluster
Knative Serving is a dependency resource required to run Knative Eventing. Install the necessary Knative Service components on your VKE cluster as described in the steps below.
v1.11.0
, apply the latest version components to your cluster.Install the Knative Custom Resource Definitions (CRDs)
$ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.11.0/serving-crds.yaml
Install the Knative core components
$ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.11.0/serving-core.yaml
Install the Knative Kourier controller
$ kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.11.0/kourier.yaml
Configure Knative Serving to use Kourier as the default controller
$ kubectl patch configmap/config-network --namespace knative-serving --type merge --patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
Verify that the Kourier controller is available in your cluster
$ kubectl --namespace kourier-system get service kourier
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kourier LoadBalancer 10.99.96.89 172.20.2.1 80:30491/TCP,443:30118/TCP 2m9s
Verify that the Kourier load balancer resource has a new external IP address
Verify that all Knative Serving components are ready and running
$ kubectl get pods -n knative-serving
Output:
NAME READY STATUS RESTARTS AGE
activator-5c95bd8f69-hk7vz 1/1 Running 0 117s
autoscaler-7dc9d77576-mk5lj 1/1 Running 0 115s
controller-77878dc999-7qjk7 1/1 Running 0 113s
net-kourier-controller-7bbb56bddd-25bzc 1/1 Running 0 79s
webhook-5586b8f6d7-n59j9 1/1 Running 0 109s
v1.11.0
is applied in this article, use the latest version to correctly install all components to your cluster.Install the Knative Eventing CRDs
$ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/eventing-crds.yaml
Install the latest Knative Eventing core components
$ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/eventing-core.yaml
Verify that the installed Knative Eventing components are available and running in your cluster
$ kubectl get pods -n knative-eventing
Output:
NAME READY STATUS RESTARTS AGE
eventing-controller-6cc445d8c5-wgbdd 1/1 Running 2 (3m34s ago) 3m47s
eventing-webhook-7bcc5cb885-hcjg2 1/1 Running 2 (3m31s ago) 3m44s
Install the in-memory channel to pass events
$ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/in-memory-channel.yaml
Install the broker to use available channels and run event routing
$ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/mt-channel-broker.yaml
Verify if the channel and broker are correctly installed and running
$ kubectl get pods -n knative-eventing
Output:
NAME READY STATUS RESTARTS AGE
eventing-controller-6cc445d8c5-wgbdd 1/1 Running 2 (4m54s ago) 5m7s
eventing-webhook-7bcc5cb885-hcjg2 1/1 Running 2 (4m51s ago) 5m4s
imc-controller-58b6df69f7-v4jq2 1/1 Running 1 (47s ago) 54s
imc-dispatcher-594458c69d-8nwff 1/1 Running 0 50s
mt-broker-controller-cc69ff94-6kt6n 1/1 Running 0 7s
mt-broker-filter-7c46c8cf7d-sdxfg 1/1 Running 0 12s
mt-broker-ingress-68f67cf96b-tvnwh 1/1 Running 0 10s
Knative CLI is a terminal-based tool that allows you to create resources such as Knative services and event sources without creating manifest files. This allows you to scale Knative services up and down based on your requirements within the Kubernetes cluster. Follow the steps below to install Knative CLI on your management server.
Download the latest Knative CLI realease file for Linux systems
$ wget https://github.com/knative/client/releases/download/knative-v1.11.0/kn-linux-amd64
When using a different operating system, visit the Knative CLI release page to download the latest build for your OS flavor.
Move the downloaded binary file to the /usr/local/bin/
directory to enable the kn
system-wide command
$ sudo mv kn-linux-amd64 /usr/local/bin/kn
Grant execute permissions on the kn
binary file
$ sudo chmod +x /usr/local/bin/kn
Verify the installed Knative CLI version
$ kn version
Output:
Version: v1.11.0
Build Date: 2023-07-27 07:42:56
Git Revision: b7508e67
Supported APIs:
* Serving
- serving.knative.dev/v1 (knative-serving v1.11.0)
* Eventing
In Knative eventing, source to sink is a basic pattern that represents the flow of events. Sources are the primary event producers that send events to a sink. A sink is a target of events generated by the source. It's responsible for receiving and responding to incoming events from other resources.
Knative eventing offers many types of event sources. In this section, use the PingSource to produce events with a fixed payload on a specified Cron schedule.
Using the Knative CLI, create a Knative Sink service application named knative-test
$ kn service create knative-test --concurrency-target=1 --image=quay.io/redhattraining/kbe-knative-hello:0.0.1
Output:
Creating service 'knative-test' in namespace 'default':
9.091s Configuration "knative-test" is waiting for a Revision to become ready.
9.115s Ingress has not yet been reconciled.
9.158s Waiting for load balancer to be ready
9.352s Ready to serve.
Service 'knative-test' created to latest revision 'knative-test-00001' is available at URL:
http://knative-test.default.svc.cluster.local
Create a PingSource to continuously send a JSON message Test Message!
after every 1 minute to the Knative Service sink knative-test
$ kn source ping create knative-test-ping-source --schedule "* * * * *" --data '{"message": "Test Message!"}' --sink ksvc:knative-test
Verify that the PingSource is available
$ kn source ping list
Output:
NAME SCHEDULE SINK AGE CONDITIONS READY REASON
knative-test-ping-source * * * * * ksvc:knative-test 17s 3 OK / 3 True
View the cluster pods and verify that knative-test
is available
$ kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
knative-test-00001-deployment-848b49ccb-m9plw 2/2 Running 0 34s
knative-test-00001-deployment-848b49ccb-s2thg 2/2 Running 0 34s
View the logs of any running pod
$ kubectl logs -f knative-test-00001-deployment-848b49ccb-s2thg -c user-container
Your output should look like the one below:
2023-09-15 04:18:00,112 INFO [eventing-hello] (executor-thread-1) ce-id=f75a901d-303b-4525-b4fd-7627f20a99f5
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) ce-source=/apis/v1/namespaces/default/pingsources/knative-test-ping-source
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) ce-specversion=1.0
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) ce-time=2023-09-15T04:18:00.101796919Z
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) ce-type=dev.knative.sources.ping
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) content-type=null
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) content-length=28
2023-09-15 04:18:00,113 INFO [eventing-hello] (executor-thread-1) POST:{"message": "Test Message!"}
As displayed in the above output, the JSON message sent by PingSource includes the message Test Message
you created earlier
Channel and Subscription patterns route events between channels using subscriptions. In Knative, the default In-memory Channel
channel provides an interface between the event source and the subscriber. It stores the incoming event data and distributes it to the subscribers.
A Subscription connects a Channel to the event sink (Service) and specifies how events from a channel get delivered to one or more target services. In this section, set up a sample Channel and Subscription pattern using the Knative CLI tool.
Create a new channel named knative-test-channel
$ kn channel create knative-test-channel
Verify that the channel is available
$ kn channel list
Output:
NAME TYPE URL AGE READY REASON
knative-test-channel InMemoryChannel http://knative-test-channel-kn-channel.default.svc.cluster.local 6s True
Using a text editor such as Nano, create a new PingSource sink service file
$ nano knative-test-ping-source.yaml
Add the following configurations to the file
apiVersion: sources.knative.dev/v1beta2
kind: PingSource
metadata:
name: knative-test-ping-source
spec:
schedule: "* * * * *"
data: '{"message": "Test Message!"}'
sink:
ref:
apiVersion: messaging.knative.dev/v1
kind: Channel
name: knative-test-channel
Save and close the file
The above configuration defines a new PingSource resource that can receive and process the events from the Channel
Apply the resource to your cluster
$ kubectl apply -f knative-test-ping-source.yaml
Create a new subscription file to connect the service channel to an event sink
$ nano knative-test-subs.yaml
Add the following configurations to the file
apiVersion: messaging.knative.dev/v1
kind: Subscription
metadata:
name: knative-test-subs
spec:
channel:
apiVersion: messaging.knative.dev/v1
kind: Channel
name: knative-test-channel
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: knative-test
Save and close the file
Apply the subscription resource to your cluster
$ kubectl apply -f knative-test-subs.yaml
Using the Knative CLI, create another sink service knative-test-2
to view how the channel and the subscriptions work
$ kn service create knative-test-2 --concurrency-target=1 --image=quay.io/redhattraining/kbe-knative-hello:0.0.1
Verify that the sink service is available in your cluster
$ kn service list
Output:
NAME URL LATEST AGE CONDITIONS READY REASON
knative-test http://knative-test.default.svc.cluster.local knative-test-00001 9m3s 3 OK / 3 True
knative-test-2 http://knative-test-2.default.svc.cluster.local knative-test-2-00001 33s 3 OK / 3 True
As displayed in the above output, knative-test-2
is the new sink service available in your cluster
Create another subscription knative-test-2-subs
to subscribe to the knative-test-channel
$ kn subscription create knative-test-2-subs --channel knative-test-channel --sink knative-test-2
Verify that the subscription is available and ready to use
$ kn subscription list
Output:
NAME CHANNEL SUBSCRIBER REPLY DEAD LETTER SINK READY REASON
knative-test-2-subs Channel:knative-test-channel ksvc:knative-test-2 True
knative-test-subs Channel:knative-test-channel ksvc:knative-test True
Verify that all Knative service pods in your cluster are running
$ kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
knative-test-00001-deployment-848b49ccb-bkdjb 2/2 Terminating 0 89s
knative-test-00001-deployment-848b49ccb-tn2zb 2/2 Running 0 89s
knative-test-2-00001-deployment-566d9dd859-lndqr 2/2 Running 0 29s
knative-test-2-00001-deployment-566d9dd859-mqqwj 2/2 Running 0 29s
View the logs of any pod to verify if the Channel-Subscription mechanism works
$ kubectl logs -f knative-test-2-00001-deployment-566d9dd859-mqqwj -c user-container
When the pod is running correctly, you should receive the Test Message!
JSON output as displayed in the following output:
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) ce-id=cc9c5e2c-9ec6-4e00-b03c-ddc134b6fe31
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) ce-source=/apis/v1/namespaces/default/pingsources/knative-test-ping-source
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) ce-specversion=1.0
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) ce-time=2023-09-15T04:25:00.39065862Z
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) ce-type=dev.knative.sources.ping
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) content-type=null
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) content-length=28
2023-09-15 04:25:05,405 INFO [eventing-hello] (executor-thread-1) POST:{"message": "Test Message!"}
Before applying a Broker and Trigger to your cluster, remove the ping source, channel, and subscription resources to avoid conflicts
$ kn subscription delete knative-test-subs && kn subscription delete knative-test-2-subs && kn channel delete knative-test-channel && kn source ping delete knative-test-ping-source
Broker and Trigger are event mesh
based patterns that collect a pool of events and distribute them to consumers. They offer a custom filtering mechanism to distribute events based on the trigger type.
Create a new broker named knative-test-broker
to collect events
$ kn broker create knative-test-broker
View the new broker resource
$ kn broker list
Output:
NAME URL AGE CONDITIONS READY REASON
knative-test-broker http://broker-ingress.knative-eventing.svc.cluster.local/default/knative-test-broker 18s 6 OK / 6 True
Create a Knative Trigger knative-test-trigger
that references the broker, sink and defines the condition type testing1
for incoming events
$ kn trigger create knative-test-trigger --broker=knative-test-broker --sink=ksvc:knative-test --filter=type=testing1
Create another Trigger knative-test-2-trigger
with a different condition named testing2
$ kn trigger create knative-test-2-trigger --broker=knative-test-broker --sink=ksvc:knative-test-2 --filter=type=testing2
Verify the created Triggers
$ kn trigger list
Output:
NAME BROKER SINK AGE CONDITIONS READY REASON
knative-test-2-trigger knative-test-broker ksvc:knative-test-2 11s 6 OK / 6 True
knative-test-trigger knative-test-broker ksvc:knative-test 74s 6 OK / 6 True
The knative-test
service handles events with the type testing1
, and knative-test-2
handles events with the type testing2
View the broker Kubernetes service URL to verify your broker and triggers
$ kubectl get broker knative-test-broker -o jsonpath='{.status.address.url}'
Output:
http://broker-ingress.knative-eventing.svc.cluster.local/default/knative-test-broker
Run the following command to send greetings with the type testing1
$ kubectl run greeting-requester --image quay.io/redhattraining/kbe-greeting-requester:latest --env="BROKER_URL=http://broker-ingress.knative-eventing.svc.cluster.local/default/knative-test-broker" --env="GREETING=testing1" --rm=True --attach=true --restart=Never
The above command scales up the knative-test
service you have defined with the condition type testing1
View the list of running pods and verify that the knative-test
service scales up
$ kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
knative-test-00001-deployment-848b49ccb-pb2rx 2/2 Running 0 50s
knative-test-00001-deployment-848b49ccb-s28r9 2/2 Running 0 7m12s
knative-test-2-00001-deployment-566d9dd859-5kzrb 2/2 Running 0 7m12s
Send another greeting with the type testing2
to scale up the knative-test-2
service
$ kubectl run greeting-requester --image quay.io/redhattraining/kbe-greeting-requester:latest --env="BROKER_URL=http://broker-ingress.knative-eventing.svc.cluster.local/default/knative-test-broker" --env="GREETING=testing2" --rm=True --attach=true --restart=Never
The above command should now scale up the knative-test-2
service. You can verify it using the below command.
View the list of running pods and verify that the knative-test-2
service scales up
$ kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
knative-test-2-00001-deployment-566d9dd859-2qxdx 2/2 Running 0 14s
knative-test-2-00001-deployment-566d9dd859-gktkh 2/2 Running 0 14s
knative-test-2-00001-deployment-566d9dd859-mr5vk 2/2 Running 0 11s
knative-test-2-00001-deployment-566d9dd859-n6jq5 2/2 Running 0 11s
knative-test-2-00001-deployment-566d9dd859-s97jj 2/2 Running 0 11s
The above output confirms that the filtering mechanism of triggers is successful.
You have implemented different patterns using Knative Eventing on a Vultr Kubernetes Engine (VKE) cluster. Implementing Knative Eventing on the Kubernetes cluster allows you to build scalable, and event-driven microservices. For more information to unlock the full potential of your microservices, visit the official Knative Eventing documentation.