使用client-go模拟“ kubectl等待”以准备就绪的吊舱

时间:2020-08-17 01:26:16

标签: go kubernetes wait pod client-go

在bash脚本中,我通常使用'kubectl wait'来阻塞,直到某个pod资源准备好为止,例如类似于以下内容:

kubectl wait --for=condition=Ready --timeout=2m -n mynamespace pod -l myselector

之所以行之有效,是因为通常我不知道需要等待的Pod的确切名称,而'kubectl wait'允许我根据选择器定位Pod,然后阻塞直到准备就绪。

现在,我需要在golang代码中执行类似的操作。我已经看到了使用client-go库通过名称认证和“获取”特定pod的示例。但是我对如何最好地适应我的需求有一些疑问...

  1. 我不知道能够“获取()”的容器的确切名称/全名,这就是为什么“ kubectl wait”是完美的原因,因为它允许我使用选择器来查找容器。我假设我应该使用客户端库来代替CoreV1()。Pods()。List()而不是Get()调用,以便允许我使用选择器找到想要的Pod?

  2. 此外,广告连播可能不会立即存在,并且可能仅在1分钟左右后创建,“ kubectl等待”将为我处理。在代码中,我是否需要循环/睡眠并继续执行List()直到吊舱存在?

  3. 与#2相似的问题...一旦List()返回一个容器名称,在golang中“等待”该容器处于“就绪”状态的最佳方法是什么?如果可以避免的话,我不想对睡眠进行任何丑陋的调查...因此,使用golang'wait'软件包或类似工具是否有更好的选择?您有什么建议?

1 个答案:

答案 0 :(得分:3)

如何像kubectl那样做呢?基本上,使用List(...)根据字段选择器列出,然后使用Watch(...)

摘要:

...
        // List with a name field selector to get the current resourceVersion to watch from (not the object's resourceVersion)
        gottenObjList, err := o.DynamicClient.Resource(info.Mapping.Resource).Namespace(info.Namespace).List(context.TODO(), metav1.ListOptions{FieldSelector: nameSelector})
        if apierrors.IsNotFound(err) {
            return info.Object, true, nil
        }
        if err != nil {
            // TODO this could do something slightly fancier if we wish
            return info.Object, false, err
        }
        if len(gottenObjList.Items) != 1 {
            return info.Object, true, nil
        }
        gottenObj := &gottenObjList.Items[0]
        resourceLocation := ResourceLocation{
            GroupResource: info.Mapping.Resource.GroupResource(),
            Namespace:     gottenObj.GetNamespace(),
            Name:          gottenObj.GetName(),
        }
        if uid, ok := o.UIDMap[resourceLocation]; ok {
            if gottenObj.GetUID() != uid {
                return gottenObj, true, nil
            }
        }

        watchOptions := metav1.ListOptions{}
        watchOptions.FieldSelector = nameSelector
        watchOptions.ResourceVersion = gottenObjList.GetResourceVersion()
        objWatch, err := o.DynamicClient.Resource(info.Mapping.Resource).Namespace(info.Namespace).Watch(context.TODO(), watchOptions)
        if err != nil {
            return gottenObj, false, err
        }
...

✌️<​​/ p>