Sink binding docs (reopened PR) (#3669)

* Edit sinkbinding docs

* adding attributes, need to add runtime contract

* indent

* document the env vars

* try points:

* add contract:

* More edits to sinkbinding docs

* Fix trailing whitespace

* Update titles

* Remove old sinkbinding topic

* Add context

* Update docs/eventing/sources/sinkbinding/_index.md

Co-authored-by: Ashleigh Brennan <abrennan@redhat.com>

* Update docs/eventing/sources/sinkbinding/_index.md

Co-authored-by: Ashleigh Brennan <abrennan@redhat.com>

* Update docs/eventing/sources/sinkbinding/_index.md

Co-authored-by: Ashleigh Brennan <abrennan@redhat.com>

* Apply feedback

* making mkdocs formatting changes, changing index to README.md

* Apply feedback pt 1

* Apply feedback pt 2

* Add feedback pt 3

* Modify instructions for setting inclusion mode

* Tweak

Co-authored-by: Scott Nichols <snichols@vmware.com>
Co-authored-by: Ashleigh Brennan <abrennan@redhat.com>
Co-authored-by: Omer B <obensaadon@vmware.com>
This commit is contained in:
Samia Nneji 2021-05-27 23:04:29 +01:00 committed by GitHub
parent 64555de60d
commit aba1c06d0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 490 additions and 245 deletions

View File

@ -1,244 +0,0 @@
---
title: "Sink binding"
weight: 60
type: "docs"
aliases:
- /docs/eventing/samples/sinkbinding/index
- /docs/eventing/samples/sinkbinding/README
---
# Sink binding
![version](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
The `SinkBinding` custom object supports decoupling event production from delivery addressing.
You can use sink binding to connect Kubernetes resources that embed a `PodSpec` and want to produce events, such as an event source, to an addressable Kubernetes object that can receive events, also known as an _event sink_.
Sink binding can be used to create new event sources using any of the familiar compute objects that Kubernetes makes available.
For example, `Deployment`, `Job`, `DaemonSet`, or `StatefulSet` objects, or Knative abstractions, such as `Service` or `Configuration` objects, can be used.
Sink binding injects environment variables into the `PodTemplateSpec` of the event sink, so that the application code does not need to interact directly with the Kubernetes API to locate the event destination.
Sink binding operates in one of two modes; `Inclusion` or `Exclusion`.
You can set the mode by modifying the `SINK_BINDING_SELECTION_MODE` of the `eventing-webhook` deployment accordingly. The mode determines the default scope of the webhook.
By default, the webhook is set to `exclusion` mode, which means that any namespace that does not have the label `bindings.knative.dev/exclude: true` will be subject to mutation evalutation.
If `SINK_BINDING_SELECTION_MODE` is set to `inclusion`, only the resources in a namespace labelled with `bindings.knative.dev/include: true` will be considered. In `inclusion` mode, any SinkBinding resource created will automatically label the `subject` namespace with `bindings.knative.dev/include: true` for inclusion in the potential environment variable inclusions.
## Getting started
The following procedures show how you can create a sink binding and connect it to a service and event source in your cluster.
### Creating a namespace
Create a namespace called `sinkbinding-example`:
```bash
kubectl create namespace sinkbinding-example
```
### Creating a Knative service
Create a Knative service if you do not have an existing event sink that you want to connect to the sink binding.
#### Prerequisites
- You must have Knative Serving installed on your cluster.
- Optional: If you want to use `kn` commands with sink binding, you must install the `kn` CLI.
#### Procedure
Create a Knative service:
=== "kn"
```bash
kn service create hello --image gcr.io/knative-releases/knative.dev/eventing/cmd/event_display --env RESPONSE="Hello Serverless!"
```
=== "yaml"
1. Copy the sample YAML into a `service.yaml` file:
```yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: event-display
spec:
template:
spec:
containers:
- image: gcr.io/knative-releases/knative.dev/eventing/cmd/event_display
```
2. Apply the file:
```bash
kubectl apply --filename service.yaml
```
### Creating a cron job
Create a cron job if you do not have an existing event source that you want to connect to the sink binding.
<!-- TODO: Add kn command-->
Create a `CronJob` object:
1. Copy the sample YAML into a `cronjob.yaml` file:
```yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: heartbeat-cron
spec:
# Run every minute
schedule: "*/1 * * * *"
jobTemplate:
metadata:
labels:
app: heartbeat-cron
spec:
template:
spec:
restartPolicy: Never
containers:
- name: single-heartbeat
image: gcr.io/knative-releases/knative.dev/eventing/cmd/heartbeats
args:
- --period=1
env:
- name: ONE_SHOT
value: "true"
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
```
2. Apply the file:
```bash
kubectl apply --filename heartbeats-source.yaml
```
#### Cloning a sample heartbeat cron job
Knative [event-contrib](https://github.com/knative/eventing) contains a
sample heartbeats event source.
##### Prerequisites
- Ensure that `ko publish` is set up correctly:
- [`KO_DOCKER_REPO`](https://github.com/knative/serving/blob/main/DEVELOPMENT.md#environment-setup)
must be set. For example, `gcr.io/[gcloud-project]` or `docker.io/<username>`.
- You must have authenticated with your `KO_DOCKER_REPO`.
##### Procedure
1. Clone the `event-contib` repository:
```bash
$ git clone -b "{{ branch }}" https://github.com/knative/eventing.git
```
2. Build a heartbeats image, and publish the image to your image repository:
```bash
$ ko publish knative.dev/eventing/cmd/heartbeats
```
<!-- TODO: Add tabs if there are kn commands etc to do this also-->
## Creating a SinkBinding object
Create a `SinkBinding` object that directs events from your cron job to the event sink.
### Prerequisites
- You must have Knative Eventing installed on your cluster.
- Optional: If you want to use `kn` commands with sink binding, you must install the `kn` CLI.
### Procedure
Create a sink binding:
=== "kn"
```bash
kn source binding create bind-heartbeat \
--namespace sinkbinding-example \
--subject "Job:batch/v1:app=heartbeat-cron" \
--sink http://event-display.svc.cluster.local \
--ce-override "sink=bound"
```
=== "yaml"
1. Copy the sample YAML into a `cronjob.yaml` file:
```yaml
apiVersion: sources.knative.dev/v1alpha1
kind: SinkBinding
metadata:
name: bind-heartbeat
spec:
subject:
apiVersion: batch/v1
kind: Job
selector:
matchLabels:
app: heartbeat-cron
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: event-display
```
2. Apply the file:
```bash
kubectl apply --filename heartbeats-source.yaml
```
## Verification steps
1. Verify that a message was sent to the Knative eventing system by looking at the `event-display` service logs:
```bash
kubectl logs -l serving.knative.dev/service=event-display -c user-container --since=10m
```
2. Observe the lines showing the request headers and body of the event message, sent by the heartbeats source to the display function:
```bash
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.eventing.samples.heartbeat
source: https://knative.dev/eventing/cmd/heartbeats/#default/heartbeat-cron-1582120020-75qrz
id: 5f4122be-ac6f-4349-a94f-4bfc6eb3f687
time: 2020-02-19T13:47:10.41428688Z
datacontenttype: application/json
Extensions,
beats: true
heart: yes
the: 42
Data,
{
"id": 1,
"label": ""
}
```
## Cleanup
Delete the `sinkbinding-example` namespace and all of its resources from your
cluster:
```bash
kubectl delete namespace sinkbinding-example
```

View File

@ -0,0 +1,19 @@
# SinkBinding
![API version v1](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
The SinkBinding object supports decoupling event production from
delivery addressing.
You can use sink binding to direct a subject to a sink.
A _subject_ is a Kubernetes resource that embeds a PodSpec template and produces events.
A _sink_ is an addressable Kubernetes object that can receive events.
The SinkBinding object injects environment variables into the PodTemplateSpec of the
sink. Because of this, the application code does not need to interact
directly with the Kubernetes API to locate the event destination.
These environment variables are as follows:
- `K_SINK` - The URL of the resolved sink.
- `K_CE_OVERRIDES` - A JSON object that specifies overrides to the outbound
event.

View File

@ -0,0 +1,294 @@
# Create a SinkBinding object
![API version v1](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
This topic describes how to create a SinkBinding object.
The SinkBinding resolves a sink as a URI, sets the URI in the environment
variable `K_SINK`, and adds the URI to a subject using `K_SINK`.
If the URI changes, the SinkBinding updates the value of `K_SINK`.
In the examples below, the sink is a Knative Service and the subject is a CronJob.
If you have an existing subject and sink, you can replace the examples with your
own values.
## Before you begin
Before you can create a SinkBinding object:
- You must have Knative Eventing installed on your cluster.
- Optional: If you want to use `kn` commands with SinkBinding, install the `kn` CLI.
## Optional: Choose SinkBinding namespace selection behavior
The SinkBinding object operates in one of two modes: `exclusion` or `inclusion`.
The default mode is `exclusion`.
In exclusion mode, SinkBinding behavior is enabled for the namespace by default.
To disallow a namespace from being evaluated for mutation you must exclude it
using the label `bindings.knative.dev/exclude: true`.
In inclusion mode, SinkBinding behavior is not enabled for the namespace.
Before a namespace can be evaluated for mutation, you must
explicitly include it using the label `bindings.knative.dev/include: true`.
To set the SinkBinding object to inclusion mode:
1. Change the value of `SINK_BINDING_SELECTION_MODE` from `exclusion` to `inclusion` by running:
```bash
kubectl -n knative-eventing set env deployments eventing-webhook --containers="eventing-webhook" SINK_BINDING_SELECTION_MODE=inclusion
```
2. To verify that `SINK_BINDING_SELECTION_MODE` is set as desired, run:
```bash
kubectl -n knative-eventing set env deployments eventing-webhook --containers="eventing-webhook" --list | grep SINK_BINDING
```
## Create a namespace
If you do not have an existing namespace, create a namespace for the SinkBinding:
```bash
kubectl create namespace <namespace>
```
Where `<namespace>` is the namespace that you want your SinkBinding to use.
For example, `sinkbinding-example`.
!!! note
If you have selected inclusion mode, you must add the
`bindings.knative.dev/include: true` label to the namespace to enable
SinkBinding behavior.
## Create a sink
The sink can be any addressable Kubernetes object that can receive events.
If you do not have an existing sink that you want to connect to the SinkBinding,
create a Knative service.
!!! note
To create a Knative service you must have Knative Serving installed on your cluster.
=== "kn"
Create a Knative service by running:
```bash
kn service create <app-name> --image <image-url>
```
Where:
- `<app-name>` is the name of the application.
- `<image-url>` is the URL of the image container.
For example:
```bash
$ kn service create hello --image gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
```
=== "YAML"
1. Create a Knative service by running:
```yaml
kubectl apply -f - <<EOF
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: <app-name>
spec:
template:
spec:
containers:
- image: <image-url>
EOF
```
Where:
- `<app-name>` is the name of the application. For example, `event-display`.
- `<image-url>` is the URL of the image container.
For example, `gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display`
## Create a subject
The subject must be a PodSpecable resource.
You can use any PodSpecable resource in your cluster, for example:
- `Deployment`
- `Job`
- `DaemonSet`
- `StatefulSet`
- `Service.serving.knative.dev`
If you do not have an existing PodSpecable subject that you want to use, you can
use the following sample to create a CronJob object as the subject.
The following CronJob makes a single cloud event that targets `K_SINK` and adds
any extra overrides given by `CE_OVERRIDES`.
1. Create the CronJob by running:
```yaml
kubectl apply -f - <<EOF
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: heartbeat-cron
spec:
# Run every minute
schedule: "*/1 * * * *"
jobTemplate:
metadata:
labels:
app: heartbeat-cron
spec:
template:
spec:
restartPolicy: Never
containers:
- name: single-heartbeat
image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/heartbeats
args:
- --period=1
env:
- name: ONE_SHOT
value: "true"
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
EOF
```
## Create a SinkBinding object
Create a `SinkBinding` object that directs events from your subject to the sink.
=== "kn"
Create a `SinkBinding` object by running:
```bash
kn source binding create <name> \
--namespace <namespace> \
--subject "<subject>" \
--sink <sink> \
--ce-override "<cloudevent-overrides>"
```
Where:
- `<name>` is the name of the SinkBinding object you want to create.
- `<namespace>` is the namespace you created for your SinkBinding to use.
- `<subject>` is the subject to connect. Examples:
- `Job:batch/v1:app=heartbeat-cron` matches all jobs in namespace with label `app=heartbeat-cron`.
- `Deployment:apps/v1:myapp` matches a deployment called `myapp` in the namespace.
- `Service:serving.knative.dev/v1:hello` matches the service called `hello`.
- `<sink>` is the sink to connect. For example `http://event-display.svc.cluster.local`.
- Optional: `<cloudevent-overrides>` in the form `key=value`.
Cloud Event overrides control the output format and modifications of the event
sent to the sink and are applied before sending the event.
You can provide this flag multiple times.
For example:
```bash
$ kn source binding create bind-heartbeat \
--namespace sinkbinding-example \
--subject "Job:batch/v1:app=heartbeat-cron" \
--sink http://event-display.svc.cluster.local \
--ce-override "sink=bound"
```
<!-- TODO provide link to information about the flags for the kn command -->
=== "YAML"
Create a `SinkBinding` object by running:
```yaml
kubectl apply -f - <<EOF
apiVersion: sources.knative.dev/v1alpha1
kind: SinkBinding
metadata:
name: <name>
spec:
subject:
apiVersion: <api-version>
kind: <kind>
selector:
matchLabels:
<label-key>: <label-value>
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: <sink>
EOF
```
Where:
- `<name>` is the name of the SinkBinding object you want to create. For example, `bind-heartbeat`.
- `<api-version>` is the API version of the subject. For example `batch/v1`.
- `<kind>` is the Kind of your subject. For example `Job`.
- `<label-key>: <label-value>` is a map of key-value pairs to select subjects
that have a matching label. For example, `app: heartbeat-cron` selects any subject
with the label `app=heartbeat-cron`.
- `<sink>` is the sink to connect. For example `event-display`.
For more information about the fields you can configure for the SinkBinding
object, see [Sink Binding Reference](reference.md).
## Verify the SinkBinding
1. Verify that a message was sent to the Knative eventing system by looking at the
service logs for your sink:
```bash
kubectl logs -l <sink> -c <container> --since=10m
```
Where:
- `<sink>` is the name of your sink.
- `<container>` is the name of the container your sink is running in.
For example:
```bash
$ kubectl logs -l serving.knative.dev/service=event-display -c user-container --since=10m
```
2. From the output, observe the lines showing the request headers and body of the event message,
sent by the source to the display function. For example:
```bash
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.eventing.samples.heartbeat
source: https://knative.dev/eventing-contrib/cmd/heartbeats/#default/heartbeat-cron-1582120020-75qrz
id: 5f4122be-ac6f-4349-a94f-4bfc6eb3f687
time: 2020-02-19T13:47:10.41428688Z
datacontenttype: application/json
Extensions,
beats: true
heart: yes
the: 42
Data,
{
"id": 1,
"label": ""
}
```
## Cleanup
To delete the SinkBinding and all of the related resources in the namespace,
delete the namespace by running:
```shell
kubectl delete namespace <namespace>
```
Where `<namespace>` is the name of the namespace that contains the SinkBinding object.

View File

@ -0,0 +1,171 @@
# SinkBinding Reference
This topic provides reference information about the configurable fields for the
SinkBinding object.
## SinkBinding
A `SinkBinding` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| [`apiVersion`][kubernetes-overview] | Specifies the API version, for example `sources.knative.dev/v1`. | Required |
| [`kind`][kubernetes-overview] | Identifies this resource object as a `SinkBinding` object. | Required |
| [`metadata`][kubernetes-overview] | Specifies metadata that uniquely identifies the `SinkBinding` object. For example, a `name`. | Required |
| [`spec`][kubernetes-overview] | Specifies the configuration information for this `SinkBinding` object. | Required |
| [`spec.sink`](#sink-parameter) | A reference to an object that resolves to a URI to use as the sink. | Required |
| [`spec.subject`](#subject-parameter) | A reference to the resources for which the "runtime contract" is augmented by Binding implementations. | Required |
| [`spec.ceOverrides`](#cloudevent-overrides) | Defines overrides to control the output format and modifications to the event sent to the sink. | Optional |
### Sink parameter
Sink is a reference to an object that resolves to a URI to use as the sink.
A `sink` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| `ref` | This points to an Addressable. | Required if _not_ using `uri` |
| `ref.apiVersion` | API version of the referent. | Required if using `ref` |
| [`ref.kind`][kubernetes-kinds] | Kind of the referent. | Required if using `ref` |
| [`ref.namespace`][kubernetes-namespaces] | Namespace of the referent. If omitted this defaults to the object holding it. | Optional |
| [`ref.name`][kubernetes-names] | Name of the referent. | Required if using `ref` |
| `uri` | This can be an absolute URL with a non-empty scheme and non-empty host that points to the target or a relative URI. Relative URIs are resolved using the base URI retrieved from Ref. | Required if _not_ using `ref` |
**Note:** At least one of `ref` or `uri` is required. If both are specified, `uri` is
resolved into the URL from the Addressable `ref` result.
#### Example: Sink parameter
Given the following YAML, if `ref` resolves into
`"http://mysink.default.svc.cluster.local"`, then `uri` is added to this
resulting in `"http://mysink.default.svc.cluster.local/extra/path"`.
<!-- TODO we should have a page to point to describing the ref+uri destinations and the rules we use to resolve those and reuse the page. -->
```yaml
sink:
ref:
apiVersion: v1
kind: Service
namespace: default
name: mysink
uri: /extra/path
```
**Contract:** This results in the `K_SINK` environment variable being set on the
`subject` as `"http://mysink.default.svc.cluster.local/extra/path"`.
### Subject parameter
The Subject parameter references the resources for which the "runtime contract"
is augmented by Binding implementations.
A `subject` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| `apiVersion` | API version of the referent. | Required |
| [`kind`][kubernetes-kinds] | Kind of the referent. | Required |
| [`namespace`][kubernetes-namespaces] | Namespace of the referent. If omitted, this defaults to the object holding it. | Optional |
| [`name`][kubernetes-names] | Name of the referent. | Do not use if you configure `selector`. |
| `selector` | Selector of the referents. | Do not use if you configure `name`. |
| `selector.matchExpressions` | A list of label selector requirements. The requirements are ANDed. | Use one of `matchExpressions` or `matchLabels` |
| `selector.matchExpressions.key` | The label key that the selector applies to. | Required if using `matchExpressions` |
| `selector.matchExpressions.operator` | Represents a key's relationship to a set of values. Valid operators are `In`, `NotIn`, `Exists` and `DoesNotExist`. | Required if using `matchExpressions` |
| selector.matchExpressions.values` | An array of string values. If `operator` is `In` or `NotIn`, the values array must be non-empty. If `operator` is `Exists` or `DoesNotExist`, the values array must be empty. This array is replaced during a strategic merge patch. | Required if using `matchExpressions` |
| `selector.matchLabels` | A map of key-value pairs. Each key-value pair in the `matchLabels` map is equivalent to an element of `matchExpressions`, where the key field is `matchLabels.<key>`, the `operator` is `In`, and the `values` array contains only "matchLabels.<value>". The requirements are ANDed. | Use one of `matchExpressions` or `matchLabels` |
#### Example: Subject parameter using name
Given the following YAML, the `Deployment` named `mysubject` in the `default`
namespace is selected:
```yaml
subject:
apiVersion: apps/v1
kind: Deployment
namespace: default
name: mysubject
```
#### Example: Subject parameter using matchLabels
Given the following YAML, any `Job` with the label `working=example` in the
`default` namespace is selected:
```yaml
subject:
apiVersion: batch/v1beta1
kind: Job
namespace: default
selector:
matchLabels:
working: example
```
#### Example: Subject parameter using matchExpression
Given the following YAML, any `Pod` with the label `working=example` OR
`working=sample` in the ` default` namespace is selected:
```yaml
subject:
apiVersion: v1
kind: Pod
namespace: default
selector:
- matchExpression:
key: working
operator: In
values:
- example
- sample
```
### CloudEvent Overrides
CloudEvent Overrides defines overrides to control the output format and
modifications of the event sent to the sink.
A `ceOverrides` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| `extensions` | Specifies which attributes are added or overridden on the outbound event. Each `extensions` key-value pair is set independently on the event as an attribute extension. | Optional |
**Note:** Only valid [CloudEvent attribute names][cloudevents-attribute-naming]
are allowed as extensions. You cannot set the spec defined attributes from
the extensions override configuration. For example, you can not modify the `type`
attribute.
#### Example: CloudEvent Overrides
```yaml
ceOverrides:
extensions:
extra: this is an extra attribute
additional: 42
```
**Contract:** This results in the `K_CE_OVERRIDES` environment variable being set on the
`subject` as follows:
```json
{ "extensions": { "extra": "this is an extra attribute", "additional": "42" } }
```
[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
[kubernetes-kinds]:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
[kubernetes-names]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
[kubernetes-namespaces]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
[cloudevents-attribute-naming]:
https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#attribute-naming-convention

View File

@ -139,7 +139,10 @@ nav:
- Getting started: eventing/sources/apiserversource/getting-started/README.md
- ContainerSource: eventing/sources/containersource.md
- PingSource: eventing/sources/ping-source/index.md
- Sink binding: eventing/sources/sinkbinding.md
- SinkBinding:
- Overview: eventing/sources/sinkbinding/README.md
- Create a SinkBinding object: eventing/sources/sinkbinding/getting-started.md
- SinkBinding Reference: eventing/sources/sinkbinding/reference.md
- Camel source: eventing/sources/apache-camel-source/README.md
- Creating an event source:
- Overview: eventing/sources/creating-event-sources/README.md
@ -275,6 +278,8 @@ plugins:
strict: false
- redirects:
redirect_maps:
'eventing/samples/sinkbinding/': 'eventing/sources/sinkbinding/README.md'
'eventing/sources/sinkbinding': 'eventing/sources/sinkbinding/README.md'
'install/collecting-logs/index.md': 'admin/collecting-logs/README.md'
'install/README.md': 'admin/install/README.md'
'install/collecting-metrics/index.md': 'admin/collecting-metrics/README.md'