全部產品
Search
文件中心

Container Service for Kubernetes:使用Knative Eventing發送第一個事件

更新時間:Oct 30, 2024

Knative Eventing通過其Broker-Trigger模型為Serverless應用提供了強大的事件驅動能力,不僅支援事件的轉寄和過濾,還允許開發人員進行複雜的事件流程編排。這種架構適用於需要響應外部或內部觸發器來執行商務邏輯的應用情境,例如基於使用者行為自動發送通知、處理來自不同資料來源的資料流等。本文介紹如何基於Knative Eventing構建一個簡單的事件驅動架構,該事件驅動架構包含從服務部署到訊息傳遞機制的建立,再到最終的功能驗證。

原理說明

Knative Eventing提供了一個完整的事件模型,方便接入各個外部系統的事件。事件接入以後,通過Cloud Event標準在內部流轉,結合Broker-Trigger事件驅動模型進行事件處理。

如下圖所示,在Knative事件驅動架構中,Broker是訊息傳遞的中介,Trigger用於在特定條件下自動觸發處理流程。Broker-Trigger事件驅動模型的原理是通過Trigger訂閱Broker事件並過濾,最後將事件發送到對應的服務進行消費。

  1. Event Source:這是產生事件的源頭,可以是內部系統(如資料庫更新)或外部服務(如雲Message Service)。

  2. Ingress:在Eventing架構中,用於接收外來事件進入Knative叢集。

  3. Channel:在Knative Eventing中使用Broker-Trigger模型需要選擇相應的Channel, 也就是事件流轉系統,當前支援Kafka、NATS Streaming、InMemoryChannel事件轉寄通道,預設為InMemoryChannel。

  4. Broker:事件的中介層,負責接收來自不同事件來源的事件,並根據配置的Trigger進行路由。Broker可以實現複雜的事件流和處理邏輯,支援多種協議和後端事件服務(如NATS、Kafka等),使得事件的管理和分發更加靈活高效。

  5. Trigger:定義了事件如何被路由到特定的服務。每個Trigger都關聯了一個事件過濾器(通常基於事件類型或內容)和一個Service目標,只有匹配過濾條件的事件才會被發送到指定的Service。

  6. Service:在Eventing情境下,Service是事件的最終處理者,接收到由Trigger路由過來的事件後執行相應的商務邏輯。

前提條件

已安裝Knative Serving和Knative Eventing。具體操作,請參見部署Knative部署Knative Eventing

下文介紹如何利用Knative Eventing架構搭建一套簡單的事件驅動系統,其中包含了事件產生、傳輸及消費的基本要素。

步驟一:部署Knative服務

本文以event-display為樣本Knative服務,該服務的主要職責是接收事件並列印出其內容。

  1. 使用以下範例程式碼建立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. 部署Knative Service。

    kubectl apply -f event-display.yaml
  3. 查看Knative Service是否建立成功。

    kubectl get ksvc

    預期輸出:

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

步驟二:建立Broker和Trigger

在樣本中,建立了一個名為default的Broker以及一個與之關聯的Triggermy-service-trigger,後者指定了所有未特別指定處理方式的事件都應轉寄至之前部署的event-display服務。

  1. 建立Broker。

    1. 使用以下範例程式碼建立Broker。

      apiVersion: eventing.knative.dev/v1
      kind: Broker
      metadata:
        name: default
        namespace: default
    2. 部署Broker。

      kubectl  apply -f broker.yaml
    3. 查看Broker是否建立成功。

      kubectl  get broker

      預期輸出:

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

      輸出結果展示了Broker的基本資料和URL。URLzhi ding le指定了事件應該發送到哪裡。

  2. 建立Trigger。

    1. 使用以下範例程式碼建立Trigger。

      訂閱default Broker並將事件轉寄到event-display服務上。

      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

      以上代碼建立的my-service-triggerdefault Broker關聯,並指定了event-display服務作為訂閱者。這意味著,任何發送到default Broker的事件,只要沒有其他特定的Trigger指定處理,都將被轉寄到event-display服務上。

    2. 部署Trigger。

      kubectl apply -f trigger.yaml
    3. 查看Trigger是否建立成功。

      kubectl  get trigger

      預期輸出:

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

      輸出結果展示Trigger已經設定成功,並且處於就緒狀態,表明配置正確且能夠接收並路由事件。

步驟三:發送事件並驗證服務是否能夠正常接收事件

從外部直接向Broker發送HTTP POST請求類比事件觸發,然後使用curl命令發送帶有特定CloudEvents頭資訊的請求到Broker,觀察event-display服務是否接收到這條訊息,並按預期展示。

  1. 從Broker中擷取發送事件請求的地址broker-ingress.knative-eventing,通過向Broker發送事件請求,驗證Knative Eventing系統中的Broker服務是否已經正確配置並能夠接收事件。

    1. 通過kubectl的port-forward功能將叢集內部服務的連接埠轉寄到本地,以訪問服務。

       kubectl port-forward svc/broker-ingress -n knative-eventing 8080:80
    2. 使用curl命令發送一個POST請求到本地的8080連接埠,以驗證服務是否能夠正確接收並處理請求。

      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."}'
      

      預期輸出:

      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

      預期輸出表明,服務能夠正確地接收到發送到http://localhost:8080/default/default的POST請求,並返回了一個202 Accepted狀態代碼,表明請求已被接受。

  2. 查看event-display的Pod日誌,確認事件來源。

    1. 擷取event-display Pod的資訊。查看名為event-display的Pod的日誌

      kubectl get pods --namespace=default | grep event-display
      # 輸出結果如下所示:
      event-display-00001-deployment-766f7b9fd6-gfcz5   2/2     Running   0          3m43s
    2. 查看日誌內容。

      kubectl logs event-display-00001-deployment-766f7b9fd6-gfcz5 
      # 日誌輸出結果如下所示:
      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."
        }

      預期輸出表明,一個運行在Kubernetes上的應用正在接收來自Knative Samples Hello World源的CloudEvents事件,並列印出了這些事件的內容。