Knative Func无法连接Broker,curl/busybox可正常访问,求问题排查
问题描述
搭建了Knative测试环境(基于全新microk8s,未配置Istio或复杂ServiceAccount),尝试使用Eventing功能:
- default命名空间下的Broker信息如下:
C:\dev\knative-test\functions\register-user>kubectl get broker -n default NAME URL AGE READY REASON user-broker http://broker-ingress.knative-eventing.svc.cluster.local/default/user-broker 11h True
- 通过端口转发后,用curl访问Broker URL可成功发送事件并路由到对应Trigger/Subscriber,请求详情:
C:\dev\knative-test\functions\register-user>curl -v http://localhost:80/default/user-broker -X POST -H "Ce-Id: say-hello" -H "Ce-Specversion: 1.0" -H "Ce-Type: greeting" -H "Ce-Source: not-sendoff" -H "Content-Type: application/json" -d '{"msg":"Hello Knative!"}' Note: Unnecessary use of -X or --request, POST is already inferred. * Host localhost:80 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:80... * Connected to localhost (::1) port 80 > POST /default/user-broker HTTP/1.1 > Host: localhost > User-Agent: curl/8.7.1 > Accept: */* > Ce-Id: say-hello > Ce-Specversion: 1.0 > Ce-Type: greeting > Ce-Source: not-sendoff > Content-Type: application/json > Content-Length: 22 > * upload completely sent off: 22 bytes < HTTP/1.1 202 Accepted < Allow: POST, OPTIONS < Date: Sun, 11 Aug 2024 12:50:26 GMT < Content-Length: 0 < * Connection #0 to host localhost left intact
- 但使用Go编写的Knative Func发送事件时,Broker日志报错:
2024-08-11T12:45:10.096628364Z {"level":"warn","ts":"2024-08-11T12:45:10.096Z","logger":"mt_broker_ingress","caller":"ingress/ingress_handler.go:139","msg":"Broker getter failed","commit":"c3baeda"} 2024-08-11T12:45:10.096716467Z {"level":"warn","ts":"2024-08-11T12:45:10.096Z","logger":"mt_broker_ingress","caller":"ingress/ingress_handler.go:230","msg":"Failed to retrieve broker","commit":"c3baeda","error":"broker.eventing.knative.dev \"default\" not found"}
- Go代码如下:
func Handle(w http.ResponseWriter, r *http.Request) { ctx := cloudevents.ContextWithTarget(context.Background(), "http://broker-ingress.knative-eventing.svc.cluster.local/default/user-broker") p, err := cloudevents.NewHTTP( cloudevents.WithTarget("http://broker-ingress.knative-eventing.svc.cluster.local/default/user-broker"), ) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c, err := cloudevents.NewClient(p, cloudevents.WithTimeNow(), cloudevents.WithUUIDs()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Parse the request body into a User struct. var user User err = parseBody(r, &user) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Create a new event using cloudevents event := cloudevents.NewEvent() event.SetID(uuid.New().String()) event.SetSource("fanfuse/functions/register-user") event.SetType("fanfuse.user.register") if err := event.SetData(cloudevents.ApplicationJSON, user); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send the event if result := c.Send(ctx, event); !cloudevents.IsACK(result) { log.Printf("Failed to send event to broker: %v", result) http.Error(w, fmt.Sprintf("failed to send event: %v", result), http.StatusInternalServerError) return } else { log.Printf("Event sent successfully: \n%s\n", event) } }
已确认Broker正常、DNS解析正常、URL配置正确,排查问题原因及解决方法。
解决方案
问题出在Go代码创建的CloudEvents版本不兼容:
- curl请求明确指定了
Ce-Specversion: 1.0,而你的Go代码中event := cloudevents.NewEvent()默认创建的是CloudEvents 0.3版本(specversion: 0.3)。 - Knative Eventing的Broker Ingress对CloudEvents 1.0有强依赖,版本不匹配会导致Ingress无法正确解析请求路径中的Broker名称(
user-broker),进而 fallback 尝试查找名为default的Broker,最终触发broker.eventing.knative.dev "default" not found错误。
修复步骤
修改Go代码中创建Event的逻辑,明确指定使用CloudEvents 1.0版本:
// 将原来的 event := cloudevents.NewEvent() 修改为: event := cloudevents.NewEvent(cloudevents.VersionV1)
或者在创建Event后手动设置版本:
event := cloudevents.NewEvent() event.SetSpecVersion(cloudevents.VersionV1) // 添加这一行
验证要点
- 修复后,代码发送的事件会携带
Ce-Specversion: 1.0头,与curl请求格式一致。 - Broker Ingress可正确解析路径中的
default命名空间和user-broker实例,事件能正常路由到对应的Trigger。
内容的提问来源于stack exchange,提问作者Andy Troschke
相关产品推荐
相关产品推荐

