Kubernetes对象深入学习之二:细说schema.ObjectKind

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):github.com/zq2599/blog...

  • 前文咱们对对象体系有了大概了解,接下来就要按照前面换分的三个知识区域逐个深入学习,今天从最简单的对象类型开始

runtime.Object、schema.ObjectKind、metav1.TypeMeta三者的关系

  • 首先要梳理清楚runtime.Object、schema.ObjectKind、metav1.TypeMeta这三者的关系,先回顾前文的简图
  • 这里小结一下三者关系:
  1. runtime.Object是个接口,定义了GetObjectKind()方法,返回值是schema.ObjectKind
go 复制代码
type Object interface {
	GetObjectKind() schema.ObjectKind
	DeepCopyObject() Object
}
  1. 上述返回值schema.ObjectKind也是一个接口,定义了两个方法:SetGroupVersionKind和GroupVersionKind
go 复制代码
type ObjectKind interface {
	// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil
	// should clear the current setting.
	SetGroupVersionKind(kind GroupVersionKind)
	// GroupVersionKind returns the stored group, version, and kind of an object, or an empty struct
	// if the object does not expose or provide these fields.
	GroupVersionKind() GroupVersionKind
}
  1. 上面一共提到了两个接口的三个方法,它们都被metav1.TypeMeta实现了
  • 还有一点要注意:TypeMeta的GetObjectKind方法,返回的是它自己!
  • 文章写到这里,突然有了一个小小的顿悟:以后在代码中再看到runtime.Object应该就很淡定了,它可能是任何资源类型,也可能只是个TypeMeta,但是无论如何,能直接从它那里得到的东西很少,因为它只有一个方法定义而已,所以拿到runtime.Object之后,各种转换和判断是少不了的
  • 由此可见核心就是schema.ObjectKind,因为runtime.Object定义的方法要返回它,而它定义的方法又被metav1.TypeMeta实现

了解schema.ObjectKind

  • 先看源码,ObjectKind的源码很简单,就是数据结构GroupVersionKind的获取和设置方法(Java bean的既视感)
go 复制代码
type ObjectKind interface {
	// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil
	// should clear the current setting.
	SetGroupVersionKind(kind GroupVersionKind)
	// GroupVersionKind returns the stored group, version, and kind of an object, or an empty struct
	// if the object does not expose or provide these fields.
	GroupVersionKind() GroupVersionKind
}
  • 再回顾前文,如下图黄色箭头2,单个对象的数据结构中嵌入了metav1.TypeMeta,这也就说明,对象自已有GroupVersionKind和SetGroupVersionKind这两个方法,我们在程序中可以通过GroupVersionKind方法获取对象的GroupVersionKind信息,也能用SetGroupVersionKind方法设置对象的GroupVersionKind信息

  • 上面反复提到的GroupVersionKind是什么?打开源码一看,原来是基础知识,这是对kubernetes中每一种资源类别的定义

go 复制代码
// GroupVersionKind unambiguously identifies a kind.  It doesn't anonymously include GroupVersion
// to avoid automatic coercion.  It doesn't use a GroupVersion to avoid custom marshalling
type GroupVersionKind struct {
	Group   string
	Version string
	Kind    string
}
  • 关于GroupVersionKind的更多信息,请参考《Kubernetes的Group、Version、Resource学习小记》,里面有详细的介绍,这里选一副有代表性的图来说明,如下所示,Group、Version、Kind一目了然
  • 回到TypeMeta源码,看看和GroupVersionKind有关,先看Set方法,可见是用TypeMeta对象的两个字段来保存的,group和version两个字段被拼接到了一起,成为新的APIVersion字段
go 复制代码
func (obj *TypeMeta) SetGroupVersionKind(gvk schema.GroupVersionKind) {
	obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
  • 再看Get方法,里面会将obj.APIVersion拆分,还原成Group和Version,再重新组装成GroupVersionKind对象返回
go 复制代码
func (obj *TypeMeta) GroupVersionKind() schema.GroupVersionKind {
	return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
  • 看过上述代码,发现都在操作TypeMeta的APIVersion和Kind字段,那就去看看TypeMeta这个数据结构,如下所示,只有这两个字段
go 复制代码
type TypeMeta struct {
	// Kind is a string value representing the REST resource this object represents.
	// Servers may infer this from the endpoint the client submits requests to.
	// Cannot be updated.
	// In CamelCase.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`

	// APIVersion defines the versioned schema of this representation of an object.
	// Servers should convert recognized schemas to the latest internal value, and
	// may reject unrecognized values.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
	// +optional
	APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}

TypeMeta的重要性

  • 既然每种资源都必须有类型,那么TypeMeta的重要性就不用多说了,在kubernetes源码中暴力搜索一下,先排除单元测试文件,可见有多处会用到,打开一段自动生成的代码,可见复制对象时首先会复制TypeMeta
  • 然后再随便打开一个单元测试的代码,如下图黄色箭头,这就很清楚了,再回想之前写的那些代码,原来这个TypeMeta我们一直在用,是如此的属性,每次创建对象的第一步就是TypeMeta对象:
  • 至此,关于对象类型和版本的接口schema.ObjectKind就学习完成了,这是平时用client-go开发时最常见的内容了,下一篇会看到ObjectMeta,那里丰富的内容在等着咱们

欢迎关注掘金:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

相关推荐
IT_陈寒8 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
流浪克拉玛依8 小时前
Go Web 服务限流器实战:从原理到压测验证 --使用 Gin 框架 + Uber Ratelimit / 官方限流器,并通过 Vegeta 进行性能剖析
后端
孟沐9 小时前
保姆级教程:手写三层架构 vs MyBatis-Plus
后端
星浩AI9 小时前
让模型自己写 Skills——从素材到自动生成工作流
人工智能·后端·agent
华仔啊11 小时前
为啥不用 MP 的 saveOrUpdateBatch?MySQL 一条 SQL 批量增改才是最优解
java·后端
武子康12 小时前
大数据-242 离线数仓 - DataX 实战:MySQL 全量/增量导入 HDFS + Hive 分区(离线数仓 ODS
大数据·后端·apache hive
砍材农夫12 小时前
TCP和UDP区别
后端
千寻girling13 小时前
一份不可多得的 《 Django 》 零基础入门教程
后端·python·面试
千寻girling13 小时前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法
贾铭13 小时前
如何实现一个网页版的剪映(三)使用fabric.js绘制时间轴
前端·后端