如何使用client-go的RESTClient查询指定命名空间的KafkaTopic自定义资源
指定命名空间下KafkaTopic自定义资源的查询方案
首先明确:可以通过client-go实现指定范围的KafkaTopic查询,你遇到的报错是因为对Strimzi KafkaTopic的资源范围理解有误。
报错原因
KafkaTopic默认是集群范围的自定义资源(CR),Kubernetes中集群级资源的API路径不包含namespaces/<ns>段。当你调用Namespace("<my-namespace>")时,会生成错误的请求路径(例如/apis/kafka.strimzi.io/v1beta2/namespaces/<my-namespace>/kafkatopics),服务器找不到该路径对应的资源,因此抛出"服务器找不到请求的资源"错误。
正确实现方式
方式一:用RESTClient过滤关联指定命名空间的Kafka集群
如果你的需求是获取关联到某命名空间下Kafka集群的Topic,可通过字段选择器过滤spec.clusterRef.namespace字段:
import ( "context" "encoding/json" "github.com/strimzi/strimzi-kafka-operator/pkg/apis/kafka/v1beta2" kafka "github.com/strimzi/strimzi-kafka-operator/pkg/client/clientset/versioned" ) // 假设已初始化clientSet topics := &v1beta2.KafkaTopicList{} d, err := clientSet.RESTClient().Get(). AbsPath("/apis/kafka.strimzi.io/v1beta2/kafkatopics"). // 替换成目标命名空间 Param("fieldSelector", "spec.clusterRef.namespace=<my-namespace>"). DoRaw(context.TODO()) if err != nil { panic(err.Error()) } // 将响应解析到结构体 if err := json.Unmarshal(d, topics); err != nil { panic(err.Error()) }
方式二:使用Typed Client(更简洁)
如果引入了Strimzi官方生成的client-go包,可以直接用Typed Client实现过滤:
import ( "context" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kafka "github.com/strimzi/strimzi-kafka-operator/pkg/client/clientset/versioned" ) // 初始化Strimzi专属ClientSet kafkaClientSet, err := kafka.NewForConfig(restConfig) if err != nil { panic(err.Error()) } // 查询关联指定命名空间Kafka集群的Topic列表 topics, err := kafkaClientSet.KafkaV1beta2().KafkaTopics().List(context.TODO(), metav1.ListOptions{ // 替换成目标命名空间 FieldSelector: "spec.clusterRef.namespace=<my-namespace>", }) if err != nil { panic(err.Error()) }
特殊情况:若KafkaTopic是命名空间级CR
如果你的环境中KafkaTopic被配置为命名空间范围的CRD,可直接用Namespace()方法,但需调整API路径:
d, err := clientSet.RESTClient().Get(). Namespace("<my-namespace>"). AbsPath("/apis/kafka.strimzi.io/v1beta2/namespaces/<my-namespace>/kafkatopics"). DoRaw(context.TODO())
注:这种配置不属于Strimzi默认情况,需确认CRD的scope字段为Namespaced。
内容的提问来源于stack exchange,提问作者Fabrice Jammes
相关产品推荐
相关产品推荐

