繁体   English   中英

使用 client-go 观看 CustomResourceDefinitions (CRD)

[英]Watch CustomResourceDefinitions (CRD) with client-go

我已经向 Kube.netes 添加了一个新的 CRD ApiGateway ,我想查看它的新资源/更改资源。

这适用于一个简单的 Rest 客户端,如下例所示。

但我想通过k8s.io/client-go/kube.netes关注这些资源。

虽然像下面的 client-go 示例中那样获取标准资源很简单,但我没有得到任何适用于 CRD 的东西。 是否有可能通过 client-go 来完成?

标准资源的客户端示例

import (
    ....
    "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

func handleNewServices(clientset *kubernetes.Clientset) {
    for {
        serviceStreamWatcher, err := clientset.CoreV1().Services("").Watch(metav1.ListOptions{})
        if err != nil {
            panic(err.Error())
        }
        //fmt.Printf("%T\n", serviceStreamWatcher)
        for {
            select {
            case event := <-serviceStreamWatcher.ResultChan():
            service := event.Object.(*v1.Service)

            for key, value := range service.Labels {
                fmt.Printf("Key, VAlue: %s %s\n", key, value)
            }
...

RestClient(工作正常)

package main

import (
    "net/http"
    ....

)

func main() {
    for {
        // Url "cw.com" must match the config spec.group in api-gateway-crd.yaml
        // URL "apigateways" must match the config spec.names.plural in api-gateway-crd.yaml
        resp, err := http.Get("http://localhost:8001/apis/cw.com/v1/apigateways?watch=true")
        if err != nil {
            panic(err)
        }
        defer resp.Body.Close()
        decoder := json.NewDecoder(resp.Body)
        for {
            var event v1.ApiGatewayWatchEvent
            if err := decoder.Decode(&event); err == io.EOF {
                break
            } else if err != nil {
                log.Fatal(err)
            }
            log.Printf("Received watch event: %s: %s: \n", event.Type, event.Object.Metadata.Name)

        }
    }

}

CRD

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: apigateways.cw.com
spec:
  scope: Namespaced
  group: cw.com
  version: v1
  names:
    kind: ApiGateway
    singular: apigateway
    plural: apigateways

仔细想想, client-go知道deploymentsservicespods等资源。 但它无法识别您的 CRD ApiGateway

因此, client-go不能用作自定义资源的客户端(等待),除非您使它们可以被client-go识别!

怎么样?!

您必须为 CRD 生成自己的客户端。 Kubernetes 已经拥有自动生成客户端的工具,您只需要指定APIstructs 这称为code-generation

这是STEFAN SCHIMANSKI (他是kubernetes的主要贡献者之一) 关于代码生成博客文章

示例控制器

这是 kubernetes 本身给出的示例控制器示例。 pkg文件夹包含所有APISClient main.gocontroller.go包含用于监视 CRD 并相应地执行一些任务的示例代码。

!!更新!!

现在使用由 kubernetes-sigs 维护的 kubebuilder ( github repo ) 更容易生成客户端配置和控制器。

使用client-go的动态package可能是操作CRD的一个不错的选择。

基本上看例子:

cliSet, err := dynamic.NewForConfig(&rest.Config{})
if err != nil {
    return err
}

cliSet.Resource(schema.GroupVersionResource{
    // replace it with your CRD's corresponding property
    Group:    CRDGroup,
    Version:  CRDVersion,
    Resource: CRDResourceName,
}).Watch(context.Background(), metav1.ListOptions{})

高级手表,线人示例:

cliSet, err := dynamic.NewForConfig(&rest.Config{})
if err != nil {
    return err
}

fac := dynamicinformer.NewFilteredDynamicSharedInformerFactory(cliSet, 0, metav1.NamespaceAll, nil)
informer := fac.ForResource(schema.GroupVersionResource{
    // replace it with your CRD's corresponding property 
    Group:    CRDGroup,
    Version:  CRDVersion,
    Resource: CRDResourceName,
}).Informer()

informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc: func(obj interface{}) {
        // converting the dynamic object to your CRD struct
        typedObj := obj.(*unstructured.Unstructured)
        bytes, _ := typedObj.MarshalJSON()
        
        var crdObj *crd.CRD
        json.Unmarshal(bytes, &crdObj)
    },
    UpdateFunc: func(oldObj, newObj interface{}) {
        
    },
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM