使用自定义 fieldSelector 列出来自缓存客户端的自定义资源

我正在使用Operator SDK构建自定义 Kubernetes Operator。我使用相应的 Operator SDK 命令创建了自定义资源定义和控制器:


operator-sdk add api --api-version example.com/v1alpha1 --kind=Example

operator-sdk add controller --api-version example.com/v1alpha1 --kind=Example

在主协调循环中(对于上面的示例,自动生成的ReconcileExample.Reconcile方法),我有一些自定义业务逻辑,需要我在 Kubernetes API 中查询具有特定字段值的同类其他对象。我突然想到,我也许可以使用默认的 API 客户端(由控制器提供)和自定义字段选择器:


func (r *ReconcileExample) Reconcile(request reconcile.Request) (reconcile.Result, error) {

    ctx := context.TODO()

    listOptions := client.ListOptions{

        FieldSelector: fields.SelectorFromSet(fields.Set{"spec.someField": "someValue"}),

        Namespace:     request.Namespace,

    }

    otherExamples := v1alpha1.ExampleList{}


    if err := r.client.List(ctx, &listOptions, &otherExamples); err != nil {

        return reconcile.Result{}, err

    }


    // do stuff...


    return reconcile.Result{}, nil

}

当我运行该运算符并创建新Example资源时,该运算符失败并显示以下错误消息:


{"level":"info","ts":1563388786.825384,"logger":"controller_example","msg":"Reconciling Example","Request.Namespace":"default","Request.Name":"example-test"}

{"level":"error","ts":1563388786.8255732,"logger":"kubebuilder.controller","msg":"Reconciler error","controller":"example-controller","request":"default/example-test","error":"Index with name field:spec.someField does not exist","stacktrace":"..."}

最重要的部分是


名称字段索引:spec.someField 不存在


我已经搜索了关于默认 API 客户端的 Operator SDK 文档,并了解了一些有关客户端内部工作原理的信息,但没有详细解释此错误或如何修复它。


此错误消息是什么意思,如何创建此缺失索引以按此字段值有效列出对象?


慕婉清6462132
浏览 133回答 0
0回答

湖上湖

控制器提供的默认 API 客户端是一个拆分客户端——它从本地保存的缓存提供服务Get和请求,并将其他方法(例如直接转发到 Kubernetes API 服务器)转发。相应的文档中也对此进行了解释:ListCreateUpdateSDK将生成代码来创建一个Manager,它拥有一个Cache和一个Client,用于CRUD操作并与API服务器通信。默认情况下,控制器的协调器将填充管理器的客户端,该客户端是一个拆分客户端。[...] 拆分客户端从缓存中读取(获取和列出)并向 API 服务器写入(创建、更新、删除)。从Cache中读取显着减少了API服务器上的请求负载;只要API服务器更新Cache,读操作最终是一致的。要使用自定义字段选择器从缓存中查询值,缓存需要具有该字段的搜索索引。该索引器可以在设置缓存后立即定义。要注册自定义索引器,请将以下代码添加到运算符的引导逻辑中(在自动生成的代码中,这直接在 中完成main)。这需要在实例化控制器管理器 ( )之后以及将自定义 API 类型添加到后完成:manager.Newruntime.Schemepackage mainimport (    k8sruntime "k8s.io/apimachinery/pkg/runtime"    "example.com/example-operator/pkg/apis/example/v1alpha1"    // ...)function main() {    // ...    cache := mgr.GetCache()    indexFunc := func(obj k8sruntime.Object) []string {        return []string{obj.(*v1alpha1.Example).Spec.SomeField}    }    if err := cache.IndexField(&v1alpha1.Example{}, "spec.someField", indexFunc); err != nil {        panic(err)    }    // ...}当定义相应的索引器函数时,字段选择器spec.someField将按预期从本地缓存工作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go