国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Kubernetes1.5源碼分析(一) apiServer啟動分析

stormgens / 1782人閱讀

摘要:源碼版本簡介是最重要的組成部分,不論是命令操作還是通過進行控制,實際都需要經過。僅用于長時間執行的請求最小請求處理超時時間,默認僅用于該文件內設置鑒權機構一組用于運行時的配置信息。在最后會啟動服務。

源碼版本

Kubernetes v1.5.0

簡介

apiserver是K8S最重要的組成部分,不論是命令操作還是通過remote API進行控制,實際都需要經過apiserver。
apiserver是k8s系統中所有對象的增刪改查盯的http/restful式服務端,其中盯是指watch操作。數據最終存儲在分布式一致的etcd存儲內,apiserver本身是無狀態的,提供了這些數據訪問的認證鑒權、緩存、api版本適配轉換等一系列的功能。

關鍵結構:

ServerRunOptions結構:
路徑: cmd/kube-apiserver/app/options/options.go

type ServerRunOptions struct {
    // 重名,下面稱為GenericServerRunOptions
    GenericServerRunOptions     *genericoptions.ServerRunOptions    // 服務器通用的運行參數
    AllowPrivileged             bool  // 是否配置超級權限,即允許Pod中運行的容器擁有系統特權
    EventTTL                    time.Duration  // 事件留存事件, 默認1h
    KubeletConfig               kubeletclient.KubeletClientConfig  // K8S kubelet配置
    MaxConnectionBytesPerSec    int64    // 每秒的最大連接數
    // 指定的話,可以通過SSH指定的秘鑰文件和用戶名對Node進行訪問
    SSHKeyfile                  string
    SSHUser                     string
    // 包含PEM-encoded x509 RSA公鑰和私鑰的文件路徑,用于驗證Service Account的token
    // 不指定的話,則使用--tls-private-key-file指定的文件
    ServiceAccountKeyFile       string
    // 設置為true時,系統會到etcd驗證ServiceAccount token是否存在
    ServiceAccountLookup        bool
    WebhookTokenAuthnConfigFile string
    WebhookTokenAuthnCacheTTL   time.Duration
}

ServerRunOptions結構:
路徑: pkg/genericapiserver/options/server_run_options.go

type ServerRunOptions struct {
    // 準入控制,如:"AlwaysAdmit","LimitRanger","ReousrceQuota"等
    AdmissionControl           string      
    // 準入控制的配置文件
    AdmissionControlConfigFile string      
    // 用于廣播給集群的所有成員自己的IP地址,不指定的話就使用"--bind-address"的IP地址
    AdvertiseAddress           net.IP    
    // 安全訪問的認證模式列表,以逗號分隔,包括:AlwaysAllow、AlwaysDeny、ABAC、Webhook、RBAC
    AuthorizationMode                        string
    // mode設置為ABAC時使用的csv格式的授權配置文件
    AuthorizationPolicyFile                  string
    // 下列跟mode配置成webhook有關
    AuthorizationWebhookConfigFile           string
    AuthorizationWebhookCacheAuthorizedTTL   time.Duration
    AuthorizationWebhookCacheUnauthorizedTTL time.Duration
    // mode設置為RBAC時使用的超級用戶名,用該用戶名進行RBAC認證
    AuthorizationRBACSuperUser               string

    AnonymousAuth                bool
    // 使用http基本認證的方式訪問API Server的安全端口
    BasicAuthFile                string
    // 默認"0.0.0.0",apiServer在該地址的6443端口上開啟https服務
    BindAddress                  net.IP
    // TLS證書所在目錄,默認"/var/run/kubernetes"
    CertDirectory                string
    // 指定的話,該客戶端證書將用于認證過程
    ClientCAFile                 string
    // 下列的云服務商有關
    CloudConfigFile              string
    CloudProvider                string
    // CORS 跨域資源共享
    CorsAllowedOriginList        []string
    // 默認的持久化存儲格式,比如"application/json"
    DefaultStorageMediaType      string
    // 指定清理的工作線程數,可以提高清理namespace的效率,但是會增加系統資源的占用
    DeleteCollectionWorkers      int
    // 日志相關策略
    AuditLogPath                 string
    AuditLogMaxAge               int
    AuditLogMaxBackups           int
    AuditLogMaxSize              int
    // 使能GC
    EnableGarbageCollection      bool
    // 打開性能分析,可以通過:/debug/pprof/地址來查看程序棧,線程等信息
    EnableProfiling              bool
    EnableContentionProfiling    bool
    // 使能swaggerUI,訪問地址:/swagger-ui
    EnableSwaggerUI              bool
    // 使能watch cache,對所有的watch操作進行緩存
    EnableWatchCache             bool
    // 按資源覆蓋etcd服務的設置,以逗號分隔,比如group/resource#servers,其中servers為: http://ip:port
    EtcdServersOverrides         []string
    StorageConfig                storagebackend.Config
    // 用于生成該master對外的URL地址
    ExternalHost                 string
    // 綁定的不安全地址,即8080端口綁定的地址
    InsecureBindAddress          net.IP
    // 非安全端口,默認8080
    InsecurePort                 int
    // 設置keystone鑒權插件地址
    KeystoneURL                  string
    KeystoneCAFile               string
    
    KubernetesServiceNodePort    int
    LongRunningRequestRE         string
    // master數量
    MasterCount                  int
    // 設置master服務所在的namespace,默認為default
    MasterServiceNamespace       string
    // 同時處理的最大請求數,默認為400,超過該請求數將被拒絕。僅用于長時間執行的請求
    MaxRequestsInFlight          int
    // 最小請求處理超時時間,默認1800s,僅用于watch request
    MinRequestTimeout            int
    // 該文件內設置鑒權機構
    OIDCCAFile                   string
    OIDCClientID                 string
    OIDCIssuerURL                string
    OIDCUsernameClaim            string
    OIDCGroupsClaim              string
    RequestHeaderUsernameHeaders []string
    RequestHeaderClientCAFile    string
    RequestHeaderAllowedNames    []string
    // 一組key=value用于運行時的配置信息。api//,用于打開或者關閉對某個API版本的支持
    // api/all和api/legacy特別用于支持所有版本的API或支持舊版本的API
    RuntimeConfig                config.ConfigurationMap
    // https安全端口,默認6443;設置為0,表示不開啟https
    SecurePort                   int
    // service的Cluster IP池
    ServiceClusterIPRange        net.IPNet // TODO: make this a list
    // service的NodePort模式下能使用的主機端口號范圍,默認是30000--32767
    ServiceNodePortRange         utilnet.PortRange
    // 持久化存儲的資源版本號,例如"group1/version1,group2/version2,..."
    StorageVersions              string
    // The default values for StorageVersions. StorageVersions overrides
    // these; you can change this if you want to change the defaults (e.g.,
    // for testing). This is not actually exposed as a flag.
    DefaultStorageVersions string
    TargetRAMMB            int
    // TLS CA文件
    TLSCAFile              string
    // 包含x509證書的文件路徑,用于https認證
    TLSCertFile            string
    // 包含x509與tls-cert-file對應的私鑰文件路徑
    TLSPrivateKeyFile      string
    SNICertKeys            []config.NamedCertKey
    // 用于訪問APIServer安全端口的token認證文件路徑
    TokenAuthFile          string
    // 使能token
    EnableAnyToken         bool
    // 設置各資源對象watch緩存大小的列表,以逗號分隔,格式為resource#size
    // 前提是EnableWatchCache為true
    WatchCacheSizes        []string
}
ApiServer啟動

路徑:kubernetes/cmd/kube-apiserver/apiserver.go
入口main()函數:

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

    // 新建一個apiserver對象
    s := options.NewServerRunOptions()
    // 接受用戶命令行輸入,其實就是自定義上述apiserver對象 
    s.AddFlags(pflag.CommandLine)
    // 解析并格式化用戶傳入的參數,最后填充APIServer結構體的各成員
    flag.InitFlags()
    // 初始化log配置,包括log輸出位置、log等級等。
    logs.InitLogs()
    // 保證了即使apiserver異常崩潰了也能將內存中的log信息保存到磁盤文件中。 
    defer logs.FlushLogs()
    // 如果用戶只是想看apiserver的版本號而不是啟動apiserver,則打印apiserver的版本號并退出。
    verflag.PrintAndExitIfRequested()

    // 將創建的apiserver對象傳入app.Run()中,最終綁定本地端口并綁定本地端口并創建一個HTTP Server與一個HTTPS Server。
    if err := app.Run(s); err != nil {
        fmt.Fprintf(os.Stderr, "%v
", err)
        os.Exit(1)
    }
}

新建一個apiserver對象---NewServerRunOptions():

func NewServerRunOptions() *ServerRunOptions {
    s := ServerRunOptions{
        // 初始化通用的apiserver運行參數,包括etcd后端存儲參數
        GenericServerRunOptions: genericoptions.NewServerRunOptions().WithEtcdOptions(),
        // 事件的存儲保留時間
        EventTTL:                1 * time.Hour,
        // Node上kubelet的客戶端配置
        KubeletConfig: kubeletclient.KubeletClientConfig{
            // kubelet通信端口
            Port: ports.KubeletPort,
            PreferredAddressTypes: []string{
                string(api.NodeHostName),
                string(api.NodeInternalIP),
                string(api.NodeExternalIP),
                string(api.NodeLegacyHostIP),
            },
            // 是否開啟https
            EnableHttps: true,
            // HTTP超時
            HTTPTimeout: time.Duration(5) * time.Second,
        },
        // 將webhook token authenticator返回的響應保存在緩存內的時間
        WebhookTokenAuthnCacheTTL: 2 * time.Minute,
    }
    return &s
}

上面的接口在初始化GenericServerRunOptions參數時又調用了genericoptions.NewServerRunOptions().WithEtcdOptions()接口,先來看下與上面接口名字一樣的NewServerRunOptions():

func NewServerRunOptions() *ServerRunOptions {
    return &ServerRunOptions{
        // 以逗號作為分隔符的Admission Control插件的排序列表
        AdmissionControl:                         "AlwaysAdmit",
        AnonymousAuth:                            false,
        // 授權模式
        AuthorizationMode:                        "AlwaysAllow",
        AuthorizationWebhookCacheAuthorizedTTL:   5 * time.Minute,
        AuthorizationWebhookCacheUnauthorizedTTL: 30 * time.Second,
        // apiserver綁定的網卡地址
        BindAddress:                              net.ParseIP("0.0.0.0"),
        // 證書目錄
        CertDirectory:                            "/var/run/kubernetes",
        // 默認的對象存儲類型
        DefaultStorageMediaType:                  "application/json",
        DefaultStorageVersions:                   registered.AllPreferredGroupVersions(),
        DeleteCollectionWorkers:                  1,
        EnableGarbageCollection:                  true,
        EnableProfiling:                          true,
        EnableContentionProfiling:                false,
        EnableWatchCache:                         true,
        // HTTP綁定的IP地址
        InsecureBindAddress:                      net.ParseIP("127.0.0.1"),
        // 不安全端口(HTTP)
        InsecurePort:                             8080,
        LongRunningRequestRE:                     DefaultLongRunningRequestRE,
        // Kubernetes系統中Master的數量
        MasterCount:                              1,
        MasterServiceNamespace:                   api.NamespaceDefault,
        MaxRequestsInFlight:                      400,
        MinRequestTimeout:                        1800,
        // k8s運行時環境配置
        RuntimeConfig:                            make(config.ConfigurationMap),
        // 安全端口
        SecurePort:                               6443,
        ServiceNodePortRange:                     DefaultServiceNodePortRange,
        StorageVersions:                          registered.AllPreferredGroupVersions(),
    }
}

可以看到初始化的時候會有SecurePort、InsecurePort,實際就是對應HTTP、HTTPS的綁定端口。
我們可以看到這里的控制還是很全面的,包括安全控制(CertDirectory, HTTPS默認啟動)、權限控制(AdmissionControl,AuthorizationMode)、服務限流控制(MaxRequestsInFlight)等。
具體的參數前面介紹結構體時基本都有提到。
繼續后端存儲etcd的配置初始化WithEtcdOptions():

func (o *ServerRunOptions) WithEtcdOptions() *ServerRunOptions {
    o.StorageConfig = storagebackend.Config{
        // etcd的默認路徑前綴:/registry
        Prefix: DefaultEtcdPathPrefix,
        // 反序列化cache,未設置的話,會根據apiServer的內存限制進行配置
        DeserializationCacheSize: 0,
    }
    return o
}

到這里apiServer的運行參數初始化關鍵性步驟基本結束,至于后面的s.AddFlags(pflag.CommandLine)就是獲取命令行的輸入信息,然后進行重新覆蓋,這里就不講了。
可以根據kube-apiserver進程的命令行信息,把命令行傳參和結構配置進行對應:

#/usr/bin/kube-apiserver --logtostderr=true --v=0 --etcd-servers=http://test-master:2379 --insecure-bind-address=0.0.0.0 --port=8080 --kubelet-port=10250 --allow-privileged=false --service-cluster-ip-range=10.254.0.0/16 --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota --service-account-key-file=/var/run/kubernetes/apiserver.key

初始化完成之后,最重要的任務就是啟動實例了。
所有的操作都是在run函數中執行,app.run()接口實現在cmd/kube-apiserver/app/server.go。
RUN源碼分析:

func Run(s *options.ServerRunOptions) error {
    // 檢查etcd后端存儲相關參數的有效性
    genericvalidation.VerifyEtcdServersList(s.GenericServerRunOptions)
    // 檢查一些運行參數的有效性,并會設置一些默認值
    // 比如options.AdvertiseAddress參數沒有設置,并且bind-address也沒有設置,
    // k8s將會獲取默認網卡的地址給該成員
    genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions)
    // 根據之前初始化的GenericServerRunOptions對象來初始化創建genericapiserver.config
    // NewConfig()是初始化了一個默認的config,
    // ApplyOptions()根據GenericServerRunOptions進行再一遍的初始化
    // Complete()對一些沒填充的字段,可以根據別的字段進行初始化
    // 實際NewConfig()中也調用了ApplyOptions()接口,只是參數是default值
    genericConfig := genericapiserver.NewConfig(). // create the new config
                            ApplyOptions(s.GenericServerRunOptions).
                            Complete()

    // 根據ServiceClusterIPRange輸入參數,獲取IPRange和ServiceIP
    serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(s.GenericServerRunOptions.ServiceClusterIPRange)
    if err != nil {TargetRAMMB
        glog.Fatalf("Error determining service IP ranges: %v", err)
    }
    // 有需要的話生成證書
    if err := genericConfig.MaybeGenerateServingCerts(apiServerServiceIP); err != nil {
        glog.Fatalf("Failed to generate service certificate: %v", err)
    }
    
    // 初始化能力集,多次運行apiserver也只會初始化一次
    capabilities.Initialize(capabilities.Capabilities{
        // 是否有超級權限
        AllowPrivileged: s.AllowPrivileged,
        // TODO(vmarmol): Implement support for HostNetworkSources.
        PrivilegedSources: capabilities.PrivilegedSources{
            HostNetworkSources: []string{},
            HostPIDSources:     []string{},
            HostIPCSources:     []string{},
        },
        // 每個用戶連接的最大值,字節數/秒。當前只適用于長時間運行的請求
        PerConnectionBandwidthLimitBytesPerSec: s.MaxConnectionBytesPerSec,
    })

    // 有需要的話設置網絡隧道
    var tunneler genericapiserver.Tunneler
    var proxyDialerFn apiserver.ProxyDialerFunc
    // 如果運行在云平臺中,則需要安裝本機的SSH Key到Kubernetes集群中所有節點上
    // 可以用于通過該用戶名和私鑰,SSH到node上
    if len(s.SSHUser) > 0 {
        // Get ssh key distribution func, if supported
        var installSSH genericapiserver.InstallSSHKey
        cloud, err := cloudprovider.InitCloudProvider(s.GenericServerRunOptions.CloudProvider, s.GenericServerRunOptions.CloudConfigFile)
        if err != nil {
            glog.Fatalf("Cloud provider could not be initialized: %v", err)
        }
        if cloud != nil {
            if instances, supported := cloud.Instances(); supported {
                installSSH = instances.AddSSHKeyToAllInstances
            }
        }
        if s.KubeletConfig.Port == 0 {
            glog.Fatalf("Must enable kubelet port if proxy ssh-tunneling is specified.")
        }
        // Set up the tunneler
        // TODO(cjcullen): If we want this to handle per-kubelet ports or other
        // kubelet listen-addresses, we need to plumb through options.
        healthCheckPath := &url.URL{
            Scheme: "https",
            Host:   net.JoinHostPort("127.0.0.1", strconv.FormatUint(uint64(s.KubeletConfig.Port), 10)),
            Path:   "healthz",
        }
        tunneler = genericapiserver.NewSSHTunneler(s.SSHUser, s.SSHKeyfile, healthCheckPath, installSSH)

        // Use the tunneler"s dialer to connect to the kubelet
        s.KubeletConfig.Dial = tunneler.Dial
        // Use the tunneler"s dialer when proxying to pods, services, and nodes
        proxyDialerFn = tunneler.Dial
    }

    // Proxying to pods and services is IP-based... don"t expect to be able to verify the hostname
    proxyTLSClientConfig := &tls.Config{InsecureSkipVerify: true}

    // 后端存儲etcd的反序列化緩存沒有設置的話,根據TargetRAMMB值進行恰當的設置
    // TargetRAMMB:用戶手動輸入的apiServer的內存限制(單位:MB)
    // 小于1000MB的話按1000MB算
    if s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize == 0 {
        glog.V(2).Infof("Initalizing deserialization cache size based on %dMB limit", s.GenericServerRunOptions.TargetRAMMB)

        clusterSize := s.GenericServerRunOptions.TargetRAMMB / 60
        s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize = 25 * clusterSize
        if s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize < 1000 {
            s.GenericServerRunOptions.StorageConfig.DeserializationCacheSize = 1000
        }
    }
    // 存儲組版本
    storageGroupsToEncodingVersion, err := s.GenericServerRunOptions.StorageGroupsToEncodingVersion()
    if err != nil {
        glog.Fatalf("error generating storage version map: %s", err)
    }
    // 創建api工廠,包括請求頭、解析工具、編碼格式、API配置
    // 創建了一個DefaultStorageFactory對象
    storageFactory, err := genericapiserver.BuildDefaultStorageFactory(
        s.GenericServerRunOptions.StorageConfig, s.GenericServerRunOptions.DefaultStorageMediaType, api.Codecs,
        genericapiserver.NewDefaultResourceEncodingConfig(), storageGroupsToEncodingVersion,
        // FIXME: this GroupVersionResource override should be configurable
        []unversioned.GroupVersionResource{batch.Resource("cronjobs").WithVersion("v2alpha1")},
        master.DefaultAPIResourceConfigSource(), s.GenericServerRunOptions.RuntimeConfig)
    if err != nil {
        glog.Fatalf("error in initializing storage factory: %s", err)
    }
    // 添加jobs和HPA(水平自動擴容)的接口
    storageFactory.AddCohabitatingResources(batch.Resource("jobs"), extensions.Resource("jobs"))
    storageFactory.AddCohabitatingResources(autoscaling.Resource("horizontalpodautoscalers"), extensions.Resource("horizontalpodautoscalers"))
    // 根據用戶輸入的etcd-servers-overrides參數,設置對應groupResource對應的etcd地址
    for _, override := range s.GenericServerRunOptions.EtcdServersOverrides {
        tokens := strings.Split(override, "#")
        if len(tokens) != 2 {
            glog.Errorf("invalid value of etcd server overrides: %s", override)
            continue
        }

        apiresource := strings.Split(tokens[0], "/")
        if len(apiresource) != 2 {
            glog.Errorf("invalid resource definition: %s", tokens[0])
            continue
        }
        group := apiresource[0]
        resource := apiresource[1]
        groupResource := unversioned.GroupResource{Group: group, Resource: resource}

        servers := strings.Split(tokens[1], ";")
        // 上面都是解析用戶輸入的字符串,并生成對應的groupResource
        // 設置對應groupResource的etcdLocation
        storageFactory.SetEtcdLocation(groupResource, servers)
    }

    // 授權認證有關
    if len(s.ServiceAccountKeyFiles) == 0 && s.GenericServerRunOptions.TLSPrivateKeyFile != "" {
        if authenticator.IsValidServiceAccountKeyFile(s.GenericServerRunOptions.TLSPrivateKeyFile) {
            s.ServiceAccountKeyFiles = []string{s.GenericServerRunOptions.TLSPrivateKeyFile}
        } else {
            glog.Warning("No TLS key provided, service account token authentication disabled")
        }
    }

    var serviceAccountGetter serviceaccount.ServiceAccountTokenGetter
    // 判斷是否設置為true,是的話則創建接口用于從etcd驗證ServiceAccount token是否存在
    if s.ServiceAccountLookup {
        // If we need to look up service accounts and tokens,
        // go directly to etcd to avoid recursive auth insanity
        storageConfig, err := storageFactory.NewConfig(api.Resource("serviceaccounts"))
        if err != nil {
            glog.Fatalf("Unable to get serviceaccounts storage: %v", err)
        }
        serviceAccountGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storageConfig, storageFactory.ResourcePrefix(api.Resource("serviceaccounts")), storageFactory.ResourcePrefix(api.Resource("secrets")))
    }

    // 安全認證相關
    apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{
        Anonymous:                   s.GenericServerRunOptions.AnonymousAuth,
        AnyToken:                    s.GenericServerRunOptions.EnableAnyToken,
        // 指定basicauthfile文件所在的位置,當這個參數不為空的時候,
        // 會開啟basicauth的認證方式,這是一個.csv文件,
        // 三列分別是password,username,useruid
        BasicAuthFile:               s.GenericServerRunOptions.BasicAuthFile,
        // 用于給客戶端簽名的根證書,當這個參數不為空的時候,
        // 會開啟https的認證方式,會通過這個根證書對客戶端的證書進行身份認證
        ClientCAFile:                s.GenericServerRunOptions.ClientCAFile,
        // 用于Token文件所在的位置,當這個參數不為空的時候,會采用token的認證方式,
        // token文件也是csv的格式,分別是“token,username,userid”
        TokenAuthFile:               s.GenericServerRunOptions.TokenAuthFile,
        OIDCIssuerURL:               s.GenericServerRunOptions.OIDCIssuerURL,
        OIDCClientID:                s.GenericServerRunOptions.OIDCClientID,
        OIDCCAFile:                  s.GenericServerRunOptions.OIDCCAFile,
        OIDCUsernameClaim:           s.GenericServerRunOptions.OIDCUsernameClaim,
        OIDCGroupsClaim:             s.GenericServerRunOptions.OIDCGroupsClaim,
        // 當不為空的時候,采用ServiceAccount的認證方式,這其實是一個公鑰方式。
        // 發過來的信息是客戶端使用對應的私鑰加密,服務端使用指定的公鑰來解密信息
        ServiceAccountKeyFiles:      s.ServiceAccountKeyFiles,
        // 默認為false。如果為true的話,就會從etcd中取出對應的ServiceAccount與
        // 傳過來的信息進行對比驗證,反之不會
        ServiceAccountLookup:        s.ServiceAccountLookup,
        ServiceAccountTokenGetter:   serviceAccountGetter,
        KeystoneURL:                 s.GenericServerRunOptions.KeystoneURL,
        KeystoneCAFile:              s.GenericServerRunOptions.KeystoneCAFile,
        WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile,
        WebhookTokenAuthnCacheTTL:   s.WebhookTokenAuthnCacheTTL,
        RequestHeaderConfig:         s.GenericServerRunOptions.AuthenticationRequestHeaderConfig(),
    })

    if err != nil {
        glog.Fatalf("Invalid Authentication Config: %v", err)
    }

    privilegedLoopbackToken := uuid.NewRandom().String()
    selfClientConfig, err := s.GenericServerRunOptions.NewSelfClientConfig(privilegedLoopbackToken)
    if err != nil {
        glog.Fatalf("Failed to create clientset: %v", err)
    }
    client, err := s.GenericServerRunOptions.NewSelfClient(privilegedLoopbackToken)
    if err != nil {
        glog.Errorf("Failed to create clientset: %v", err)
    }
    sharedInformers := informers.NewSharedInformerFactory(client, 10*time.Minute)

    authorizationConfig := authorizer.AuthorizationConfig{
        PolicyFile:                  s.GenericServerRunOptions.AuthorizationPolicyFile,
        WebhookConfigFile:           s.GenericServerRunOptions.AuthorizationWebhookConfigFile,
        WebhookCacheAuthorizedTTL:   s.GenericServerRunOptions.AuthorizationWebhookCacheAuthorizedTTL,
        WebhookCacheUnauthorizedTTL: s.GenericServerRunOptions.AuthorizationWebhookCacheUnauthorizedTTL,
        RBACSuperUser:               s.GenericServerRunOptions.AuthorizationRBACSuperUser,
        InformerFactory:             sharedInformers,
    }
    authorizationModeNames := strings.Split(s.GenericServerRunOptions.AuthorizationMode, ",")
    apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizationModeNames, authorizationConfig)
    if err != nil {
        glog.Fatalf("Invalid Authorization Config: %v", err)
    }

    admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")

    // TODO(dims): We probably need to add an option "EnableLoopbackToken"
    if apiAuthenticator != nil {
        var uid = uuid.NewRandom().String()
        tokens := make(map[string]*user.DefaultInfo)
        tokens[privilegedLoopbackToken] = &user.DefaultInfo{
            Name:   user.APIServerUser,
            UID:    uid,
            Groups: []string{user.SystemPrivilegedGroup},
        }

        tokenAuthenticator := authenticator.NewAuthenticatorFromTokens(tokens)
        apiAuthenticator = authenticatorunion.New(tokenAuthenticator, apiAuthenticator)

        tokenAuthorizer := authorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
        apiAuthorizer = authorizerunion.New(tokenAuthorizer, apiAuthorizer)
    }

    pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer)
    // 準入控制器
    admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer)
    if err != nil {
        glog.Fatalf("Failed to initialize plugins: %v", err)
    }

    proxyTransport := utilnet.SetTransportDefaults(&http.Transport{
        Dial:            proxyDialerFn,
        TLSClientConfig: proxyTLSClientConfig,
    })
    kubeVersion := version.Get()
    
    // genericConfig在該接口最開始進行了創建并初始化
    genericConfig.Version = &kubeVersion
    genericConfig.LoopbackClientConfig = selfClientConfig
    genericConfig.Authenticator = apiAuthenticator
    genericConfig.Authorizer = apiAuthorizer
    genericConfig.AdmissionControl = admissionController
    genericConfig.APIResourceConfigSource = storageFactory.APIResourceConfigSource
    genericConfig.OpenAPIConfig.Info.Title = "Kubernetes"
    genericConfig.OpenAPIConfig.Definitions = generatedopenapi.OpenAPIDefinitions
    genericConfig.EnableOpenAPISupport = true
    genericConfig.EnableMetrics = true
    genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions

    // master.Config配置初始化
    config := &master.Config{
        GenericConfig: genericConfig.Config,

        StorageFactory:          storageFactory,
        EnableWatchCache:        s.GenericServerRunOptions.EnableWatchCache,
        EnableCoreControllers:   true,
        DeleteCollectionWorkers: s.GenericServerRunOptions.DeleteCollectionWorkers,
        EventTTL:                s.EventTTL,
        KubeletClientConfig:     s.KubeletConfig,
        EnableUISupport:         true,
        EnableLogsSupport:       true,
        ProxyTransport:          proxyTransport,

        Tunneler: tunneler,

        ServiceIPRange:       serviceIPRange,
        APIServerServiceIP:   apiServerServiceIP,
        APIServerServicePort: 443,

        ServiceNodePortRange:      s.GenericServerRunOptions.ServiceNodePortRange,
        KubernetesServiceNodePort: s.GenericServerRunOptions.KubernetesServiceNodePort,

        MasterCount: s.GenericServerRunOptions.MasterCount,
    }
    // 判斷是否對watch cache進行了使能,默認是true
    // 是true的話,會初始化watchCacheSize,然后設置各個resource的CacheSize
    if s.GenericServerRunOptions.EnableWatchCache {
        glog.V(2).Infof("Initalizing cache sizes based on %dMB limit", s.GenericServerRunOptions.TargetRAMMB)
        cachesize.InitializeWatchCacheSizes(s.GenericServerRunOptions.TargetRAMMB)
        cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes)
    }
    // 創建master
    // Complete()完善了config的初始化
    // New()進行resources的初始化及RESTful-api注冊
    m, err := config.Complete().New()
    if err != nil {
        return err
    }

    sharedInformers.Start(wait.NeverStop)
    // 運行HTTP/HTTPS服務
    m.GenericAPIServer.PrepareRun().Run(wait.NeverStop)
    return nil
}

該接口調用主要用于生成master實例對象,各種api的請求最后都是通過master對象來處理的。
在最后APIServer會啟動HTTP/HTTPS服務。

基本的啟動流程就介紹完了,這里不進入細講,由于大致了解下啟動流程。
后面會繼續分章節介紹各個關鍵點。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/32558.html

相關文章

  • Kubernetes1.5源碼分析(三) apiServer之go-restful的使用

    摘要:它包括一組和一個對象,使用進行請求派發。流程基本就是這樣,接著我們直接進入接口看實現拼裝然后填充并返回一個對象創建一個這個是關鍵,會對各種進行注冊增加一個的將該加入到前兩個調用函數比較簡單,這里不進行介紹了。 源碼版本 Kubernetes v1.5.0 go-restful 簡介 go-restful是用于構建REST-style web服務的golang包。它是出現時因為一個jav...

    Doyle 評論0 收藏0
  • Kubernetes1.5源碼分析(四) apiServer資源的etcd接口實現

    摘要:為所有對外提供服務的資源實現了一套通用的符合要求的操作接口,每個服務接口負責處理一類資源對象。該接口最終返回了的和清除操作資源的接口。 源碼版本 Kubernetes v1.5.0 簡介 k8s的各個組件與apiServer交互操作各種資源對象,最終都會落入到etcd中。k8s為所有對外提供服務的Restful資源實現了一套通用的符合Restful要求的etcd操作接口,每個服務接口負...

    K_B_Z 評論0 收藏0
  • Kubernetes1.5源碼分析(二) apiServer之資源注冊

    摘要:我們先將上面的接口解析放放,先看下是如何初始化的路徑定義了,再看路徑定義空的創建,用于不同版本對象轉換增加一些轉換函數上面就創建了一個空的。其實就是向添加了轉換函數,比如將轉換為,將轉換為。 源碼版本 Kubernetes v1.5.0 簡介 k8s里面有各種資源,如Pod、Service、RC、namespaces等資源,用戶操作的其實也就是這一大堆資源。但這些資源并不是雜亂無章的,...

    imccl 評論0 收藏0
  • kubeadm源碼分析(kubernetes離線安裝包,三步安裝)

    摘要:離線安裝包三步安裝,簡單到難以置信源碼分析說句實在話,的代碼寫的真心一般,質量不是很高。然后給該租戶綁定角色。 k8s離線安裝包 三步安裝,簡單到難以置信 kubeadm源碼分析 說句實在話,kubeadm的代碼寫的真心一般,質量不是很高。 幾個關鍵點來先說一下kubeadm干的幾個核心的事: kubeadm 生成證書在/etc/kubernetes/pki目錄下 kubeadm 生...

    Eirunye 評論0 收藏0
  • kubeadm源碼分析(kubernetes離線安裝包,三步安裝)

    摘要:離線安裝包三步安裝,簡單到難以置信源碼分析說句實在話,的代碼寫的真心一般,質量不是很高。然后給該租戶綁定角色。 k8s離線安裝包 三步安裝,簡單到難以置信 kubeadm源碼分析 說句實在話,kubeadm的代碼寫的真心一般,質量不是很高。 幾個關鍵點來先說一下kubeadm干的幾個核心的事: kubeadm 生成證書在/etc/kubernetes/pki目錄下 kubeadm 生...

    Heier 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<