資源類型Scheme

資源類型Scheme

1、介紹

當我們操作資源和 apiserver 進行通信的時候,需要根據資源對象類型的 Group、Version、Kind 以及規範定義、編解碼等內容構成 Scheme 類型,然後 Clientset 對象就可以來訪問和操作這些資源類型了,Scheme 的定義主要在 api 子項目之中,源碼倉庫地址: https://github.com/kubernetes/api ,被同步到 Kubernetes 源碼的 staging/src/k8s.io/api 之下。

主要就是各種資源對象的原始結構體定義,比如查看apps/v1目錄下面的定義:

$ tree staging/src/k8s.io/api/apps/v1
staging/src/k8s.io/api/apps/v1
├── doc.go
├── generated.pb.go
├── generated.proto
├── register.go
├── types.go
├── types_swagger_doc_generated.go
└── zz_generated.deepcopy.go

0 directories, 7 files

2、types.go

其中 types.go 文件裏面就是 apps/v1 這個 GroupVersion 下面所有的資源對象的定義,有 Deployment、DaemonSet、StatefulSet、ReplicaSet 等幾個資源對象,比如 Deployment 的結構體定義如下所示:

![image-20220429093909437](/Users/Christian/Library/Application Support/typora-user-images/image-20220429093909437.png)

由 TypeMeta、ObjectMeta、DeploymentSpec 以及 DeploymentStatus 4個屬性組成,和我們使用 YAML 文件定義的 Deployment 資源對象也是對應的。

apiVersion: apps/v1
kind: Deployment  
metadata:
  name:  nginx-deploy
  namespace: default
spec:
  selector:  
    matchLabels:
      app: nginx
  template:  
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

其中 apiVersionkind 就是 TypeMeta 屬性,metadata 屬性就是 ObjectMeta,spec 屬性就是 DeploymentSpec,當資源部署過後也會包含一個 status 的屬性,也就是 DeploymentStatus ,這樣就完整的描述了一個資源對象的模型。

3、zz_generated.deepcopy.go

上面定義的規範在 Kubernetes 中稱爲資源類型 Scheme,此外zz_generated.deepcopy.go 文件是由 deepcopy-gen 工具創建的定義各資源類型 DeepCopyObject() 方法的文件,所有註冊到 Scheme 的資源類型都要實現 runtime.Object 接口:

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

而所有的資源類型都包含一個 TypeMeta 類型,而該類型實現了 GetObjectKind() 方法,所以各資源類型只需要實現 DeepCopyObject() 方法即可:

// staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }

各個資源類型的 DeepCopyObject() 方法也不是手動定義,而是使用 deepcopy-gen 工具命令統一自動生成的,該工具會讀取 types.go 文件中的 +k8s:deepcopy-gen 註釋,以 Deployment 爲例:

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Deployment enables declarative updates for Pods and ReplicaSets.
type Deployment struct {
	......
}

然後將自動生成的代碼保存到 zz_generated.deepcopy.go 文件中。

4、register.go文件

register.go 文件的主要作用是定義AddToScheme函數,將各種資源類型註冊到 ``Clientset 使用的 Scheme 對象中去,由於每個資源自動生成了 DeepCopyObject() 方法,這樣資源就實現了 runtime.Object `接口,所以可以註冊到 Scheme 中去了。

// staging/src/k8s.io/api/apps/v1/register.go

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 方法用於註冊該 Group/Version 下所有資源類型
	AddToScheme        = localSchemeBuilder.AddToScheme
)


// staging/src/k8s.io/client-go/kubernetes/scheme/register.go

// 定義一個 Scheme,將各類資源對象都添加到該Scheme
var Scheme = runtime.NewScheme()
// 爲 Scheme 中的所有類型創建一個編解碼工廠
var Codecs = serializer.NewCodecFactory(Scheme)
// 爲 Scheme 中的所有類型創建一個參數編解碼工廠
var ParameterCodec = runtime.NewParameterCodec(Scheme)
// 將各 k8s.io/api/<Group>/<Version> 目錄下資源類型的 AddToScheme() 方法註冊到 SchemeBuilder 中
var localSchemeBuilder = runtime.SchemeBuilder{
	admissionregistrationv1.AddToScheme,
	admissionregistrationv1beta1.AddToScheme,
	internalv1alpha1.AddToScheme,
	appsv1.AddToScheme,
	appsv1beta1.AddToScheme,
	appsv1beta2.AddToScheme,
	authenticationv1.AddToScheme,
	authenticationv1beta1.AddToScheme,
	authorizationv1.AddToScheme,
	authorizationv1beta1.AddToScheme,
	autoscalingv1.AddToScheme,
	autoscalingv2.AddToScheme,
	autoscalingv2beta1.AddToScheme,
	autoscalingv2beta2.AddToScheme,
	batchv1.AddToScheme,
	batchv1beta1.AddToScheme,
	certificatesv1.AddToScheme,
	certificatesv1beta1.AddToScheme,
	coordinationv1beta1.AddToScheme,
	coordinationv1.AddToScheme,
	corev1.AddToScheme,
	discoveryv1.AddToScheme,
	discoveryv1beta1.AddToScheme,
	eventsv1.AddToScheme,
	eventsv1beta1.AddToScheme,
	extensionsv1beta1.AddToScheme,
	flowcontrolv1alpha1.AddToScheme,
	flowcontrolv1beta1.AddToScheme,
	flowcontrolv1beta2.AddToScheme,
	networkingv1.AddToScheme,
	networkingv1beta1.AddToScheme,
	nodev1.AddToScheme,
	nodev1alpha1.AddToScheme,
	nodev1beta1.AddToScheme,
	policyv1.AddToScheme,
	policyv1beta1.AddToScheme,
	rbacv1.AddToScheme,
	rbacv1beta1.AddToScheme,
	rbacv1alpha1.AddToScheme,
	schedulingv1alpha1.AddToScheme,
	schedulingv1beta1.AddToScheme,
	schedulingv1.AddToScheme,
	storagev1beta1.AddToScheme,
	storagev1.AddToScheme,
	storagev1alpha1.AddToScheme,
}

var AddToScheme = localSchemeBuilder.AddToScheme

func init() {
	v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
	// 調用 SchemeBuilder 中各資源對象的 AddToScheme() 方法,將它們註冊到到 Scheme 對象
	utilruntime.Must(AddToScheme(Scheme))
}

將各類資源類型註冊到全局的 Scheme 對象中,這樣 Clientset 就可以識別和使用它們了。

apimachinery 子項目主要是 Kubernetes 服務端和客戶端項目都共同依賴的一些公共方法、struct、工具類的定義,主要服務於 kubernetes、client-go、apiserver 這三個項目。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章