10月30日总结

发布时间 2023-11-05 08:47:07作者: lmyyyy

1.2.2 创建 APIExtensions Server

创建完通用 APIServer 后继续创建 APIExtensions Server。

func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*CustomResourceDefinitions, error) {
genericServer, err := c.GenericConfig.New("apiextensions-apiserver", delegationTarget)

s := &CustomResourceDefinitions{
	GenericAPIServer: genericServer,
}

// 存储建立 REST API 到资源实体的信息
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiextensions.GroupName, Scheme, metav1.ParameterCodec, Codecs)

// 资源实体
storage := map[string]rest.Storage{}

// customresourcedefinitions
if resource := "customresourcedefinitions"; apiResourceConfig.ResourceEnabled(v1.SchemeGroupVersion.WithResource(resource)) {
    // 创建资源实体
	customResourceDefinitionStorage, err := customresourcedefinition.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter)
	if err != nil {
		return nil, err
	}
	storage[resource] = customResourceDefinitionStorage
	storage[resource+"/status"] = customresourcedefinition.NewStatusREST(Scheme, customResourceDefinitionStorage)
}
if len(storage) > 0 {
	apiGroupInfo.VersionedResourcesStorageMap[v1.SchemeGroupVersion.Version] = storage
}

if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {
	return nil, err
}

APIGroupInfo 对象用于描述资源组信息,storage 存储资源到资源实体的对应关系。

资源实体,通过 NewREST() 函数创建。

kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go

package customresourcedefinition

// NewREST returns a RESTStorage object that will work against API services.
func NewREST(scheme runtime.Scheme, optsGetter generic.RESTOptionsGetter) (REST, error) {
strategy := NewStrategy(scheme)

store := &genericregistry.Store{
	NewFunc:                   func() runtime.Object { return &apiextensions.CustomResourceDefinition{} },
	NewListFunc:               func() runtime.Object { return &apiextensions.CustomResourceDefinitionList{} },
	PredicateFunc:             MatchCustomResourceDefinition,
	DefaultQualifiedResource:  apiextensions.Resource("customresourcedefinitions"),
	SingularQualifiedResource: apiextensions.Resource("customresourcedefinition"),

	CreateStrategy:      strategy,
	UpdateStrategy:      strategy,
	DeleteStrategy:      strategy,
	ResetFieldsStrategy: strategy,

	// TODO: define table converter that exposes more than name/creation timestamp
	TableConvertor: rest.NewDefaultTableConvertor(apiextensions.Resource("customresourcedefinitions")),
}
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
	return nil, err
}
return &REST{store}, nil

}

可以看到,资源实体是在资源包 customresourcedefinition 的 etcd.go 中创建的,创建的资源实体负责和 etcd 交互。
(关于 etcd 交互的部分先不讲,后续会专门介绍。)

创建完资源实体后,通过 apiGroupInfo.VersionedResourcesStorageMap[v1.SchemeGroupVersion.Version] = storage 将资源实体存储到 apiGroupInfo。

继续调用 InstallAPIGroup(apiGroupInfo *APIGroupInfo) 安装 REST API。

kubernetes/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go