理解 Kubernetes 的 API Schema

    作者:匿名更新于: 2022-06-19 11:51:35

      在 Kubernetes 中也有 schema 的概念,通过对 kubernetes 中资源(GVK)的规范定义、相互关系间的映射等,schema 即 k8s 资源对象元数据。

      词起源于希腊语中的 ​​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 文件,例如

      复制

      1. apiVersion: apps/v1

      2. kind: Deployment

      3. metadata:

      4. name: ngx

      5. namespace: default

      6. spec:

      7. selector:

      8. matchLabels:

      9. app: ngx

      10. template:

      11. metadata:

      12. labels:

      13. app: nginx

      14. spec:

      15. containers:

      16. - name: ngx-schema

      17. image: nginx

      18. ports:

      19. - containerPort: 80 

      而对应的的即为 ​​TypeMeta​​​ 、​​ObjectMeta​​​ 和 ​​DeploymentSpec​​​,​​TypeMeta​​​ 为 ​​kind​​​ 与 ​​apiserver​​​,​​ObjectMeta​​​ 为 ​​Name​​​ 、​​Namespace​​​ ​​CreationTimestamp​​ 等段。

      ​​DeploymentSpec​​ 则对应了 yaml 中的 spec。

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

      复制

      1. type Deployment struct {

      2. metav1.TypeMeta `json:",inline"`

      3. // Standard object metadata.

      4. // +optional

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

      6.

          7. // Specification of the desired behavior of the Deployment.

      8. // +optional

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

         10.

      11. // Most recently observed status of the Deployment.

      12. // +optional

      13. Status DeploymentStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`

      14. }1.2.3.4.5.6.7.8.9.10.11.12.13.14.

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

      复制

      1. var (

      2. // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.

      3. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.

      4. SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

      5. localSchemeBuilder = &SchemeBuilder

      6. AddToScheme = localSchemeBuilder.AddToScheme

      7. )

          8.

      9. // Adds the list of known types to the given scheme.

      10. func addKnownTypes(scheme *runtime.Scheme) error {

      11. scheme.AddKnownTypes(SchemeGroupVersion,

      12. &Deployment{},

      13. &DeploymentList{},

      14. &StatefulSet{},

      15. &StatefulSetList{},

      16. &DaemonSet{},

      17. &DaemonSetList{},

      18. &ReplicaSet{},

      19. &ReplicaSetList{},

      20. &ControllerRevision{},

      21. &ControllerRevisionList{},

      22. )

      23. metav1.AddToGroupVersion(scheme, SchemeGroupVersion)

      24. return nil

      25. }

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

      通过示例了解 schema

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

      复制

      1. type Deployment struct {

      2. metav1.TypeMeta `json:",inline"`

      3. // Standard object metadata.

      4. // +optional

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

       如上述代码所示,Deployment 中的 ​​metav1.TypeMeta​​​ 和 ​​metav1.ObjectMeta​​

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

      8所以在实现方法时,需要实现 ​​DeepCopyinfo​​​ , ​​DeepCopy​​​ 和继承接口 ​​Object​​​ 的 ​​DeepCopyObject​​ 方法

      复制

      1. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

      2. func (in *StateDeployment) DeepCopyInto(out *StateDeployment) {

      3. *out = *in

      4. out.TypeMeta = in.TypeMeta

      5. in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)

      6. in.Spec.DeepCopyInto(&out.Spec)

      7. in.Status.DeepCopyInto(&out.Status)

      8. return

      9. }

         10.

      11. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StateDeployment.

      12. func (in *StateDeployment) DeepCopy() *StateDeployment {

      13. if in == nil {

      14. return nil

      15. }

      16. out := new(StateDeployment)

      17. in.DeepCopyInto(out)

      18. return out

      19. }

          20. 

      21. // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

      22. func (in *StateDeployment) DeepCopyObject() runtime.Object {

      23. if c := in.DeepCopy(); c != nil {

      24. return c

      25. }

      26. return nil

      27. }

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

      资源类型在:​​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​

      >>>>>>点击进入系统运维专题

系统运维 更多推荐

课课家教育

未登录