k8s :kube-apiserver 啓動流程 - 1

前言

看 k8s 源代碼有一段時間,總感受在迷宮裏亂竄,有時候以爲終於找到出口了,一會兒又撞牆了,總結下來仍是本身的內功不夠深厚,本文是對 kube-apiserver Legacy(遺留,即將廢棄)API 初始化流程(以及數據結構)的一個梳理,算是作個"路標",便於之後在"迷宮"中還能找到回來的路後端

kube-apiserver 主要功能是提供 api 接口給客戶端訪問 後端 etcd 存儲,固然這中間不光是簡單的 key/value 存儲,爲了方便擴展,kube-apiserver 設計了一套代碼框架將 "資源對象" 映射到 RESTful APIapi

本文梳理了一下 kube-apiserver 啓動流程和相關數據結構數據結構

k8s 代碼更新比較快,本文基於 k8s release-1.9.x 代碼app

數據結構

kube-apiserver 啓動流程相關的(主要)數據結構框架

  • XXXOptions 命令行參數相關的類
  • XXXConfig 配置相關的類
  • XXXServer kube-apiserver 服務對象
  • XXXStorage 資源對象,好比 PosStorage,經過 XXXStorage 操做後端存儲(etcd)

Options,Config 和 Server 對象的(大體)關係:
由 Options 對象建立(配置) Config 對象,而後由 Config 對象建立(配置) Server 對象ide

ServerRunOptions

ServerRunOptions 類封裝了 kube-apiserver 命令行參數,這些參數按照不一樣的類別進行分組函數

// kubernetes/cmd/kube-apiserver/app/options/options.go
import (
    ...
    genericoptions "k8s.io/apiserver/pkg/server/options"
    ...
)

type ServerRunOptions struct {
    GenericServerRunOptions *genericoptions.ServerRunOptions
    Etcd                    *genericoptions.EtcdOptions
    SecureServing           *genericoptions.SecureServingOptions
    InsecureServing         *kubeoptions.InsecureServingOptions
    ...
}

咱們重點看看 EtcdOptions,etcd 存儲相關的配置,它和 kube-apiserver 如何訪問後端 etcd 存儲密切相關ui

EtcdOptions

StorageConfig 定義了 etcd 詳細配置,好比 etcd 版本,key 公共前綴等命令行

// kubernetes/vendor/k8s.io/apiserver/pkg/server/options/etcd.go
type EtcdOptions struct {
    StorageConfig storagebackend.Config
    EncryptionProviderConfigFilepath string
    ...
}

// kubernetes/vender/k8s.io/apiserver/storage/storagebackend/config.o
type Config struct {
    // Type defines the type of storage backend, e.g. "etcd2", "etcd3"
    Type string
    // Prefix is the prefix to all keys passed to storage.Interface methods.
    Prefix string
    // ServerList is the list of storage servers to connect with
    ...
}

建立

《工廠方法》NewEtcdOptions 用於建立 EtcdOptions設計

// kubernetes/cmd/kube-apiserver/app/options/options.go
func NewServerRunOptions() *ServerRunOptions {
    s := ServerRunOptions {
        ...
        Etcd: genericoptions.NewEtcdOptions(
            storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, nil))
        ...
    }
}

ApplyWithStorageFactoryTo

EtcdOptions 有一個很是重要的方法 ApplyWithStorageFactoryTo 用於初始化 server.Config(服務配置類,見下文)的 RESTOptionsGetter 屬性,該屬性用於建立 etcd 後端存儲(見下文)

// kubernetes/vendor/k8s.io/apiserver/pkg/server/options/etcd.go
func (s *EtcdOptions) ApplyWithStorageFactoryTo(
    factory server storage.StorageFactory, c *server.Config) error {
    s.RESTOptionsGetter = &storageFactoryRestOptionsFactory{
        Options: *s,
        StorageFactory: factory
    }
}

// kubernetes/pkg/kubeapiserver/options/storage_versions.go
const (
    DefaultEtcdPathPrefix = "/registry"
)

server.Config

Config is a structure used to configure a GenericAPIServer
server.Config 類用於配置和建立 GenericAPIServer(見下文)

// kubernetes/vender/k8s.io/apiserver/pkg/server/config.go
type Config struct {
    ...
    // 這個字段很重要,標記一下
    RESTOptionsGetter generic registry.RESTOptionsGetter
    ...
}

建立

《工廠方法》NewConfig 建立 server.Config 實例,該方法只是給 server.Config 的一些字段賦予一些默認值,《構建方法》BuildGenericConfig 對剩餘的字段進行初始化

func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transport) (...) {
    //《工廠方法》
    genericConfig := genericapiserver.NewConfig(legacy scheme.Codecs)
    ...
    // 將 ServerRunOptions.SecureServing "應用" 到 server.Config
    if err := s.SecureServing.ApplyTo(genericConfig); err 1= nil {
        ...
    }
}

方法體中還有不少 ApplyTo 函數調用,基本都是將 ServerRunOptions 中的字段 "應用" 到 server.Config

GenericAPIServer

GenericAPIServer contains state for a Kubernetes cluster api server
GenericAPIServer 結構體包含 server "通用" 的狀態(字段),通常作爲字段內嵌在具體 server(Master, APIAggregator .etc)中,能夠把 GenericAPIServer 看做一個基類

type GenericAPIServer struct {
    ...
}

Master

Master contains state for a Kubernetes cluster master/api server
Master 結構體包含 GenericAPIServer 的引用,下面將要介紹的幾個其它的結構體也都具備相似的結構

type Master struct {
    GenericAPIServer *genericapiserver.GenericAPIServer
    ClientCARegistrationHook ClientCARegistrationHook
}

APIAggregator

APIAggregator contains state for a Kubernetes cluster master/api server

type APIAggregator struct {
    GenericAPIServer *genericapiserver.GenericAPIServer
    ...
}

kube-apiserver 啓動流程

kube-apiserver 入口在 kubernetes/cmd/kube-apiserver/apiserver.go

PS:經過如下命令能夠(單獨)構建 kube-apiserver

# export GOPATH=/opt/kubernetes-src/
# cd $GOPATH/src/k8s.io/kubernetes
# make WHAT=cmd/kube-apiserver all
// kubernetes/cmd/kube-apiserver/apiserver.go
import(
    ...
    "k8s.io.kubernetes/cmd/kube-apiserver/app"
    ...
)

func main() {
    rand.Seed(time.Now().UTC().UnixNano())

    // 解析命令行參數
    s := options.NewServerRunOptions()
    s.AddFlags(pflag.CommandLine)
    flag.InitFlags()

    // 初始化 log
    logs.InitLogs()
    defer logs.FlushLogs()

    ...

    stopCh := server.SetupSignalHandler()
    if err := app.Run(s, stopCh); err != nil {
        fmt.FPrintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }
}

main 函數只是個殼子,解析完命令行參數後會調用 app 包中的 Run 函數

// kubernetes/cmd/kube-apiserver/app.server.go
func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
    ...
    server, err := CreateServerChain(runOptions, stopCh)
    if err != nil {
        return err
    }
    return server.PrepareRun().Run(stopCh)
}

CreateServerChain 函數使用了《責任鏈》模式,多個 server 組成一個鏈條,緊密相連,給客戶端提供 RESTful API 服務

相關文章
相關標籤/搜索