Build Event Driven Applications on Vultr Kubernetes Engine with Knative Eventing

Introduction

Knative 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

Prerequisites

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

Install Knative Serving

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.

  • Visit the Knative Serving releases page and verify the latest version number. This article uses v1.11.0, apply the latest version components to your cluster.
  1. Install the Knative Custom Resource Definitions (CRDs) $ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.11.0/serving-crds.yaml
  2. Install the Knative core components $ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.11.0/serving-core.yaml
  3. Install the Knative Kourier controller $ kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.11.0/kourier.yaml
  4. 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"}}'
  5. Verify that the Kourier controller is available in your cluster $ kubectl --namespace kourier-system get service kourierOutput: 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 2m9sVerify that the Kourier load balancer resource has a new external IP address
  6. Verify that all Knative Serving components are ready and running $ kubectl get pods -n knative-servingOutput: 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

Install Knative Eventing

  • Visit the Knative Eventing Release page and verify the latest version. v1.11.0 is applied in this article, use the latest version to correctly install all components to your cluster.
  1. Install the Knative Eventing CRDs $ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/eventing-crds.yaml
  2. Install the latest Knative Eventing core components $ kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.11.0/eventing-core.yaml
  3. Verify that the installed Knative Eventing components are available and running in your cluster $ kubectl get pods -n knative-eventingOutput: 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
  4. 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
  5. 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
  6. Verify if the channel and broker are correctly installed and running $ kubectl get pods -n knative-eventingOutput: 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

Install the Knative CLI Tool

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.

  1. Download the latest Knative CLI realease file for Linux systems $ wget https://github.com/knative/client/releases/download/knative-v1.11.0/kn-linux-amd64When using a different operating system, visit the Knative CLI release page to download the latest build for your OS flavor.
  2. 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
  3. Grant execute permissions on the kn binary file $ sudo chmod +x /usr/local/bin/kn
  4. Verify the installed Knative CLI version $ kn versionOutput: 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

Implement Source to Sink Patterns Using Knative 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.

  1. 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.1Output: 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
  2. 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
  3. Verify that the PingSource is available $ kn source ping listOutput: NAME SCHEDULE SINK AGE CONDITIONS READY REASON knative-test-ping-source * * * * * ksvc:knative-test 17s 3 OK / 3 True
  4. View the cluster pods and verify that knative-test is available $ kubectl get podsOutput: 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
  5. View the logs of any running pod $ kubectl logs -f knative-test-00001-deployment-848b49ccb-s2thg -c user-containerYour 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

Implement Channel and Subscription Using Knative Eventing

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.

  1. Create a new channel named knative-test-channel $ kn channel create knative-test-channel
  2. Verify that the channel is available $ kn channel listOutput: NAME TYPE URL AGE READY REASON knative-test-channel InMemoryChannel http://knative-test-channel-kn-channel.default.svc.cluster.local 6s True
  3. Using a text editor such as Nano, create a new PingSource sink service file $ nano knative-test-ping-source.yaml
  4. 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-channelSave and close the fileThe above configuration defines a new PingSource resource that can receive and process the events from the Channel
  5. Apply the resource to your cluster $ kubectl apply -f knative-test-ping-source.yaml
  6. Create a new subscription file to connect the service channel to an event sink $ nano knative-test-subs.yaml
  7. 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-testSave and close the file
  8. Apply the subscription resource to your cluster $ kubectl apply -f knative-test-subs.yaml
  9. 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
  10. Verify that the sink service is available in your cluster$ kn service listOutput: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
  11. 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
  12. Verify that the subscription is available and ready to use$ kn subscription listOutput: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
  13. Verify that all Knative service pods in your cluster are running$ kubectl get podsOutput: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
  14. 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-containerWhen 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!"}
  15. 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

Implement Broker and Trigger Using Knative Eventing

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.

  1. Create a new broker named knative-test-broker to collect events $ kn broker create knative-test-broker
  2. View the new broker resource $ kn broker listOutput: 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
  3. 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
  4. 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
  5. Verify the created Triggers $ kn trigger listOutput: 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
  6. 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
  7. 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=NeverThe above command scales up the knative-test service you have defined with the condition type testing1
  8. View the list of running pods and verify that the knative-test service scales up $ kubectl get podsOutput: 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
  9. 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=NeverThe above command should now scale up the knative-test-2 service. You can verify it using the below command.
  10. View the list of running pods and verify that the knative-test-2 service scales up$ kubectl get podsOutput: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 11sThe above output confirms that the filtering mechanism of triggers is successful.

Conclusion

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. 

Introduction Knative 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…

Introduction Knative 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…

Leave a Reply

Your email address will not be published. Required fields are marked *