【问题标题】:How to Submit generic "runtime.Object" to Kubernetes API using client-go如何使用 client-go 向 Kubernetes API 提交通用“runtime.Object”
【发布时间】:2019-04-19 20:53:36
【问题描述】:

我正在使用 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。

【问题讨论】:

  • Put() 仅用于更新调用。此外,您需要clientset.RESTClient().Put().Namespace(ns).Resource(resource_type).Name(name).Body(obj).Do()

标签: kubernetes kubernetes-apiserver client-go


【解决方案1】:

如果你有一个“通用”runtime.Object,你可以在 client-go 中使用dynamic client。动态客户端处理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
}

【讨论】:

  • runtime.DefaultUnstructuredConverter.ToUnstructured() 返回一个map[string]interface{},我认为这个例子是缺失的,你实际上创建了一个unstructured.Unstructured 结构并将它放在它的.Object 下。
  • 如果我理解正确的话,在“创建对象”部分我们可以创建对象,因为我们知道它是一个节点资源。我们可以在不知道它是什么类型的情况下创建一个对象吗?
【解决方案2】:

您需要动态客户端是正确的,但要保持通用与 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{})

【讨论】:

  • 你能想出一种方法来自动确定资源是命名空间范围还是集群范围?
猜你喜欢
  • 2020-07-01
  • 2016-01-04
  • 2018-11-27
  • 2019-02-12
  • 2018-11-03
  • 2021-07-03
  • 1970-01-01
  • 2019-05-22
  • 2021-03-29
相关资源
最近更新 更多