测试 kubernetes go client api 调用时通过 FieldSelector spec.nodeName 过滤 Pod 的方式

Posted

技术标签:

【中文标题】测试 kubernetes go client api 调用时通过 FieldSelector spec.nodeName 过滤 Pod 的方式【英文标题】:Way of filter Pods by FieldSelector spec.nodeName when testing kubernetes go client api calls 【发布时间】:2021-06-03 11:48:48 【问题描述】:

作为在给定 k8s 节点中列出 pod 的编写逻辑的一部分,我有以下 api 调用:

func ListRunningPodsByNodeName(kubeClient kubernetes.Interface, nodeName string (*v1.PodList, error) 
  return kubeClient.
    CoreV1().
    Pods("").
    List(context.TODO(), metav1.ListOptions
        FieldSelector: "spec.nodeName=" + nodeName,
    )

为了使用k8s提供的假客户端测试ListRunningPodsByNodeName,我想出了以下测试初始化​​:

func TestListRunningPodsByNodeName(t *testing.T) 

    // happy path
    kubeClient := fake.NewSimpleClientset(&v1.Pod
    ObjectMeta: metav1.ObjectMeta
        Name:        "pod1",
        Namespace:   "default",
        Annotations: map[string]string,
    ,
        Spec: v1.PodSpec
            NodeName: "foo",
        ,
    , &v1.Pod
            ObjectMeta: metav1.ObjectMeta
                    Name:        "pod2",
                    Namespace:   "default",
                    Annotations: map[string]string,
            ,
            Spec: v1.PodSpec
                NodeName: "bar",
            ,
    )

    got, _ := ListRunningPodsByNodeName(kubeClient, "foo")

    for i, pod := range got.Items 
        fmt.Println(fmt.Sprintf("[%2d] %s", i, pod.GetName()))
    

    t.Errorf("Error, expecting only one pod")

调试时,我得到了 pod1pod2 Pod,尽管我正在过滤那些在 foo 节点中运行的 Pod。使用相同的方法通过某些元数据进行过滤就像一个魅力,但在通过 nodeName 过滤的情况下无法使其工作。 ¿ 有人知道为什么吗?我怀疑这可能是假客户端功能的限制,但还不能完全确定会打开一个问题

提前致谢

【问题讨论】:

【参考方案1】:

假的 k8s 客户端不支持按字段选择器过滤(请参阅this comment)。当使用假的 k8s 客户端进行单元测试时,最好假设 k8s 客户端将在现实世界中按预期工作(根据您的字段选择器查询返回正确的 pod)。在您的测试中,将 pod 提供给 您的应用程序 期望的假 k8s 客户端并测试您自己的逻辑,而不是同时测试 k8s 客户端的查询逻辑。

如果假客户端为您执行过滤绝对至关重要,您可以使用假客户端反应器将此自定义行为注入假客户端。这只是意味着更多样板代码。

可以通过添加处理特定类型操作的反应器,在操作中使用附加信息(在本例中为 ListAction#GetListRestrictions().Fields),将任何非泛型(如字段选择行为)注入测试,并自定义返回的数据

我根本没有测试过这个,但希望它能给你一些开始。

client := fake.NewSimpleClientset()
client.AddReactor("*", "MyResource", func(action testing.Action) (handled bool, ret runtime.Object, err error) 
    // Add custom filtering logic here
)

【讨论】:

谢谢克拉克,我担心这就是问题所在,我有 Node.js 和 python 背景,你可以在其中模拟/伪造任何你想要的东西,但这似乎不是去吧,很公平,会检查你建议的添加反应器的方法 顺便说一句,我在其他语言中所做的是为方法设置一个间谍,以期望使用哪些参数来调用客户端,原因与您之前所说的相同,我不需要或不想要测试与 go 客户端本身相关的任何内容

以上是关于测试 kubernetes go client api 调用时通过 FieldSelector spec.nodeName 过滤 Pod 的方式的主要内容,如果未能解决你的问题,请参考以下文章

测试 kubernetes go client api 调用时通过 FieldSelector spec.nodeName 过滤 Pod 的方式

client-go连接kubernetes集群-delete相关操作

client-go连接kubernetes集群-create

client-go连接kubernetes集群

client-go连接kubernetes集群-update相关操作

client-go 源码分析