All Products
Search
Document Center

Container Service for Kubernetes:Use Knative Eventing to send the first event

Last Updated:Nov 14, 2024

Knative Eventing offers robust event-driven capabilities for serverless applications with its Broker-Trigger model. This component enables event forwarding and filtering, and can be used to orchestrate complex event flows. The Broker-Trigger model is ideal for applications that respond to external or internal triggers, such as automatically sending notifications based on user behaviors and processing data streams from various sources. This topic describes how to build a simple event-driven architecture using Knative Eventing, covering service deployment, message delivery mechanism, and feature verification.

How it works

Knative Eventing provides a comprehensive event model that interfaces with various external event systems. After events are ingested, they are forwarded internally using the Cloud Events standard and are processed using the Broker-Trigger event-driven model.

As shown in the following figure, in the Knative event-driven architecture, the Broker acts as an intermediary for message transmission, while the Trigger automatically initiates workflows under specific conditions. The principle of the Broker-Trigger event-driven model is to have the Trigger subscribe to and filter Broker events, then dispatch the events to the corresponding services for consumption.

image
  1. Event Source: The origin of events, which can be internal systems such as database updates, or external services such as cloud messaging services.

  2. Ingress: Receives external events into the Knative cluster.

  3. Channel: In Knative Eventing, using the Broker-Trigger model requires selecting an appropriate channel, which forwards events. Supported event forwarding channels include ApsaraMQ for Kafka, NATS Streaming, and InMemoryChannel. The default channel is InMemoryChannel.

  4. Broker: Acts as the event intermediary, routing events from different sources according to the configured Trigger. Brokers can implement complex event flows and processing logic, supporting multiple protocols and backend event services such as NATS and ApsaraMQ for Kafka, making event management and distribution more flexible and efficient.

  5. Trigger: Defines how events are routed to specific Services. Each Trigger is associated with an event filter, usually based on event type or content, and a Service target. Only events that match the filter criteria are sent to the specified Service.

  6. Service: The final processor of events. After receiving events routed by Triggers, it executes the corresponding business logic.

Prerequisites

Knative Serving and Knative Eventing are installed. For more information, see Deploy Knative and Deploy Knative Eventing.

The following sections describe the process of building a basic event-driven system using the Knative Eventing framework, including the creation, transmission, and consumption of events.

Step 1: Deploy a Knative Service

This section uses event-display as an example of a Knative Service. The primary responsibility of event-display is to receive events and print their contents.

  1. Use the following YAML template to create a Knative Service:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: event-display
      namespace: default
    spec:
      template:
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/event-display:v1028
  2. Deploy the Knative Service.

    kubectl apply -f event-display.yaml
  3. Verify whether the Knative Service is created.

    kubectl get ksvc

    Expected output:

    NAME            URL                                        LATESTCREATED         LATESTREADY           READY   REASON
    event-display   http://event-display.default.example.com   event-display-00001   event-display-00001   True    

Step 2: Create a Broker and a Trigger

Create a Broker named default and a Trigger named my-service-trigger. The Trigger ensures that events not explicitly handled are routed to the event-display Service deployed in Step 1.

  1. Create a Broker.

    1. Use the following YAML template to create a Broker:

      apiVersion: eventing.knative.dev/v1
      kind: Broker
      metadata:
        name: default
        namespace: default
    2. Deploy the Broker.

      kubectl  apply -f broker.yaml
    3. Verify whether the Broker is created.

      kubectl  get broker

      Expected output:

      NAME      URL                                                                        AGE   READY   REASON
      default   http://broker-ingress.knative-eventing.svc.cluster.local/default/default   9s    True    

      The output displays the information and URL of the Broker. The URL indicates where to send events.

  2. Create a Trigger.

    1. Create a Trigger with the sample code below.

      Subscribe to the default Broker to route events to the event-display Service.

      apiVersion: eventing.knative.dev/v1
      kind: Trigger
      metadata:
        name: my-service-trigger
      spec:
        broker: default
        subscriber:
          ref:
            apiVersion: serving.knative.dev/v1
            kind: Service
            name: event-display

      The my-service-trigger created by the preceding YAML template is linked to the default Broker and specifies the event-display Service as a subscriber. This means that any events sent to the default Broker, provided that no other specific Triggers are specified to handle them, will be forwarded to the event-display Service.

    2. Deploy the Trigger.

      kubectl apply -f trigger.yaml
    3. Verify whether the Trigger is created.

      kubectl  get trigger

      Expected output:

      NAME                 BROKER    SUBSCRIBER_URI                                   AGE   READY   REASON
      my-service-trigger   default   http://event-display.default.svc.cluster.local   22s   True    

      The output indicates that the Trigger is ready, which means that the Trigger is configured correctly and can receive and route events.

Step 3: Send events and verify if the Service can receive events

Simulate event triggering by sending an HTTP POST request directly to the Broker from an external source. Use the curl command to send a request with specific CloudEvents headers to the Broker, and verify if the event-display Service receives this message and prints it as expected.

  1. Retrieve the event request address from the Broker using broker-ingress.knative-eventing. By sending event requests to the Broker, confirm that the Broker Service in the Knative Eventing system is correctly configured and can receive events.

    1. Use the port-forward function of kubectl to forward the internal Service port within the cluster to the local machine, allowing access to the Service.

       kubectl port-forward svc/broker-ingress -n knative-eventing 8080:80
    2. Use the curl command to send a POST request to the local port 8080 to verify that the Service can correctly receive and process the request.

      curl -v "http://localhost:8080/default/default" \
         -X POST \
         -H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f79" \
         -H "Ce-Specversion: 1.0" \
         -H "Ce-Type: dev.knative.samples.helloworld" \
         -H "Ce-Source: dev.knative.samples/helloworldsource" \
         -H "Content-Type: application/json" \
         -d '{"msg":"Hello World from the curl pod."}'
      

      Expected output:

      Note: Unnecessary use of -X or --request, POST is already inferred.
      *   Trying 127.0.0.1:8080...
      * Connected to localhost (127.0.0.1) port 8080 (#0)
      > POST /default/default HTTP/1.1
      > Host: localhost:8080
      > User-Agent: curl/8.1.2
      > Accept: */*
      > Ce-Id: 53****3-88be-4077-9d7a-a3f162******9
      > Ce-Specversion: 1.0
      > Ce-Type: dev.knative.samples.helloworld
      > Ce-Source: dev.knative.samples/helloworldsource
      > Content-Type: application/json
      > Content-Length: 40
      > 
      < HTTP/1.1 202 Accepted
      < Allow: POST, OPTIONS
      < Date: Tue, 15 Oct 2024 09:36:42 GMT
      < Content-Length: 0
      < 
      * Connection #0 to host localhost left intact

      The expected output confirms that the Service has correctly received the POST request sent to http://localhost:8080/default/default and has returned a 202 Accepted status code, indicating that the request has been accepted.

  2. Inspect the logs of the event-display pod to confirm the event source.

    1. Retrieve details about the event-display pod and view its logs.

      kubectl get pods --namespace=default | grep event-display
      # The output is as follows:
      event-display-00001-deployment-766f7b9fd6-gfcz5   2/2     Running   0          3m43s
    2. View the logs.

      kubectl logs event-display-00001-deployment-766f7b9fd6-gfcz5 
      # The log output is as follows:
      Defaulted container "user-container" out of: user-container, queue-proxy
      ☁️  cloudevents.Event
      Context Attributes,
        specversion: 1.0
        type: dev.knative.samples.helloworld
        source: dev.knative.samples/helloworldsource
        id: 536808d3-88be-4077-9d7a-a3f162705f79
        datacontenttype: application/json
      Extensions,
        knativearrivaltime: 2024-10-28T11:48:56.929517041Z
      Data,
        {
          "msg": "Hello World from the curl pod1."
        }

      The expected output indicates that an application running on Kubernetes is receiving CloudEvents events from the Knative Samples Hello World source, and that it is printing the contents of these events.