Skip to content

Start a Kube API Server

In this article, I will describe the workflow of the start of a kube-apiserver.

In some parts related to the Cacher we will mention in WATCH, I will explore the codes deeper.

The version of the code base is kubernete v1.16. Have fun!

Overview

This is a brief description of how the kube-apiser starts. When you run the command kube-apiserver, what is happening?

stateDiagram-v2
    state kubernetes/cmd/kubeapiserver/apiserver.go {
        [*] --> app.NewAPIServerCommand()
        app.NewAPIServerCommand() --> NewAPIServerCommand
        app.NewAPIServerCommand() --> command.Execute()
        command.Execute() --> Run()
    }
    state kubernetes/cmd/kubeapiserverapp/server.go {
        NewAPIServerCommand --> RunE
        RunE --> Run()
        Run() --> CreateServerChain()
        CreateServerChain() --> server.PrepareRun()
        server.PrepareRun() --> prepared.Run(stopCh)

    }

Create Server Chain

stateDiagram-v2
    state kubernetes/cmd/kubeapiserver {
        state app/server.go {
            CreateServerChain --> CreateKubeAPIServerConfig()
            CreateKubeAPIServerConfig() --> kubeAPIServerConfig
            kubeAPIServerConfig --> createAPIExtensionsConfig()
            createAPIExtensionsConfig() --> apiExtensionsConfig
            apiExtensionsConfig --> createAPIExtensionsServer()
            kubeAPIServerConfig --> createAPIExtensionsServer()
            createAPIExtensionsServer() --> apiExtensionsServer
            kubeAPIServerConfig --> CreateKubeAPIServer()
            apiExtensionsServer --> CreateKubeAPIServer()
            CreateKubeAPIServer() --> kubeAPIServer
            kubeAPIServerConfig --> createAggregatorConfig()
            createAggregatorConfig() --> aggregatorConfig
            kubeAPIServer --> createAggregatorServer()
            aggregatorConfig --> createAggregatorServer()
            createAggregatorServer() --> aggregatorServer
            kubeAPIServerConfig --> buildGenericConfig()
        }
    }

Create Kube API Server Config

Overview

stateDiagram-v2
    state kubernetes/cmd/kubeapiserver/app/server.go {
        state CreateKubeAPIServerConfig() {
            [*] --> buildGenericConfig()
            config
            state genericConfig {
                MergedResourceConfig
            }
        }
    }

    buildGenericConfig() --> genericConfig
    state kubernetes/pkg/master {
        state master.go {
            DefaultAPIResourceConfigSource()
            state Config {
                GenericConfig
            }
        }
    }
    DefaultAPIResourceConfigSource() --> MergedResourceConfig
    genericConfig --> GenericConfig
    Config --> config

Build Generic Config

stateDiagram-v2
        state buildGenericConfig() {
            [*] --> NewConfig()
            genericConfig
            state storageFactoryConfig {
                ApiResourceConfig
                Complete(s.Etcd)
            }
            state completedStorageFactoryConfig {
                New()
            }
            storageFactory
            s.Etcd.ApplyWithStorageFactoryTo(storageFactory,genericConfig)
            state k8s.io/apiserver/pkg/server/config.go {
                Config
                NewConfig()
            }
            state k8s.io/kubernetes/pkg/kubeapiserver {
                state default_storage_factory_builder.go {
                    NewStorageFactoryConfig()
                }
            }
        }

        state k8s.io/apiserver/pkg/server/options/etcd.go {
            state EtcdOptions {
                ApplyWithStorageFactoryTo(storageFactory,genericConfig)
            }
            state StorageFactoryRestOptionsFactory {
                StorageFactory
            }
        }

    state state kuberenetes/cmd/kubeapiserver/app/options.go {
        state ServerRunOptions {
            GenericServerRunOptions
            Etcd
            OtherOptions
        }
    }
    NewConfig() --> Config
    Config --> genericConfig
    genericConfig --> NewStorageFactoryConfig()
    NewStorageFactoryConfig() --> storageFactoryConfig
    ApiResourceConfig --> Complete(s.Etcd)
    Complete(s.Etcd) --> completedStorageFactoryConfig
    New() --> storageFactory
    storageFactory --> s.Etcd.ApplyWithStorageFactoryTo(storageFactory,genericConfig)
    s.Etcd.ApplyWithStorageFactoryTo(storageFactory,genericConfig) --> ServerRunOptions
    Etcd --> EtcdOptions
    ApplyWithStorageFactoryTo(storageFactory,genericConfig) --> StorageFactoryRestOptionsFactory
    StorageFactoryRestOptionsFactory --> genericConfig.RESTOptionsGetter
    storageFactory --> StorageFactory

StorageFactoryRestOptionsFactory

StorageFactoryRestOptionsFactory's method GetRESTOptions will set the Storage Decorator with a Cacher. The rest of the logics about how the cacher and watchCache work can be found in the Watch Implementation document.

stateDiagram-v2
    state StorageFactoryRestOptionsFactory {
        Options
        StorageFactory
        state GetRESTOptions() {
            genericregistry.StorageWithCacher(cacheSize)
        }
    }
    state k8s.io/apiserver/pkg/registry/generic/registry {
        state store_factory.go {
            StorageWithCacher(cacheSize)
            cacherstorage.NewCacherFromConfig(cacherConfig)
        }
    }
    state k8s.io/apiserver/pkg/storage/cacher {
        state cacher.go {
            NewCacherFromConfig(cacherConfig)
        }
    }
    genericregistry.StorageWithCacher(cacheSize) --> StorageWithCacher(cacheSize)
    StorageWithCacher(cacheSize) --> cacherstorage.NewCacherFromConfig(cacherConfig)
    cacherstorage.NewCacherFromConfig(cacherConfig) --> NewCacherFromConfig(cacherConfig)

Create Kube API Server

stateDiagram-v2
    state k8s.io/apiserver/pkg/server {
        state config.go {
            [*] --> kubeAPIServerConfig.Complete().New()
            Config.Complete()
            CompletedConfig.New()
            installAPI()
        }
    }
    kubeAPIServerConfig.Complete().New() --> Config.Complete()
    Config.Complete() --> CompletedConfig.New()
    CompletedConfig.New() --> installAPI()

Create Agregator Server

Overview

stateDiagram-v2
    state kubernetes/cmd/kubeapiserver/app/aggregator.go {
        createAggregatorConfig() --> createAggregatorServer()
    }
    state k8s.io/kube-aggregator/pkg/apiserver/apiserver.go {
        state Config {
            Complete()
        }
        state completedConfig.NewWithDelegate(KubeAPIServer) {
            NewRESTStorage(c.GenericConfig.MergedResourceConfig,c.GenericConfig.RESTOptionsGetter)
            NewRESTStorage(c.GenericConfig.MergedResourceConfig,c.GenericConfig.RESTOptionsGetter) --> apiGroupInfo
            apiGroupInfo --> s.GenericAPIServer.InstallAPIGroup
        }
    }
    state k8s.io/apiserver/pkg/server/generaicapiserver.go {
        state GenericAPIServer {
        InstallAPIGroup() --> InstallAPIGroups()
            InstallAPIGroups() --> installAPIResources
            installAPIResources --> getAPIGroupVersion()
            getAPIGroupVersion() --> newAPIGroupVersion()
        }
    }
    state k8s.io/apiserver/pkg/endpoints {
        state groupversion.go {
            state APIGroupVersion {
                InstallREST() --> Install()
            }
        }
        state installer.go {
            state APIInstaller {
                Install() --> registerResourceHandlers()
            }
        }
    }
    createAggregatorServer() --> Complete()
    Complete() --> NewRESTStorage(c.GenericConfig.MergedResourceConfig,c.GenericConfig.RESTOptionsGetter)
    s.GenericAPIServer.InstallAPIGroup --> InstallAPIGroup()
    newAPIGroupVersion() --> InstallREST()

NewRESTStorage

Here, the restOptionsGetter is the genericConfig's RestOptionGetter, which is previously set with an instance of StorageFactoryRestOptionsFactory.

stateDiagram-v2
    state k8s.io/kube-aggregator/pkg/registry/apiservice/rest/rest.go {
        [*] --> NewRESTStorage()
    }
    state k8s.io/apiserver/pkg/server/generaicapiserver.go {
        state APIGroupInfo {
            VersionedResourcesStorageMap
        }
        NewDefaultAPIGroupInfo()
    }
    state k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go {
        state NewREST(Scheme,restOptionsGetter) {
            state StoreOptions {
                RESTOptions_restOptionsGetter
                AttrFunc
            }
        }
    }
    state k8s.io/apiserver/pkg/registry/generic/registry/store.go {
        CompleteWithOptions(options) --> options.RESTOptions.GetRESTOptions()
        options.RESTOptions.GetRESTOptions() --> e.Storage.Storage,e.DestroyFunc,err=opts.Decorator(opts.StorageConfig,..)
    }
    NewRESTStorage() --> NewDefaultAPIGroupInfo()
    NewDefaultAPIGroupInfo() --> APIGroupInfo
    NewRESTStorage() --> NewREST(Scheme,restOptionsGetter)
    NewREST(Scheme,restOptionsGetter) --> CompleteWithOptions(options)