Apiserversource docs (#3812)

* Style tweaks for apiserversource

* Add reference for apiserversource

* Add reference page to mkdocs.yml

* Adding back because this PR should not touch containersource

* Apply suggestions from code review

Co-authored-by: Ali Ok <aliok@redhat.com>

* Apply feedback from review part 1

* Define PodSpecable and other tweaks

* Fix whitespace

Co-authored-by: Ali Ok <aliok@redhat.com>
This commit is contained in:
Samia Nneji 2021-06-29 16:37:17 +01:00 committed by GitHub
parent 95b571e21e
commit 661627c335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 486 additions and 240 deletions

View File

@ -1,15 +1,7 @@
--- # ApiServerSource
title: "API server source"
weight: 01
type: "docs"
aliases:
- /docs/eventing/sources/apiserversource
---
# API server source
![version](https://img.shields.io/badge/API_Version-v1-red?style=flat-square) ![version](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
The API server source is a Knative Eventing Kubernetes custom resource that listens for Kubernetes events and forwards received events to a sink. The API server source is a Knative Eventing Kubernetes custom resource that listens for Kubernetes events and forwards received events to a sink.
The API server source is part of the core Knative Eventing component, and is provided by default when Knative Eventing is installed. Multiple instances of an APIServerSource object can be created by users. The API server source is part of the core Knative Eventing component, and is provided by default when Knative Eventing is installed. Multiple instances of an ApiServerSource object can be created by users.

View File

@ -0,0 +1,236 @@
# Creating an ApiServerSource object
![version](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
This topic describes how to create an ApiServerSource object.
## Before you begin
Before you can create an ApiServerSource object:
- You must have [Knative Eventing](../../../../../admin/install/eventing/install-eventing-with-yaml)
installed on your cluster.
- You must install the [`kubectl` CLI](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
tool.
- Optional: If you want to use the `kn` commands, install the [`kn`](../../../../../client/install-kn/) tool.
## Create an ApiServerSource object
1. Optional: Create a namespace for the API server source instance by running the
command:
```bash
kubectl create namespace <namespace>
```
Where `<namespace>` is the name of the namespace that you want to create.
!!! note
Creating a namespace for your ApiServerSource and related components
allows you to view changes and events for this workflow more easily, since
these are isolated from the many other components that may exist in your `default` namespace.<br><br>
It also makes removing the source easier, since you can simply delete the namespace to remove all of the resources.
1. Create a ServiceAccount by running the command:
```yaml
kubectl create -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: <service-account>
namespace: <namespace>
EOF
```
Where:
- `<service-account>` is the name of the ServiceAccount that you want to create.
- `<namespace>` is the namespace that you created in step 1 above.
1. Create a ClusterRole by running the command:
```yaml
kubectl create -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <cluster-role>
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- get
- list
- watch
EOF
```
Where `<cluster-role>` is the name of the ClusterRole that you want to create.
1. Create a ClusterRoleBinding by running the command:
```yaml
kubectl create -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <cluster-role-binding>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: <cluster-role>
subjects:
- kind: ServiceAccount
name: <service-account>
namespace: <namespace>
EOF
```
Where:
- `<cluster-role-binding>` is the name of the ClusterRoleBinding that you want to create.
- `<cluster-role>` is the name of the ClusterRole that you created in step 3 above.
- `<service-account>` is the name of the ServiceAccount that you created in step 2 above.
- `<namespace>` is the name of the namespace that you created in step 1 above.
1. Create the ApiServerSource object by running the command:
=== "kn"
```bash
kn source apiserver create <apiserversource> \
--namespace <namespace> \
--mode "Resource" \
--resource "Event:v1" \
--service-account <service-account> \
--sink <sink>
```
Where:
- `<apiserversource>` is the name of the source that you want to create.
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<service-account>` is the name of the ServiceAccount that you created in step 2 above.
- `<sink>` is the name of the PodSpecable object that you want to use as a sink.
A PodSpecable is an object that describes a PodSpec.
=== "YAML"
```yaml
kubectl create -f - <<EOF
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
serviceAccountName: <service-account>
mode: <event-mode>
resources:
- apiVersion: v1
kind: Event
sink:
ref:
apiVersion: v1
kind: <sink-kind>
name: <sink-name>
EOF
```
Where:
- `<apiserversource>` is the name of the source that you want to create.
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<service-account>` is the name of the ServiceAccount that you created in step 2 above.
- `<event-mode>` is either `Resource` or `Reference`. If set to `Resource`, the event payload contains the entire resource that the event is for. If set to `Reference`, the event payload only contains a reference to the resource that the event is for. The default is `Reference`.
- `<sink-kind>` is any supported PodSpecable object that you want to use as a sink, for example, `Service` or `Deployment`. A PodSpecable is an object that describes a PodSpec.
- `<sink-name>` is the name of your sink.
## Verify the ApiServerSource object
1. Make the Kubernetes API server create events by launching a test pod in your namespace by running the command:
```bash
kubectl run busybox --image=busybox --namespace=<namespace> --restart=Never -- ls
```
Where `<namespace>` is the name of the namespace that you created in step 1 above.
1. Delete the test pod by running the command:
```bash
kubectl --namespace=<namespace> delete pod busybox
```
Where `<namespace>` is the name of the namespace that you created in step 1 above.
1. View the logs to verify that Kubernetes events were sent to the sink by the Knative Eventing system by running the command:
```bash
kubectl logs --namespace=<namespace> -l app=<sink> --tail=100
```
Where:
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<sink>` is the name of the PodSpecable object that you used as a sink in step 5 above.
Example log output:
```{ .bash .no-copy }
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.apiserver.resource.update
source: https://10.96.0.1:443
subject: /apis/v1/namespaces/apiserversource-example/events/testevents.15dd3050eb1e6f50
id: e0447eb7-36b5-443b-9d37-faf4fe5c62f0
time: 2020-07-28T19:14:54.719501054Z
datacontenttype: application/json
Extensions,
kind: Event
name: busybox.1626008649e617e3
namespace: apiserversource-example
Data,
{
"apiVersion": "v1",
"count": 1,
"eventTime": null,
"firstTimestamp": "2020-07-28T19:14:54Z",
"involvedObject": {
"apiVersion": "v1",
"fieldPath": "spec.containers{busybox}",
"kind": "Pod",
"name": "busybox",
"namespace": "apiserversource-example",
"resourceVersion": "28987493",
"uid": "1efb342a-737b-11e9-a6c5-42010a8a00ed"
},
"kind": "Event",
"lastTimestamp": "2020-07-28T19:14:54Z",
"message": "Started container",
"metadata": {
"creationTimestamp": "2020-07-28T19:14:54Z",
"name": "busybox.1626008649e617e3",
"namespace": "default",
"resourceVersion": "506088",
"selfLink": "/api/v1/namespaces/apiserversource-example/events/busybox.1626008649e617e3",
"uid": "2005af47-737b-11e9-a6c5-42010a8a00ed"
},
"reason": "Started",
"reportingComponent": "",
"reportingInstance": "",
"source": {
"component": "kubelet",
"host": "gke-knative-auto-cluster-default-pool-23c23c4f-xdj0"
},
"type": "Normal"
}
```
## Delete the ApiServerSource
To remove the ApiServerSource object and all of the related resources:
- Delete the namespace by running the command:
```bash
kubectl delete namespace <namespace>
```
Where `<namespace>` is the name of the namespace that you created in step 1 above.

View File

@ -0,0 +1,244 @@
# ApiServerSource reference
![version](https://img.shields.io/badge/API_Version-v1-red?style=flat-square)
This topic provides reference information about the configurable fields for the
ApiServerSource object.
## ApiServerSource
An ApiServerSource 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 an ApiServerSource object. | Required |
| [`metadata`][kubernetes-overview] | Specifies metadata that uniquely identifies the ApiServerSource object. For example, a `name`. | Required |
| [`spec`][kubernetes-overview] | Specifies the configuration information for this ApiServerSource object. | Required |
| `spec.mode` | EventMode controls the format of the event. Set to `Reference` to send a `dataref` event type for the resource being watched. Only a reference to the resource is included in the event payload. Set to `Resource` to have the full resource lifecycle event in the payload. Defaults to `Reference`. | Optional |
| [`spec.owner`](#owner-parameter) | ResourceOwner is an additional filter to only track resources that are owned by a specific resource type. If ResourceOwner matches Resources[n] then Resources[n] is allowed to pass the ResourceOwner filter. | Optional |
| [`spec.resources`](#resources-parameter) | The resources that the source tracks so it can send related lifecycle events from the Kubernetes ApiServer. Includes an optional label selector to help filter. | Required |
| `spec.serviceAccountName` | The name of the ServiceAccount to use to run this source. Defaults to `default` if not set. | Optional |
| [`spec.sink`](#sink-parameter) | A reference to an object that resolves to a URI to use as the sink. | Required |
| [`spec.ceOverrides`](#cloudevent-overrides) | Defines overrides to control the output format and modifications to the event sent to the sink. | Optional |
### Owner parameter
ResourceOwner is an additional filter to only track resources that are owned by
a specific resource type. If ResourceOwner matches Resources[n] then Resources[n]
is allowed to pass the ResourceOwner filter.
An `owner` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| `apiVersion` | API version of the resource to watch. | Required |
| [`kind`][kubernetes-kinds] | Kind of the resource to watch. | Required |
#### Example: Owner parameter
```yaml
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
...
owner:
apiVersion: apps/v1
kind: Deployment
...
```
### Resources parameter
The `resources` parameter specifies the resources that the source tracks so that
it can send related lifecycle events from the Kubernetes ApiServer.
The parameter includes an optional label selector to help filter.
A `resources` definition supports the following fields:
| Field | Description | Required or optional |
|-------|-------------|----------------------|
| `apiVersion` | API version of the resource to watch. | Required |
| [`kind`][kubernetes-kinds] | Kind of the resource to watch. | Required |
| [`selector`][label-selectors] | LabelSelector filters this source to objects to those resources pass the label selector. <!-- unsure what this means --> | Optional |
| `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: Resources parameter
Given the following YAML, the ApiServerSource object receives events for all Pods
and Deployments in the namespace: <!-- is this correct? -->
```yaml
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
# ...
resources:
- apiVersion: v1
kind: Pod
- apiVersion: apps/v1
kind: Deployment
```
#### Example: Resources parameter using matchExpressions
Given the following YAML, ApiServerSource object receives events for all Pods in
the namespace that have a label `app=myapp` or `app=yourapp`: <!-- is this correct? -->
```yaml
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
# ...
resources:
- apiVersion: v1
kind: Pod
selector:
matchExpressions:
- key: app
operator: In
values:
- myapp
- yourapp
```
#### Example: Resources parameter using matchLabels
Given the following YAML, the ApiServerSource object receives events for all Pods
in the namespace that have a label `app=myapp`: <!-- is this correct? -->
```yaml
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
# ...
resources:
- apiVersion: v1
kind: Pod
selector:
matchLabels:
app: myapp
```
### 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
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
...
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 sink container
as `"http://mysink.default.svc.cluster.local/extra/path"`.
### 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
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
...
ceOverrides:
extensions:
extra: this is an extra attribute
additional: 42
```
!!! contract
This results in the `K_CE_OVERRIDES` environment variable being set on the
sink container 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
[label-selectors]:
http://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
[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

@ -1,227 +0,0 @@
---
title: "Getting started"
weight: 01
type: "docs"
showlandingtoc: "false"
aliases:
- /docs/eventing/samples/kubernetes-event-source
---
# Getting started
## Prerequisites
Before you can create an API server source, you must install Knative Eventing and the `kubectl` CLI tool.
## Create an API server source
1. Optional: Create a namespace for the API server source instance:
```bash
kubectl create namespace <namespace>
```
Where `<namespace>` is the name of the namespace that you want to create.
Creating a namespace for your API server source and related components allows you to view changes and events for this workflow more easily, since these are isolated from the many other components that may exist in your `default` namespace.
It also makes removing the source easier, since you can simply delete the namespace to remove all of the resources.
1. Create a service account:
```yaml
kubectl create -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: <service-account>
namespace: <namespace>
EOF
```
where;
- `<service-account>` is the name of the service account that you want to create.
- `<namespace>` is the namespace that you created in step 1 above.
1. Create a cluster role:
```yaml
kubectl create -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <cluster-role>
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- get
- list
- watch
EOF
```
where;
- `<cluster-role>` is the name of the cluster role that you want to create.
1. Create a cluster role binding:
```yaml
kubectl create -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <cluster-role-binding>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: <cluster-role>
subjects:
- kind: ServiceAccount
name: <service-account>
namespace: <namespace>
EOF
```
where;
- `<cluster-role-binding>` is the name of the cluster role binding that you want to create.
- `<cluster-role>` is the name of the cluster role that you created in step 3 above.
- `<service-account>` is the name of the service account that you created in step 2 above.
- `<namespace>` is the name of the namespace that you created in step 1 above.
1. Create an ApiServerSource object:
=== "kn"
```bash
kn source apiserver create <apiserversource> \
--namespace <namespace> \
--mode "Resource" \
--resource "Event:v1" \
--service-account <service-account> \
--sink <sink>
```
where;
- `<apiserversource>` is the name of the source that you want to create.
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<service-account>` is the name of the service account that you created in step 2 above.
- `<sink>` is the name of the PodSpecable object that you want to use as a sink.
=== "YAML"
```yaml
kubectl create -f - <<EOF
apiVersion: sources.knative.dev/v1
kind: ApiServerSource
metadata:
name: <apiserversource>
namespace: <namespace>
spec:
serviceAccountName: <service-account>
mode: Resource
resources:
- apiVersion: v1
kind: Event
sink:
ref:
apiVersion: v1
kind: Service
name: <sink>
EOF
```
where;
- `<apiserversource>` is the name of the source that you want to create.
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<service-account>` is the name of the service account that you created in step 2 above.
- `<sink>` is the name of the Knative service that you want to use as a sink. A service is used here as an example, however you can use any supported PodSpecable object by updating the `kind` from `Service` to another object type.
6. Create events by launching a test pod in your namespace:
```bash
kubectl run busybox --image=busybox --namespace=<namespace> --restart=Never -- ls
```
where;
- `<namespace>` is the name of the namespace that you created in step 1 above.
1. Delete the test pod:
```bash
kubectl --namespace=<namespace> delete pod busybox
```
where;
- `<namespace>` is the name of the namespace that you created in step 1 above.
1. View the logs to verify that Kubernetes events were sent to the Knative Eventing system:
```bash
kubectl logs --namespace=<namespace> -l app=<sink> --tail=100
```
where;
- `<namespace>` is the name of the namespace that you created in step 1 above.
- `<sink>` is the name of the PodSpecable object that you used as a sink in step 5 above.
Example log output:
```{ .bash .no-copy }
☁️ cloudevents.Event
Validation: valid
Context Attributes,
specversion: 1.0
type: dev.knative.apiserver.resource.update
source: https://10.96.0.1:443
subject: /apis/v1/namespaces/apiserversource-example/events/testevents.15dd3050eb1e6f50
id: e0447eb7-36b5-443b-9d37-faf4fe5c62f0
time: 2020-07-28T19:14:54.719501054Z
datacontenttype: application/json
Extensions,
kind: Event
name: busybox.1626008649e617e3
namespace: apiserversource-example
Data,
{
"apiVersion": "v1",
"count": 1,
"eventTime": null,
"firstTimestamp": "2020-07-28T19:14:54Z",
"involvedObject": {
"apiVersion": "v1",
"fieldPath": "spec.containers{busybox}",
"kind": "Pod",
"name": "busybox",
"namespace": "apiserversource-example",
"resourceVersion": "28987493",
"uid": "1efb342a-737b-11e9-a6c5-42010a8a00ed"
},
"kind": "Event",
"lastTimestamp": "2020-07-28T19:14:54Z",
"message": "Started container",
"metadata": {
"creationTimestamp": "2020-07-28T19:14:54Z",
"name": "busybox.1626008649e617e3",
"namespace": "default",
"resourceVersion": "506088",
"selfLink": "/api/v1/namespaces/apiserversource-example/events/busybox.1626008649e617e3",
"uid": "2005af47-737b-11e9-a6c5-42010a8a00ed"
},
"reason": "Started",
"reportingComponent": "",
"reportingInstance": "",
"source": {
"component": "kubelet",
"host": "gke-knative-auto-cluster-default-pool-23c23c4f-xdj0"
},
"type": "Normal"
}
```
## Delete the API server source
Deleting the namespace removes the API server source and all of the related resources that were created in this namespace:
```bash
kubectl delete namespace <namespace>
```
Where `<namespace>` is the name of the namespace that you created in step 1 above.

View File

@ -77,6 +77,10 @@ nav:
- Debugging application issues: developer/serving/troubleshooting/debugging-application-issues.md - Debugging application issues: developer/serving/troubleshooting/debugging-application-issues.md
- Knative Eventing: - Knative Eventing:
- Event sources: - Event sources:
- ApiServerSource:
- Overview: developer/eventing/sources/apiserversource/README.md
- Creating an ApiServerSource object: developer/eventing/sources/apiserversource/getting-started/README.md
- ApiServerSource reference: developer/eventing/sources/apiserversource/reference.md
- ContainerSource: - ContainerSource:
- Creating a ContainerSource object: developer/eventing/sources/containersource/README.md - Creating a ContainerSource object: developer/eventing/sources/containersource/README.md
- ContainerSource Reference: developer/eventing/sources/containersource/reference.md - ContainerSource Reference: developer/eventing/sources/containersource/reference.md
@ -161,9 +165,6 @@ nav:
- Getting started: eventing/getting-started.md - Getting started: eventing/getting-started.md
- Event sources: - Event sources:
- Overview: eventing/sources/README.md - Overview: eventing/sources/README.md
- API server source:
- Overview: eventing/sources/apiserversource/README.md
- Getting started: eventing/sources/apiserversource/getting-started/README.md
- PingSource: eventing/sources/ping-source/README.md - PingSource: eventing/sources/ping-source/README.md
- SinkBinding: - SinkBinding:
- Overview: eventing/sources/sinkbinding/README.md - Overview: eventing/sources/sinkbinding/README.md