|
| 1 | +# Trigger a Knative service |
| 2 | + |
| 3 | +TriggerMesh and Knative are powerful building blocks for building event-driven applications. On the one hand, [Knative Serving](https://knative.dev/docs/serving/) can be used to deploy services to Kubernetes that can react to incoming events, scale according to load, and scale to zero when idle. On the other hand, TriggerMesh is great at capturing events from many different systems and processing and routing them to event consumers. |
| 4 | + |
| 5 | +There are two ways that you can trigger a Knative service from TriggerMesh: either with generic HTTP requests, or with CloudEvents. This guide explains how to make generic HTTP requests with the [HTTP target](../../targets/http.md), in which the `data` attribute from the event in TriggerMesh is directly used as the body of the HTTP request. |
| 6 | + |
| 7 | +If on the other hand your Knative service expects a CloudEvent, or you'd like an example of how to build one from the ground up, then take a look at [this post](https://www.triggermesh.com/blog/build-a-custom-triggermesh-component-with-fastapi) that shows how to build a CloudEvents Knative service using Python FastAPI and route CloudEvents to it with TriggerMesh. |
| 8 | + |
| 9 | +The solution we’ll build in this guide is illustrated in the schema below. |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +## Setup |
| 14 | + |
| 15 | +If you haven’t already done so, you’ll need to install TriggerMesh and Knative Serving on your cluster. I’m using [Minikube](https://minikube.sigs.k8s.io/docs/start/) to create a local cluster and I [followed the guide](../../installation/kubernetes-yaml.md) for installing TriggerMesh and Knative Serving onto the cluster. |
| 16 | + |
| 17 | +I’m going to use a simple containerised http service that I [found here](https://hub.docker.com/r/strm/helloworld-http/) to run as a Knative service. Feel free to replace this with your own of course. |
| 18 | + |
| 19 | +Define the Knative service in a manifest called knative-service.yaml: |
| 20 | + |
| 21 | +```yaml |
| 22 | +apiVersion: serving.knative.dev/v1 |
| 23 | +kind: Service |
| 24 | +metadata: |
| 25 | + name: hello-http |
| 26 | +spec: |
| 27 | + template: |
| 28 | + spec: |
| 29 | + containers: |
| 30 | + - image: strm/helloworld-http |
| 31 | + ports: |
| 32 | + - containerPort: 80 |
| 33 | +``` |
| 34 | +
|
| 35 | +Apply this to the cluster: |
| 36 | +
|
| 37 | +```sh |
| 38 | +kubectl apply -f knative-service.yaml |
| 39 | +``` |
| 40 | + |
| 41 | +Check that the Knative service is running with the following command: |
| 42 | + |
| 43 | +```sh |
| 44 | +kubectl get ksvc hello-http |
| 45 | +NAME URL LATESTCREATED LATESTREADY READY REASON |
| 46 | +hello-http http://hello-http.default.svc.cluster.local hello-http-00002 hello-http-00002 True |
| 47 | +``` |
| 48 | + |
| 49 | +Now deploy a TriggerMesh broker to the cluster. The broker decouples event producers and consumers, and provides triggers that send events to consumers if they match a given filter. Create the following broker.yaml: |
| 50 | + |
| 51 | +```yaml |
| 52 | +apiVersion: eventing.triggermesh.io/v1alpha1 |
| 53 | +kind: MemoryBroker |
| 54 | +metadata: |
| 55 | + name: broker |
| 56 | +``` |
| 57 | +
|
| 58 | +And apply it to the cluster: |
| 59 | +
|
| 60 | +```sh |
| 61 | +kubectl apply -f broker.yaml |
| 62 | +``` |
| 63 | + |
| 64 | +Check that the broker is available: |
| 65 | + |
| 66 | +```sh |
| 67 | +kubectl get memorybrokers.eventing.triggermesh.io |
| 68 | +NAME URL AGE READY REASON |
| 69 | +broker http://broker-mb-broker.default.svc.cluster.local 3h38m True |
| 70 | +``` |
| 71 | + |
| 72 | +Now create a Webhook source, in a file called `webhook-source.yaml`, that we'll use as an event producer. It will let us easily send events of type `my.event.type` to the broker over HTTP. Later, you can replace it or add additional event sources like Kafka, AWS SQS, Google Pub/Sub, etc… |
| 73 | + |
| 74 | +```yaml |
| 75 | +apiVersion: sources.triggermesh.io/v1alpha1 |
| 76 | +kind: WebhookSource |
| 77 | +metadata: |
| 78 | + name: sample |
| 79 | +spec: |
| 80 | + eventType: my.event.type |
| 81 | + sink: |
| 82 | + ref: |
| 83 | + apiVersion: eventing.triggermesh.io/v1alpha1 |
| 84 | + kind: MemoryBroker |
| 85 | + name: broker |
| 86 | +``` |
| 87 | +
|
| 88 | +And create the Webhook source |
| 89 | +
|
| 90 | +```sh |
| 91 | +kubectl apply -f webhook-source.yaml |
| 92 | +``` |
| 93 | + |
| 94 | +Create the HTTP target in a `http-target.yaml` file, and set its endpoint parameter to the cluster local address of the Knative service that you created before. |
| 95 | + |
| 96 | +```yaml |
| 97 | +apiVersion: targets.triggermesh.io/v1alpha1 |
| 98 | +kind: HTTPTarget |
| 99 | +metadata: |
| 100 | + name: http-target |
| 101 | +spec: |
| 102 | + endpoint: http://hello-http.default.svc.cluster.local |
| 103 | + method: GET |
| 104 | +``` |
| 105 | +
|
| 106 | +Create the HTTP target: |
| 107 | +
|
| 108 | +```sh |
| 109 | +kubectl apply -f http-target.yaml |
| 110 | +``` |
| 111 | + |
| 112 | +Now create a Trigger that will route events of type `my.event.type` (those produced by the Webhook source) to the HTTP target, in a `trigger.yaml` file: |
| 113 | + |
| 114 | +```yaml |
| 115 | +apiVersion: eventing.triggermesh.io/v1alpha1 |
| 116 | +kind: Trigger |
| 117 | +metadata: |
| 118 | + name: trigger-knative-service |
| 119 | +spec: |
| 120 | + broker: |
| 121 | + group: eventing.triggermesh.io |
| 122 | + kind: MemoryBroker |
| 123 | + name: broker |
| 124 | + filters: |
| 125 | + - exact: |
| 126 | + type: my.event.type |
| 127 | + target: |
| 128 | + ref: |
| 129 | + apiVersion: targets.triggermesh.io/v1alpha1 |
| 130 | + kind: HTTPTarget |
| 131 | + name: http-target |
| 132 | +``` |
| 133 | +
|
| 134 | +Create the Trigger: |
| 135 | +
|
| 136 | +```sh |
| 137 | +kubectl apply -f trigger.yaml |
| 138 | +``` |
| 139 | + |
| 140 | +## Test it out! |
| 141 | + |
| 142 | +Run `minikube tunnel` in a separate terminal, so that the load balancer service is assigned an IP. That loadbalancer IP is used by the sslip.io config. |
| 143 | + |
| 144 | +Run the command below to get the Webhook source’s URL (accessible outside of the cluster thanks to `minikube tunnel`): |
| 145 | + |
| 146 | +```sh |
| 147 | +kubectl get webhooksources.sources.triggermesh.io |
| 148 | +NAME READY REASON URL SINK AGE |
| 149 | +sample True http://webhooksource-sample.default.127.0.0.1.sslip.io http://broker-mb-broker.default.svc.cluster.local 3h19m |
| 150 | +``` |
| 151 | + |
| 152 | +Then send an event into your Webhook source: |
| 153 | + |
| 154 | +```sh |
| 155 | +curl http://webhooksource-sample.default.127.0.0.1.sslip.io -d '{"http":"is easy"}' -H 'Content-type: application/json' |
| 156 | +``` |
| 157 | + |
| 158 | +Quickly run `kubectl get pods` and if all went well, you should see the HTTP target pods, the hello-http pods, as well as the webhook source pods spin up: |
| 159 | + |
| 160 | +```sh |
| 161 | +kubectl get po |
| 162 | +NAME READY STATUS RESTARTS AGE |
| 163 | +broker-mb-broker-5546995d8f-jdltd 1/1 Running 0 3h43m |
| 164 | +httptarget-http-target-00002-deployment-7cb9bc65dc-nlxjj 1/2 Running 0 1s |
| 165 | +knative-operator-66f5b45fcd-z6q95 1/1 Running 0 27h |
| 166 | +hello-http-00002-deployment-6c8b4c7658-pwzp2 0/2 ContainerCreating 0 0s |
| 167 | +operator-webhook-9f5487b8f-qc8zj 1/1 Running 0 27h |
| 168 | +webhooksource-sample-00001-deployment-797d4f57f6-2ch8f 2/2 Running 0 3s |
| 169 | +``` |
| 170 | + |
| 171 | +These three services run as Knative services, which is why you’ll only see their pods appear when there are events to process (else they scale down to 0). If you look at the hello-http pod logs you’ll see that it has received the event: |
| 172 | + |
| 173 | +```sh |
| 174 | +kubectl logs pods/hello-http-00002-deployment-6c8b4c7658-pwzp2 |
| 175 | +Defaulted container "user-container" out of: user-container, queue-proxy |
| 176 | +127.0.0.1 - - [23/May/2023 18:09:15] "GET / HTTP/1.1" 200 - |
| 177 | +``` |
| 178 | + |
| 179 | +Congratulations, you’ve triggered a generic http Knative service with TriggerMesh 🥳. Now that you’ve seen how to do this, you could use other event sources to trigger the service other than the Webhook source shown in this demo. For instance, you could try triggering it when an event lands on an [AWS SQS queue](../../sources/awssqs.md), a [Google Pub/Sub topic](../../sources/googlecloudpubsub.md), or an [Azure Event Hub](../../sources/azureeventhubs.md). |
0 commit comments