如何使用client-go向Kubernetes API提交通用的"runtime.Object"?

14

我正在使用AWS的EKS,它是Kubernetes v1.10,我正在使用client-go v7.0.0。

我想做的是解析一个.yml文件,其中包含多个Kubernetes资源定义,并将这些资源提交到Kubernetes API。我可以使用此代码scheme.Codecs.UniversalDeserializer().Decode成功解析文件,并获得runtime.Object数组。

我知道所有Kubernetes资源都符合runtime.Object接口,但我找不到一种将通用接口提交给API的方法。我看到的大多数方法都使用具体类型(如Deployment、Pod等)上的方法。

我看到有些代码使用类似于此的通用RESTClient:clientset.RESTClient().Put().Body(obj).Do(),但那并不起作用,我也搞不清楚。

我知道我的clientset已正确配置,因为我可以成功列出所有Pod。


2
Put() 方法仅用于更新调用。此外,您需要使用 clientset.RESTClient().Put().Namespace(ns).Resource(resource_type).Name(name).Body(obj).Do() - Shudipta Sharma
2个回答

12

如果您有一个“通用”的runtime.Object,则可以在client-go中使用动态客户端。动态客户端处理unstructured.Unstructured对象,所有runtime.Object都可以转换为它。这是一个示例:

// create the dynamic client from kubeconfig
dynamicClient, err := dynamic.NewForConfig(kubeconfig)
if err != nil {
    return err
}

// convert the runtime.Object to unstructured.Unstructured
unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
    return err
}

// create the object using the dynamic client
nodeResource := schema.GroupVersionResource{Version: "v1", Resource: "Node"}
createdUnstructuredObj, err := dynamicClient.Resource(nodeResource).Namespace(ns).Create(unstructuredObj)
if err != nil {
    return err
}

// convert unstructured.Unstructured to a Node
var node *corev1.Node
if err = runtime.DefaultUnstructuredConverter.FromUnstructured(createdUnstructuredObj, node); err != nil {
    return err
}

6
runtime.DefaultUnstructuredConverter.ToUnstructured() 返回一个 map[string]interface{},我认为这个例子缺少了实际创建 unstructured.Unstructured 结构体并将其放置在 .Object 下的部分。 - Eytan Avisror
2
如果我理解正确,在“创建对象”部分,我们可以创建对象,因为我们知道它是一个节点资源。我们能否在不知道对象类型的情况下创建对象? - sitaktif

6

确实需要动态客户端,但为了使事情更通用,使用 runtime.Object 工作时需要使用 DiscoveryRESTMapper,该工具需要使用类型化的客户端来发现可用的 API 版本:

dynClient, err := dynamic.NewForConfig(config)
...
clientset, err := kubernetes.NewForConfig(config)
...
gvk := obj.GroupVersionKind()
gk := schema.GroupKind{Group: gvk.Group, Kind: gvk.Kind}
groupResources, err := restmapper.GetAPIGroupResources(clientset.Discovery())
...
rm := restmapper.NewDiscoveryRESTMapper(groupResources)
mapping, err := rm.RESTMapping(gk, gvk.Version)
...
dynClient.Resource(mapping.Resource).Namespace("default").Create(obj, metav1.CreateOptions{})

你能想到一种自动确定资源是命名空间范围还是集群范围的方法吗? - perrohunter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接