K8s源码分析(4)-Resource Model

上一篇文章中我们主要介绍了 kubernetes 世界中的各种 resource 的 version,其中包括了资源的内部 internal version 和外部非 internal version,以及引入 internal version 来方便各种 resource 持续渐进演化的设计初衷。另外也从源码的角度分析了其中各个资源 group 的对外 version 和 internal version 都定义在哪些源文件之中,在这里我们主要介绍 kubernetes 中各种 resource 的基本定义 model。

我们可以用如下图例来表示 kubernetes 中 resource 的基本定义 model:

根据以前文章,在 kubernetes 世界之中所有 resource 的基本定义里(例如我们常用的 YAML 文件),一定都有 type meta 和 object meta 这两个部分。在上一篇文章里我们以 deployment 资源为例, 也看同时到了 type meta 和 object meta 在源文件中的对应。

type Deployment struct {
  metav1.TypeMeta `json:",inline"`


  metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`


  Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`


  Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
  • 我们看到在 deployment 的定义中 type meta 和 object meta 类型并没有名称的定义,而是直接写的类型。在 go 语言中,这种特性就相当于是继承 (类比 java 语言的继承) 。

  • DeploymentSpec 和 DeploymentStatus 这两种类型在资源 deployment 的定义中是有名称 Spec 和 Status 的, 在 go 语言中,这种方式就相当于是组合(类比 java 语言的成员变量)。

  • 所以综上进行总结,在 kubernetes 世界里所有的 resource 定义之中,通过继承的方式来继承了 type meta 和 object meta 两种类型,通过组合成员变量的方式组合了属于自己特定的 spec 和 status。

从源码的角度来看 kubernetes resource 的 group version kind (即 GVK) 的属性被定义在 staging/src/k8s.io/apimachinery/pkg/runtime/schema/group_version.go 中

type GroupVersionKind struct {
  Group   string
  Version string
  Kind    string
}

对于 TypeMeta 这个类型定义来说,它实现了 runtime.Object 和 schema.ObjectKind 接口 (即实现了接口里定义的方法)

// staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go
type Object interface {
  GetObjectKind() schema.ObjectKind
  DeepCopyObject() Object
}


// staging/src/k8s.io/apimachinery/pkg/runtime/schema/interfaces.go
type ObjectKind interface {
  SetGroupVersionKind(kind GroupVersionKind)
  GroupVersionKind() GroupVersionKind
}


// staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { 
  return obj
 }
 
 func (obj *TypeMeta) SetGroupVersionKind(gvk schema.GroupVersionKind) {
  obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}

对于 ObjectMeta,它实现了 meta.Object 接口

// staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go
type Object interface {
  GetNamespace() string
  SetNamespace(namespace string)
  GetName() string
  SetName(name string)
  GetGenerateName() string
  SetGenerateName(name string)
  GetUID() types.UID
  SetUID(uid types.UID)
  .........
}


func (meta *ObjectMeta) GetNamespace() string                { return meta.Namespace }
func (meta *ObjectMeta) SetNamespace(namespace string)       { meta.Namespace = namespace }
func (meta *ObjectMeta) GetName() string                     { return meta.Name }
func (meta *ObjectMeta) SetName(name string)                 { meta.Name = name }
func (meta *ObjectMeta) GetGenerateName() string             { return meta.GenerateName }
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
func (meta *ObjectMeta) GetUID() types.UID                   { return meta.UID }
func (meta *ObjectMeta) SetUID(uid types.UID)                { meta.UID = uid }
.........

由上述源码分析可以总结:

  • TypeMeta 和 ObjectMeta 两种结构体分别定义了 kubernetes 各种资源的类型属性和实例属性。

  • 两种结构体又分别各自实现了不同的接口, TypeMeta 来实现了 runtime.Object 这个接口以及 schema.ObjectKind 等主要接口。 而 ObjectMeta  结构体则是实现了 meta.Object 等主要接口。

  • 对于kubernetes 中的各种不同资源(例如 deployment 等), 通过继承的方式来继承了 TypeMeta 和 ObjectMeta 两种结构体类型, 从而定义了资源 common 的属性和方法。通过组合的方式定义了属于各自不同的 spec 和 status。

  • 虽然以上的定义和设计都是 go 语言的特性,但是不难发现其中也处处蕴含着类似我们熟悉的 java 语言之中面向对象的概念, 例如接口, 继承, 组合等等。

目前先我们写到这里,在下一篇文章中我们来介绍 kubernates resource 的 meta 序列化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值