找回密码
 立即注册
查看: 329|回复: 0

理解 Kubernetes 的 API Schema

[复制链接]
发表于 2022-6-17 15:23 | 显示全部楼层 |阅读模式
schema 一词起源于希腊语中的 form 或 figure,但具体应该如何定义 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)
星型模式是类似于一个简单的数据仓库图,包括一对多的事实表和维度表。它使用非规范化数据。


雪花模式是更为复杂的一种流行的数据库模式,在该模式下,维度表是规范化的,可以节省存储空间并最大限度地减少数据冗余。
事实星座模式远比星型模式和雪花模式复杂得多。它拥有多个共享多个维度表的事实表。


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


而对应的的即为 TypeMeta 、ObjectMeta 和 DeploymentSpec,TypeMeta 为 kind 与 apiserver,ObjectMeta 为 Name 、Namespace 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.TypeMeta 和 metav1.ObjectMeta


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


所以在实现方法时,需要实现 DeepCopyinfo , DeepCopy 和继承接口 Object 的 DeepCopyObject 方法
// 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.TypeMeta 和 metav1.ObjectMeta
  • metav1.TypeMeta 实现了 GetObjectKind() ;metav1.ObjectMeta 实现了 DeepCopyinfo=(),DeepCopy() ,还需要实现 DeepCopyObject()
  • 最后注册资源到 schema 中 k8s.io/api/apps/v1/register.go
链接:https://www.cnblogs.com/Cylon/p/16282407.html
运维君莫笑:Kubernetes 网络插件 Calico 完全运维指南
运维君莫笑:大规模 K8s 集群 ApiServer/Etcd LIST 请求性能瓶颈和调优实践
运维君莫笑:轻量级 Kubernetes 集群发行版 K3s 完全进阶指南
运维君莫笑:详解 K8S Pod 高级调度策略
运维君莫笑:5 款强大的 Kubernetes Events 收集与检索工具
运维君莫笑:Kubernetes的复杂和高准入门槛,只是暂时的
运维君莫笑:使用 Thanos 和 Prometheus 打造一个高可用的 Kubernetes 监控系统
运维君莫笑:容器与Pod到底有什么区别和联系?
运维君莫笑:Docker+K8s 零基础从入门到进阶
运维君莫笑:几张大图就把 Kubernetes Ingress 来龙去脉搞清楚了,看完后真“香”
运维君莫笑:Kubernetes 4000 节点运维经验分享
运维君莫笑:K8S Service实战与原理初探
运维君莫笑:深度揭秘阿里云 Serverless Kubernetes

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-6-5 23:49 , Processed in 0.241303 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表