How to Submit generic “runtime.Object” to Kubernetes API using client-go

折月煮酒 提交于 2021-02-18 05:13:41

问题


I'm using AWS' EKS which is Kubernetes v1.10 and I'm using client-go v7.0.0.

What I'm trying to do is parse a .yml file with multiple Kubernetes resource definitions in a file and submit those resources to the Kubernetes API. I can successfully parse the files using this code scheme.Codecs.UniversalDeserializer().Decode, and I get back an array of runtime.Object.

I know that all the Kubernetes resources conform to the runtime.Object interface, but I can't find a way to submit the generic interface to the API. Most methods I've seen use the methods on the concrete types like Deployment, Pod, etc.

I've seen some code around a generic RESTClient like this clientset.RESTClient().Put().Body(obj).Do(), but that doesn't work and I can't figure it out.

I know my clientset is configured correctly because I can successfully list all Pods.


回答1:


If you have a "generic" runtime.Object, you can use the dynamic client in client-go for this. The dynamic client deals with unstructured.Unstructured objects and all runtime.Objects can be converted to it. Here is an example:

// 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
}



回答2:


It's correct that you need the dynamic client for that but to keep things generic working with runtime.Object you need to use the DiscoveryRESTMapper which needs to use the typed client for discovery of available api versions:

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{})


来源:https://stackoverflow.com/questions/53341727/how-to-submit-generic-runtime-object-to-kubernetes-api-using-client-go

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!