1. 在主节点master中注册api入口
// kubernetes/pkg/master/master.go
kubernets/pkg/master/master.go
func New(c *Config)(*Master, error) {
m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...)
}
InstallAPIs方法中的第一个参数用来验证api的版本信息,后面的参数都与存储有关。
type APIResourceConfigSourceinterface {
VersionEnabled(version schema.GroupVersion) bool
AnyVersionForGroupEnabled(group string) bool
}
2. 根据Config往APIGroupsInfo内增加组信息,然后通过InstallAPIGroups进行注册
// InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
func (m *Master) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) {
/*用传入的版本信息和存储信息构建apiGroupsInfo,结构如下:
(APIGroupInfo类型的很多参数都是schema.GroupVersion类型,这种类型里面只有两个string类型的字段Group和Version。)
type APIGroupInfo struct {
PrioritizedVersions []schema.GroupVersion
// 从版本到资源再到存储的map
VersionedResourcesStorageMap map[string]map[string]rest.Storage
// OptionsExternalVersion controls the APIVersion used for common objects in the // schema like api.Status, api.DeleteOptions, and metav1.ListOptions. Other implementors may // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. // If nil, defaults to groupMeta.GroupVersion.
OptionsExternalVersion *schema.GroupVersion
// 默认值为 "meta.k8s.io/v1" and is the scheme group version used to decode // common API implementations like ListOptions.
MetaGroupVersion *schema.GroupVersion
// Scheme includes all of the types used by this group and how to convert between them (or // to convert objects from outside of this group that are accepted in this API).
Scheme *runtime.Scheme
// NegotiatedSerializer controls how this group encodes and decodes data
NegotiatedSerializer runtime.NegotiatedSerializer
// ParameterCodec performs conversions for query parameters passed to API calls ParameterCodec runtime.ParameterCodec
}
*/
apiGroupsInfo := []genericapiserver.APIGroupInfo{}
......
for i :=range apiGroupsInfo {
if err := m.GenericAPIServer.InstallAPIGroup(&apiGroupsInfo[i]); err != nil {
glog.Fatalf("Error in registering group versions: %v", err)
}
}
}
3. k8s.io/apiserver/pkg/server/genericapiserver.go
// Exposes the given api group in the API.
func (s *GenericAPIServer) InstallAPIGroup(apiGroupInfo *APIGroupInfo) error {
......
if err := s.installAPIResources(APIGroupPrefix, apiGroupInfo); err != nil {
return err
}
// 在/apis/添加一个枚举出group中所有支持version的api接口
......
s.DiscoveryGroupManager.AddGroup(apiGroup)
s.Handler.GoRestfulContainer.Add(discovery.NewAPIGroupHandler(s.Serializer, apiGroup).WebService())
......
}
4. k8s.io/apiserver/pkg/server/genericapiserver.go
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource
func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo) error {
......
apiGroupVersion := s.getAPIGroupVersion(apiGroupInfo, groupVersion, apiPrefix)
......
if err := apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer); err != nil {
return fmt.Errorf("unable to setup API %v: %v", apiGroupInfo, err)
}
}
return nil
}
首先获得apiGroupVersion(v1beta)等信息,然后由apiGroupVersion调用InstallREST方法完成后续。
5. k8s.io/apiserver/pkg/endpoints/groupversion.go
// InstallREST将REST handlers(storage, watch, proxy and redirect)注册到一个restful容器中
func (g *APIGroupVersion) InstallREST(container *restful.Container) error {
prefix := path.Join(g.Root, g.GroupVersion.Group, g.GroupVersion.Version)
installer := &APIInstaller{
group: g,
prefix: prefix,
minRequestTimeout: g.MinRequestTimeout,
enableAPIResponseCompression: g.EnableAPIResponseCompression,
}
apiResources, ws, registrationErrors := installer.Install()
versionDiscoveryHandler := discovery.NewAPIVersionHandler(g.Serializer, g.GroupVersion, staticLister{apiResources})
versionDiscoveryHandler.AddToWebService(ws)
container.Add(ws)
return utilerrors.NewAggregate(registrationErrors)
}