首页 > 文章列表 > Kubernetes Watch 返回空结果(无数据,无返回值)

Kubernetes Watch 返回空结果(无数据,无返回值)

196 2024-02-03
问题内容

我正在使用 Kubernetes client-go 监视一些资源。

func watchGVR(ctx context.Context, args *Arguments, dynClient *dynamic.DynamicClient, gvr schema.GroupVersionResource) error {
    //if gvr.Group==" events.k8s.io" && gvr.Resource==
    fmt.Printf("Watching %q %qn", gvr.Group, gvr.Resource)
    watch, err := dynClient.Resource(gvr).Watch(context.TODO(), metav1.ListOptions{})
    if err != nil {
        fmt.Printf("..Error watching %v. group %q version %q resource %qn", err,
            gvr.Group, gvr.Version, gvr.Resource)
        return err
    }
    defer watch.Stop()
    for {
        select {
        case event := <-watch.ResultChan():
            handleEvent(gvr, event)
        case <-ctx.Done():
            return nil
        }
    }
}

func handleEvent(gvr schema.GroupVersionResource, event watch.Event) {
    if event.Object == nil {
        fmt.Printf("event.Object is nil? Skipping this event. Type=%s %+v gvr: (group=%s version=%s resource=%s)n", event.Type, event,
            gvr.Group, gvr.Version, gvr.Resource)
        return
    }
    gvk := event.Object.GetObjectKind().GroupVersionKind()
    obj, ok := event.Object.(*unstructured.Unstructured)
    if !ok {
        fmt.Printf("Internal Error, could not cast to Unstructered %T %+vn", event.Object, event.Object)
        return
    }
....

这工作正常,除了对于某些资源我得到连续的空结果: event.Object 为零,event.Type 是空字符串。

这种情况会发生在这样的资源上:


event.Object is nil? Skipping this event. Type= {Type: Object:} gvr: (group=operator.cluster.x-k8s.io version=v1alpha2 resource=addonproviders)

event.Object is nil? Skipping this event. Type= {Type: Object:} gvr: (group=operator.cluster.x-k8s.io version=v1alpha2 resource=coreproviders)

这可能是什么原因?


正确答案


我发现了这个问题。

我需要在从通道读取时检查结果:

case event := <-watch.ResultChan():
            handleEvent(gvr, event)

case event, ok := <-watch.ResultChan():
            if !ok {
                fmt.Printf("ResultChan is closed %+vn", gvr)
                return nil
            }
            handleEvent(gvr, event)

如果该资源没有对象,通道将关闭。