Knative Eventing docs are a little confusing when it comes to different event delivery methods it supports. It talks about event brokers and triggers and it also talks about sources, services, channels, and subscriptions. What to use and when? It’s not clear. Let’s break it down.
Delivery methods
There are 3 distinct methods in Knative:
- Simple delivery
- Complex delivery with optional reply
- Broker and Trigger delivery
Broker and Trigger delivery is what you should care about most of the time. However, the simple and complex delivery have been in Knative for a while and still good to know for what’s happening under the covers.
Simple delivery
In simple delivery, an event source sends messages directly to a service. It’s 1:1 with no delivery guarantees at all:
Simple delivery where a Source directly sends an event to a Service
For example, here is a CronJobSource that fires events on a given cron schedule, sending messages directly to a Knative Service:
apiVersion: sources.eventing.knative.dev/v1alpha1
kind: CronJobSource
metadata:
name: source
spec:
schedule: "* * * * *"
data: '{"message": "Hello world from cron!"}'
sink:
apiVersion: serving.knative.dev/v1
kind: Service
name: service
You can see a full simple delivery example in my Knative Tutorial.
Complex delivery
Complex delivery allows delivery guarantees with channels and 1:n fanout with subscriptions.
Complex delivery with 1:n fanout
Source sends a message to a channel. It can be an in-memory channel or a more persistent channel like Kafka channel:
apiVersion: sources.eventing.knative.dev/v1alpha1
kind: CronJobSource
metadata:
name: source
spec:
schedule: "\* \* \* \* \*"
data: '{"message": "Hello world from cron!"}'
sink:
apiVersion: messaging.knative.dev/v1alpha1
kind: InMemoryChannel
name: channel
Then, services connect to the channel via subscriptions:
apiVersion: messaging.knative.dev/v1alpha1
kind: Subscription
metadata:
name: subscription1
spec:
channel:
apiVersion: messaging.knative.dev/v1alpha1
kind: InMemoryChannel
name: channel
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: service1
Complex delivery also allows a service to reply to events with other events:
Complex delivery where Service2 replies an event with another event
In this case, Service2 replies back to incoming event with another event and this gets routed to Service3 via another channel and subscription. Replies are defined as part of the subscription:
apiVersion: messaging.knative.dev/v1alpha1
kind: Subscription
metadata:
name: subscription2
spec:
channel:
apiVersion: messaging.knative.dev/v1alpha1
kind: InMemoryChannel
name: channel1
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: service2
reply:
ref:
apiVersion: messaging.knative.dev/v1alpha1
kind: InMemoryChannel
name: channel2
You can see a full complex delivery example and complex delivery with reply example in my Knative Tutorial.
Broker and Trigger delivery
Complex Delivery model works but it’s hard to maintain multiple channels, subscriptions and replies. It also does not have the concept for filtering, so services have to filter all messages themselves.
A simpler model to work with is broker and trigger. Broker combines channel, reply, and filter functionality into a single resource. Trigger provides declarative filtering of all events.
In this method, the previous example turns into this:
A broker is injected into the namespace of services and sources. Source sends events to the broker:
apiVersion: sources.eventing.knative.dev/v1alpha1
kind: CronJobSource
metadata:
name: source
spec:
schedule: "\* \* \* \* \*"
data: '{"message": "Hello world from cron!"}'
sink:
apiVersion: eventing.knative.dev/v1alpha1
kind: Broker
name: default
Broker is backed by a channel. Services register interest to a certain event type with a trigger:
apiVersion: eventing.knative.dev/v1alpha1
kind: Trigger
metadata:
name: trigger1
spec:
filter:
attributes:
type: dev.knative.cronjob.event
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: service1
Under the covers, trigger creates subscriptions. Any service can reply back to an incoming event. A reply event routed back through broker and services interested in that type event gets the event:
apiVersion: eventing.knative.dev/v1alpha1
kind: Trigger
metadata:
name: trigger3
spec:
filter:
attributes:
type: dev.knative.samples.hifromknative
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: service3
You can see a full broker and trigger delivery example in my Knative Tutorial.
As I mentioned before, you’d generally only care about Broker and Trigger in Knative Eventing but I hope this post clarifies different delivery methods and what happens under the covers.
As always, feel free to reach out to me on Twitter, if you have any questions!