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

alo*_*ras 8 kubernetes kubernetes-apiserver client-go

我正在使用AWS'EKS,这是Kubernetes v1.10,我正在使用client-go v7.0.0.

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

我知道所有Kubernetes资源都符合runtime.Object接口,但我找不到将通用接口提交给API的方法.我见过的大多数方法都使用了Deployment,Pod等具体类型的方法.

我已经看到了像这样的通用RESTClient的一些代码clientset.RESTClient().Put().Body(obj).Do(),但这不起作用,我无法弄明白.

我知道我的客户端配置正确,因为我可以成功列出所有Pod.

Nik*_*ath 9

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

// 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
}
Run Code Online (Sandbox Code Playgroud)

  • `runtime.DefaultUnstructedConverter.ToUnstructed()` 返回一个 `map[string]interface{}`,我认为这个示例缺少您实际创建一个 `unstructed.Unstructed` 结构并将其放在它的 .Object 下的位置。 (2认同)
  • 如果我理解正确的话,在“创建对象”部分中,我们可以创建对象,因为我们知道它是节点资源。我们可以在不知道对象是什么类型的情况下创建它吗? (2认同)

Joh*_*mke 5

您需要动态客户端是正确的,但为了让运行时的东西通用,您需要使用 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{})
Run Code Online (Sandbox Code Playgroud)