This tutorial walks you through building a minimal event-driven system on ACK using Knative Eventing's Broker-Trigger model. By the end, you'll have a running event pipeline: a Broker accepts events, a Trigger routes them, and a Knative Service receives and logs them.
How it works
Knative Eventing uses the CloudEvents standard to pass events between components. In the Broker-Trigger model, events flow through three stages:
An event source sends a CloudEvent to a Broker.
The Broker evaluates each event against registered Triggers.
Each Trigger forwards matching events to its subscriber Service.
The components in the diagram are:
Event Source: The origin of events—an internal system such as a database, or an external service such as a cloud messaging service.
Ingress: The entry point that receives external events into the Knative cluster.
Channel: The backend transport layer that forwards events within the Broker. Supported options include ApsaraMQ for Kafka, NATS Streaming, and InMemoryChannel. The default is InMemoryChannel.
Broker: The event hub. It accepts events from sources and routes them to Triggers based on their configuration. Brokers support multiple backend options such as NATS and ApsaraMQ for Kafka, making event management flexible at scale.
Trigger: The routing rule. Each Trigger subscribes to a Broker, applies an optional event filter (by type, source, or other CloudEvent attributes), and forwards matching events to a subscriber Service.
Service: The event consumer. It receives routed events from Triggers and executes business logic.
Prerequisites
Before you begin, ensure that you have:
Knative Serving installed. See Deploy Knative.
Knative Eventing installed. See Deploy Knative Eventing.
Step 1: Deploy a Knative Service
Deploy event-display, a sample Knative Service that receives events and prints their contents to the log.
Create a file named
event-display.yamlwith the following content:apiVersion: serving.knative.dev/v1 kind: Service metadata: name: event-display namespace: default spec: template: spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/event-display:v1028Deploy the Knative Service:
kubectl apply -f event-display.yamlVerify the Service is ready:
kubectl get ksvcExpected output:
NAME URL LATESTCREATED LATESTREADY READY REASON event-display http://event-display.default.example.com event-display-00001 event-display-00001 True
The event-display Service is now running and ready to receive events. Next, create a Broker to accept events and a Trigger to route them to this Service.
Step 2: Create a Broker and a Trigger
The default InMemoryChannel-backed Broker is for development and testing only. Do not use it in production. For production workloads, configure a Broker backed by ApsaraMQ for Kafka or another durable channel.
Create a Broker
Create a Broker named default. Events sent to this Broker's endpoint are evaluated against all Triggers subscribed to it.
Create a file named
broker.yamlwith the following content:apiVersion: eventing.knative.dev/v1 kind: Broker metadata: name: default namespace: defaultDeploy the Broker:
kubectl apply -f broker.yamlVerify the Broker is ready:
kubectl get brokerExpected output:
NAME URL AGE READY REASON default http://broker-ingress.knative-eventing.svc.cluster.local/default/default 9s TrueThe URL in the output is the endpoint for sending events to this Broker.
The Broker is ready, but events sent to it have nowhere to go yet. A Broker is a receptacle for events—without a Trigger, no event gets forwarded anywhere. Create a Trigger to subscribe to the Broker and route events to event-display.
Create a Trigger
Create a file named
trigger.yamlwith the following content:apiVersion: eventing.knative.dev/v1 kind: Trigger metadata: name: my-service-trigger spec: broker: default subscriber: ref: apiVersion: serving.knative.dev/v1 kind: Service name: event-displayThis Trigger subscribes to the
defaultBroker without a filter, so it forwards all events toevent-display. To route only specific events, add afilterfield with CloudEvent attribute conditions—for example,type: dev.knative.samples.helloworldto match only events of that type.Deploy the Trigger:
kubectl apply -f trigger.yamlVerify the Trigger is ready:
kubectl get triggerExpected output:
NAME BROKER SUBSCRIBER_URI AGE READY REASON my-service-trigger default http://event-display.default.svc.cluster.local 22s True
The pipeline is in place. The next step sends a test event through it.
Step 3: Send an event and verify delivery
Use kubectl port-forward to expose the Broker's ingress locally, then send a CloudEvent with curl and confirm that event-display received it.
Forward the Broker ingress port to your local machine:
kubectl port-forward svc/broker-ingress -n knative-eventing 8080:80In a separate terminal, send a CloudEvent to the Broker:
curl -v "http://localhost:8080/default/default" \ -X POST \ -H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f79" \ -H "Ce-Specversion: 1.0" \ -H "Ce-Type: dev.knative.samples.helloworld" \ -H "Ce-Source: dev.knative.samples/helloworldsource" \ -H "Content-Type: application/json" \ -d '{"msg":"Hello World from the curl pod."}'A
202 Acceptedresponse confirms the Broker received the event:Note: Unnecessary use of -X or --request, POST is already inferred. * Trying 127.0.0.1:8080... * Connected to localhost (127.0.0.1) port 8080 (#0) > POST /default/default HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/8.1.2 > Accept: */* > Ce-Id: 53****3-88be-4077-9d7a-a3f162******9 > Ce-Specversion: 1.0 > Ce-Type: dev.knative.samples.helloworld > Ce-Source: dev.knative.samples/helloworldsource > Content-Type: application/json > Content-Length: 40 > < HTTP/1.1 202 Accepted < Allow: POST, OPTIONS < Date: Tue, 15 Oct 2024 09:36:42 GMT < Content-Length: 0 < * Connection #0 to host localhost left intactGet the name of the
event-displayPod:kubectl get pods --namespace=default | grep event-displayOutput:
event-display-00001-deployment-766f7b9fd6-gfcz5 2/2 Running 0 3m43sCheck the Pod logs to confirm the event was received:
kubectl logs event-display-00001-deployment-766f7b9fd6-gfcz5Expected output:
Defaulted container "user-container" out of: user-container, queue-proxy ☁️ cloudevents.Event Context Attributes, specversion: 1.0 type: dev.knative.samples.helloworld source: dev.knative.samples/helloworldsource id: 536808d3-88be-4077-9d7a-a3f162705f79 datacontenttype: application/json Extensions, knativearrivaltime: 2024-10-28T11:48:56.929517041Z Data, { "msg": "Hello World from the curl pod1." }The log shows the full CloudEvent, confirming that the Broker routed the event and
event-displayreceived it successfully.