apiserver源码分析——处理请求 (6)

到Creater.Create是一个接口的调用,这里实现太多,无法单纯通过goland去找到实现。但这个Creater已经是storage的一个接口,在目录中找pod的storage相关定义在 /pkg/registry/core/pod/storage/storage.go中
对应的结构定义如下

type REST struct { *genericregistry.Store proxyTransport http.RoundTripper }

它继承于genericregistry.Store,自身并没有再去实现Creater接口了

genericregistry.Store的定义在/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go

所实现的Create方法大概包含下面步骤

调用了validate准入控制器验证资源

生成name,key等信息用于后续持久化到Etcd

创建一个新的空的资源用于成功时返回结果

调用storage的Create,准备持久化到Etcd

func (e *Store) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if err := rest.BeforeCreate(e.CreateStrategy, ctx, obj); err != nil { return nil, err } // at this point we have a fully formed object. It is time to call the validators that the apiserver // handling chain wants to enforce. //调用了validate准入控制器验证资源 if createValidation != nil { if err := createValidation(ctx, obj.DeepCopyObject()); err != nil { return nil, err } } //生成name,key等信息用于后续持久化到Etcd name, err := e.ObjectNameFunc(obj) if err != nil { return nil, err } key, err := e.KeyFunc(ctx, name) if err != nil { return nil, err } qualifiedResource := e.qualifiedResourceFromContext(ctx) ttl, err := e.calculateTTL(obj, 0, false) if err != nil { return nil, err } //创建一个新的空的资源用于成功时返回结果 out := e.NewFunc() //调用storage的Create,准备持久化到Etcd //如果持久化成功,out里面就会填上持久化后的所有信息到里面 if err := e.Storage.Create(ctx, key, obj, out, ttl, dryrun.IsDryRun(options.DryRun)); err != nil { err = storeerr.InterpretCreateError(err, qualifiedResource, name) err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj) if !apierrors.IsAlreadyExists(err) { return nil, err } if errGet := e.Storage.Get(ctx, key, storage.GetOptions{}, out); errGet != nil { return nil, err } accessor, errGetAcc := meta.Accessor(out) if errGetAcc != nil { return nil, err } if accessor.GetDeletionTimestamp() != nil { msg := &err.(*apierrors.StatusError).ErrStatus.Message *msg = fmt.Sprintf("object is being deleted: %s", *msg) } return nil, err } if e.AfterCreate != nil { if err := e.AfterCreate(out); err != nil { return nil, err } } if e.Decorator != nil { if err := e.Decorator(out); err != nil { return nil, err } } return out, nil } 持久化到Etcd

从e.Storage.Create经过两层调用到达store.Create方法,因为有可能包含dryRun,如果dryRun就不需要持久化到Etcd,在这里将看到

将资源转换成无版本类型,即__internal版本

再将资源转换成适合存储的格式

调用Etcd检查资源是否已经存在了

不存在才调用Put把资源存进去

成功了才从etcd的响应中把存储结果反序列化成传进来时的格式

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwpsds.html