为了账号安全,请及时绑定邮箱和手机立即绑定

kubernetes:利用client-go 创建 CustomResourceDefinition 资源

标签:
Go Kubernetes

hello 各位小伙伴们, 今天想和大家分享的是利用client-go 生成 CustomResourceDefinition

为什么要做这样一个手记呢 , 原因是 原生的client-go 的clientSet 根本不支持 创建CustomResourceDefinition, 并且我找遍了 百度和google 都没有找到合适的答案, 最后在查看多篇 github repo 后,篡出了答案,所以放在这里分享给大家, 我想用到的人应该不多, 但一旦需要 这肯定是个万能药, 如果您已经搞定了这个问题, 好吧 您可以关闭这篇手记,如果正巧 你还在为此而头疼, 那么 来看看怎么做吧


首先 我们先随便上一个 template 的demo

apiVersion: apiextensions.k8s.io/v1beta1

kind: CustomResourceDefinition

metadata:

 name: queues.scheduling.volcano.sh

spec:

 group: scheduling.volcano.sh

 names:

   kind: Queue

   plural: queues


接下来我说我遇到的坑:

1: 大家看到了 kind 是 CustomResourceDefinition, 而 apiVersion apiextensions.k8s.io/v1beta1

当我们拿到yaml的str后,正常情况下怎么解析呢?

obj, _, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(yaml), nil, nil)   // 来自

"k8s.io/client-go/kubernetes/scheme"


接下来 我们只需要吧 obj 转成我们需要的结构体,比如说 obj.(*appsV1.DaemonSet),  拿到这样的结构体,我们就可以去 get create update delete了. 但是!  scheme无法解析kind为CustomResourceDefinition的资源!所以我们遇到的第一个问题是无法把我们想要的yaml转成我们需要的结构体!

2: 标准的client-go 根本没有对应的CustomResourceDefinition的结构体!

3: 标准的client-go 根本不支持创建 CustomResourceDefinition 的资源!


以上三点让我非常郁闷,但毕竟还是有办法去解决的. 通过找零散的资料, 首先我找到了 CustomResourceDefinition的结构体的sdk-----"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"  我们通过安装他 可以拿到v1beta1.CustomResourceDefinition 这个结构体, 好, 那么问题 2解决了,  不过 即便有了结构体, 我们依然无法通过scheme 将yaml转成标准的 object.runtime ,  不过这个倒也简单, 我们只需要呀 yaml转成json, 再将json返序列放入v1beta1.CustomResourceDefinition. 有的同学会说, 我直接把yaml放到结构体里不好了吗? 但事实证明,不行, 所以 参考代码如下:

obj := v1beta1.CustomResourceDefinition{}

jsonByte, err := yaml1.YAMLToJSON([]byte(yaml))   // yaml1 "github.com/ghodss/yaml"

if err != nil {

    return err

}

err = json.Unmarshal(jsonByte, &obj)

if err != nil {

    return nil

}

 

好了 1的问题也解决了, 我们可以将yaml 字符串直接转成我们的资源结构体对象了. (当然了 代码是死的,人是活的,我们并不一定都要用scheme 来定义对象,因为业务中有时候是用户传参数,我们来自动生成对应的结构体, 所以第一步到不是非常重要,关键是 2 和 3) 那么最后一步 我们的client-go的clientset 不支持创建 CustomResourceDefinition 这种资源, 这就是说,我们必须创建另外一个支持CustomResourceDefinition的clientSet,   这个clientset 找了好久后终于找到了-----clientsetCustom "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"   通过这个sdk 我们可以拥有一个支持CustomResourceDefinition的clientset了. 但是! 问题又来了, 这个clientset(后边我们叫他 cc吧) 他需要的kubeconfig 不是 client-go 标准中的 api.config,  而是一个叫做 rest.Config 而且进去查看这个结构体,和 api.config完全不同, 但我们自己的kubeconfig 都是标准的结构,  于是我又陷入了沉思, 因为 怎么都找不到对应 可以创建rest.config的结构体. 百度 google都找遍了,我依然找不到, 再我要放弃的时候, 看到来自google的一个英文帖子, 说 可以吧api.config 转换城 rest.config, 但找了很多网页,都没有找到, 于是我继续找,哪里呢? github, 我通过关键字,一点一点的寻找, 终于找到了答案, 振奋人心啊! 我们直接贴代码:


kubeconfig, err := clientcmd.NewClientConfigFromBytes([]byte(kubeCfgStr))  //"k8s.io/client-go/tools/clientcmd"

    if err != nil {

        return nil, err

    }

    _config, err := kubeconfig.ClientConfig()   // 这一步最关键, 他将 api.config 转成了 rest.config

    if err != nil {

        return nil, err

    }

cc := clientsetCustom.NewForConfigOrDie(_config)


就这样,我们终于可以通过 cc 来 操作 CustomResourceDefinition 这个资源了! 看似一切就结束了!不 并不是的. 其实我在创建这个资源的原因是 安装volcano 这个插件, 但是 这个插件创建 batchjob的插件sdk 和 我们刚才说的几个 sdk冲突, 他会强制把 client-go 等几个sdk升级到高版本,造成冲突, 所以解决办法是强制在go.mod中降低下来版本, 或许未来可以解决这个问题吧.


好了,以上就是我遇到的坑,我大概花费了1天的时间研究这个,终于搞定了,所以记录在这里,为自己,也为别人吧.


··································

欢迎关注课程:

《Django入门到进阶-更适合Python小白的系统课程》

  金职位 Python工程师2020版


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Python工程师
手记
粉丝
231
获赞与收藏
731

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消