Kubernetes 中的 Schema 是个什么鬼?

cb1afb53ccd07244e15c7141b94254cb.gif

本文转自 Cylon 的笔记收藏册,原文:https://www.cnblogs.com/Cylon/p/16282407.html,版权归原作者所有。欢迎投稿,投稿请添加微信好友:cloud-native-yang

什么是 schema

schema 一词起源于希腊语中的 formfigure,但具体应该如何定义 schema 取决于应用环境的上下文。schema 有不同的类型,其含义与数据科学、教育、营销和 SEO 以及心理学等领域密切相关。

在维基百科中将 schema 解释为,图式,在心里学中主要描述一种思维或行为类型,用来组织资讯的类别,以及资讯之间的关系。它也可以被描述为先入为主思想的心理结构,表示世界某些观点的框架,或是用于组织和感知新资讯的系统。

但在计算机中的 schema 其实与这个解释很接近了,从很多地方都可以看到 schema 这个名词,例如 database,openldap,programing language 等的。这里可以简单的吧 schema 理解为 元数据集合 (metadata component),主要包含元素及属性的声明,与其他数据结构组成。

数据库中的 schema

在数据库中,schema 就像一个骨架结构,代表整个数据库的逻辑视图。它设计了应用于特定数据库中数据的所有约束。当在数据建模时,就会产生一个 schema。在谈到关系数据库] 和面向对象数据库时经常使用 schema。有时也指将结构或文本的描述。

数据库中 schema 描述数据的形状以及它与其他模型、表和库之间的关系。在这种情况下,数据库条目是 schema 的一个实例,包含 schema 中描述的所有属性。

数据库 schema 通常分为两类:定义数据文件实际存储方式的**物理数据库 schema ;和逻辑数据库 schema **,它描述了应用于存储数据的所有逻辑约束,包括完整性、表和视图。常见包括

  • 星型模式(star schema)

  • 雪花模式(snowflake schema)

  • 事实星座模型(fact constellation schema 或 galaxy schema)

星型模式是类似于一个简单的数据仓库图,包括一对多的事实表和维度表。它使用非规范化数据。

153830e837af0659f6240e40f914f741.png

雪花模式是更为复杂的一种流行的数据库模式,在该模式下,维度表是规范化的,可以节省存储空间并最大限度地减少数据冗余。

事实星座模式远比星型模式和雪花模式复杂得多。它拥有多个共享多个维度表的事实表。

03bea4e8dfc391ae0e8f6a9c889ebba9.png

Kubernetes 中的 schema

通过上面的阐述,大概上可以明白 schema 究竟是什么东西了,在 Kubernetes 中也有 schema 的概念,通过对 kubernetes 中资源(GVK)的规范定义、相互关系间的映射等,schema 即 k8s 资源对象元数据。

而 kubernetes 中资源对象即  Group Version Kind 这些被定义在 staging/src/k8s.io/api/type.go 中,即平时所操作的 yaml 文件,例如

apiVersion: apps/v1
kind: Deployment  
metadata:
  name:  ngx
  namespace: default
spec:
  selector:  
    matchLabels:
      app: ngx
  template:  
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: ngx-schema
        image: nginx
        ports:
        - containerPort: 80
51b6c8fba53674817eafd586daa610cb.png

而对应的的即为 TypeMetaObjectMetaDeploymentSpec,

TypeMeta` 为 `kind` 与 `apiserver

ObjectMeta 为  NameNamespace  CreationTimestamp 等段。

DeploymentSpec 则对应了 yaml 中的 spec。

而整个 yaml 组成了 一个 k8s 的资源对象。

type Deployment struct {
 metav1.TypeMeta `json:",inline"`
 // Standard object metadata.
 // +optional
 metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

 // Specification of the desired behavior of the Deployment.
 // +optional
 Spec DeploymentSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`

 // Most recently observed status of the Deployment.
 // +optional
 Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}

register.go 则是将对应的资源类型注册到 schema 中的类

var (
 // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
 // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
 SchemeBuilder      = runtime.NewSchemeBuilder(addKnownTypes)
 localSchemeBuilder = &SchemeBuilder
 AddToScheme        = localSchemeBuilder.AddToScheme
)

// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
 scheme.AddKnownTypes(SchemeGroupVersion,
  &Deployment{},
  &DeploymentList{},
  &StatefulSet{},
  &StatefulSetList{},
  &DaemonSet{},
  &DaemonSetList{},
  &ReplicaSet{},
  &ReplicaSetList{},
  &ControllerRevision{},
  &ControllerRevisionList{},
 )
 metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 return nil
}

apimachinery 包则是 schema 的实现,通过看其内容可以发下,kubernetes 中 schema 就是 GVK 的属性约束 与 GVR 之间的映射。

通过示例了解 schema

例如在 apps/v1/deployment 这个资源,在代码中表示 k8s.io/api/apps/v1/types.go ,如果需要对其资源进行扩展那么需要怎么做?如,建立一个 StateDeplyment 资源

type Deployment struct {
 metav1.TypeMeta `json:",inline"`
 // Standard object metadata.
 // +optional
 metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

如上述代码所示,Deployment 中的 metav1.TypeMetametav1.ObjectMeta

5e740968d5904dce169df3f5356be516.png

那么我们复制一个 Deployment 为 StateDeployment,注意,因为 Deployment 的两个属性, metav1.TypeMetametav1.ObjectMeta 分别实现了不同的方法,如图所示

40f0ce5822976674e4fd12d6d582df1d.png

所以在实现方法时,需要实现 DeepCopyinfoDeepCopy  和继承接口 ObjectDeepCopyObject 方法

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StateDeployment) DeepCopyInto(out *StateDeployment) {
 *out = *in
 out.TypeMeta = in.TypeMeta
 in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
 in.Spec.DeepCopyInto(&out.Spec)
 in.Status.DeepCopyInto(&out.Status)
 return
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StateDeployment.
func (in *StateDeployment) DeepCopy() *StateDeployment {
 if in == nil {
  return nil
 }
 out := new(StateDeployment)
 in.DeepCopyInto(out)
 return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *StateDeployment) DeepCopyObject() runtime.Object {
 if c := in.DeepCopy(); c != nil {
  return c
 }
 return nil
}

那么扩展一个资源的整个流为:

  • 资源类型在:k8s.io/api/{Group}/types.go

  • 资料类型的实现接口 k8s.io/apimachinery/pkg/runtime/interfaces.go.Object

  • 其中是基于 Deployment 的类型,metav1.TypeMetametav1.ObjectMeta

  • metav1.TypeMeta 实现了 GetObjectKind()metav1.ObjectMeta 实现了 DeepCopyinfo=()DeepCopy() ,还需要实现 DeepCopyObject()

  • 最后注册资源到 schema 中 k8s.io/api/apps/v1/register.go

d0f62da126199254386351c2105abde6.gif

8f35cc1288b732248cbf4475ec869a91.png

你可能还喜欢

点击下方图片即可阅读

Cilium 开源 Tetragon – 基于 eBPF 的安全可观测性 & 运行时增强

2022-05-18

37f5b24758d286041a3947ff32c6828d.png

云开发中的战斗机 Laf,让你像写博客一样写代码

2022-05-16

e6f35a2bcb869e82b661fb9b2a307df0.png

使用 Grafana 和 Loki 监控传说中的武当纵云梯

2022-05-15

13acc80c2e4abdea53fd0a8fdcfcb009.png

Admission Webhook 花式玩法,骚得很

2022-05-13

972b588a239142614ebed4eed86aa20c.png

da80dc973bf83a44d4a1e75b82bde828.gif

云原生是一种信仰 🤘

关注公众号

后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!

a214e989d7d3ba5a6cb84d8865a06dda.gif

162a9f0d0ef14651163806e9aeac1540.gif

点击 "阅读原文" 获取更好的阅读体验!

发现朋友圈变“安静”了吗?

67c8b32e0cb40e90e57a9484491d77c7.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值