测试 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")
调试时,我得到了 pod1 和 pod2 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