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,那里丰富的内容在等着咱们

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

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

相关推荐
Victor356几秒前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁17 分钟前
单线程 Redis 的高性能之道
redis·后端
GetcharZp23 分钟前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴2 小时前
COBOL语言的云计算
开发语言·后端·golang
风向决定发型丶2 小时前
K8S CPU绑核详解
云原生·容器·kubernetes
普通网友2 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒3 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan4 小时前
Go 内存回收-GC 源码1-触发与阶段
后端
shining4 小时前
[Golang]Eino探索之旅-初窥门径
后端
掘金者阿豪4 小时前
Mac 程序员效率神器:6 个我每天都在用的 Mac 工具推荐(Alfred / Paste / PixPin / HexHub / iTerm2 /)
后端