Sink Binding Example

A SinkBinding is responsible for linking together “addressable” Kubernetes resources that may receive events (aka the event “sink”) with Kubernetes resources that embed a PodSpec (as spec.template.spec) and want to produce events.

The SinkBinding can be used to author new event sources using any of the familiar compute abstractions that Kubernetes makes available (e.g. Deployment, Job, DaemonSet, StatefulSet), or Knative abstractions (e.g. Service, Configuration).

Create a CronJob that uses SinkBinding

Prerequisites

  1. Setup Knative Serving.
  2. Setup Knative Eventing and Sources.

Prepare the heartbeats image

Knative event-contrib has a sample of heartbeats event source. You could clone the source codes by

  1. git clone -b "{{< branch >}}" https://github.com/knative/eventing-contrib.git

And then build a heartbeats image and publish to your image repo with

  1. ko publish knative.dev/eventing-contrib/cmd/heartbeats

Note: ko publish requires:

  • KO_DOCKER_REPO to be set. (e.g. gcr.io/[gcloud-project] or docker.io/<username>)
  • you to be authenticated with your KO_DOCKER_REPO

Creating our event sink

In order to verify our SinkBinding is working, we will create an Event Display Service that dumps incoming messages to its log.

  1. apiVersion: serving.knative.dev/v1
  2. kind: Service
  3. metadata:
  4. name: event-display
  5. spec:
  6. template:
  7. spec:
  8. containers:
  9. - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display

Use following command to create the service from service.yaml:

  1. kubectl apply --filename service.yaml

The status of the created service can be seen using:

  1. kubectl get ksvc
  2. NAME URL LATESTCREATED LATESTREADY READY REASON
  3. event-display http://event-display.default.1.2.3.4.xip.io event-display-gqjbw event-display-gqjbw True

Create our SinkBinding

In order to direct events to our Event Display, we will first create a SinkBinding that will inject $K_SINK and $K_CE_OVERRIDES into select Jobs:

  1. apiVersion: sources.knative.dev/v1beta1
  2. kind: SinkBinding
  3. metadata:
  4. name: bind-heartbeat
  5. spec:
  6. subject:
  7. apiVersion: batch/v1
  8. kind: Job
  9. selector:
  10. matchLabels:
  11. app: heartbeat-cron
  12. sink:
  13. ref:
  14. apiVersion: serving.knative.dev/v1
  15. kind: Service
  16. name: event-display
  17. ceOverrides:
  18. extensions:
  19. sink: bound

In this case, we will bind any Job with the labels app: heartbeat-cron.

Use the following command to create the event source from sinkbinding.yaml:

  1. kubectl apply --filename sinkbinding.yaml

Create our CronJob

Now we will use the heartbeats container to send events to $K_SINK every time the CronJob runs:

  1. apiVersion: batch/v1
  2. kind: CronJob
  3. metadata:
  4. name: heartbeat-cron
  5. spec:
  6. # Run every minute
  7. schedule: "* * * * *"
  8. jobTemplate:
  9. metadata:
  10. labels:
  11. app: heartbeat-cron
  12. spec:
  13. template:
  14. spec:
  15. restartPolicy: Never
  16. containers:
  17. - name: single-heartbeat
  18. image: <FILL IN YOUR IMAGE HERE>
  19. args:
  20. - --period=1
  21. env:
  22. - name: ONE_SHOT
  23. value: "true"
  24. - name: POD_NAME
  25. valueFrom:
  26. fieldRef:
  27. fieldPath: metadata.name
  28. - name: POD_NAMESPACE
  29. valueFrom:
  30. fieldRef:
  31. fieldPath: metadata.namespace

First, edit heartbeats-source.yaml to include the image name from the ko publish command above, then run the following to apply it:

  1. kubectl apply --filename heartbeats-source.yaml

Verify

We will verify that the message was sent to the Knative eventing system by looking at event-display service logs.

  1. kubectl logs -l serving.knative.dev/service=event-display -c user-container --since=10m

You should see log lines showing the request headers and body of the event message sent by the heartbeats source to the display function:

  1. ☁️ cloudevents.Event
  2. Validation: valid
  3. Context Attributes,
  4. specversion: 1.0
  5. type: dev.knative.eventing.samples.heartbeat
  6. source: https://knative.dev/eventing-contrib/cmd/heartbeats/#default/heartbeat-cron-1582120020-75qrz
  7. id: 5f4122be-ac6f-4349-a94f-4bfc6eb3f687
  8. time: 2020-02-19T13:47:10.41428688Z
  9. datacontenttype: application/json
  10. Extensions,
  11. beats: true
  12. heart: yes
  13. the: 42
  14. Data,
  15. {
  16. "id": 1,
  17. "label": ""
  18. }

Using the SinkBinding with a Knative Service

SinkBinding is also compatible with our Knative Serving Cloud Events samples; as a next step try using those together. For example, the cloudevents-go sample may be bound with:

  1. apiVersion: sources.knative.dev/v1beta1
  2. kind: SinkBinding
  3. metadata:
  4. name: bind-heartbeat
  5. spec:
  6. subject:
  7. apiVersion: serving.knative.dev/v1
  8. kind: Service
  9. name: cloudevents-go
  10. sink:
  11. ref:
  12. apiVersion: serving.knative.dev/v1
  13. kind: Service
  14. name: event-display