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

資訊專(zhuān)欄INFORMATION COLUMN

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

stormgens / 1777人閱讀

摘要:源碼版本簡(jiǎn)介是最重要的組成部分,不論是命令操作還是通過(guò)進(jìn)行控制,實(shí)際都需要經(jīng)過(guò)。僅用于長(zhǎng)時(shí)間執(zhí)行的請(qǐng)求最小請(qǐng)求處理超時(shí)時(shí)間,默認(rèn)僅用于該文件內(nèi)設(shè)置鑒權(quán)機(jī)構(gòu)一組用于運(yùn)行時(shí)的配置信息。在最后會(huì)啟動(dòng)服務(wù)。

源碼版本

Kubernetes v1.5.0

簡(jiǎn)介

apiserver是K8S最重要的組成部分,不論是命令操作還是通過(guò)remote API進(jìn)行控制,實(shí)際都需要經(jīng)過(guò)apiserver。
apiserver是k8s系統(tǒng)中所有對(duì)象的增刪改查盯的http/restful式服務(wù)端,其中盯是指watch操作。數(shù)據(jù)最終存儲(chǔ)在分布式一致的etcd存儲(chǔ)內(nèi),apiserver本身是無(wú)狀態(tài)的,提供了這些數(shù)據(jù)訪(fǎng)問(wèn)的認(rèn)證鑒權(quán)、緩存、api版本適配轉(zhuǎn)換等一系列的功能。

關(guān)鍵結(jié)構(gòu):

ServerRunOptions結(jié)構(gòu):
路徑: cmd/kube-apiserver/app/options/options.go

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

ServerRunOptions結(jié)構(gòu):
路徑: pkg/genericapiserver/options/server_run_options.go

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

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

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

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

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

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

新建一個(gè)apiserver對(duì)象---NewServerRunOptions():

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

上面的接口在初始化GenericServerRunOptions參數(shù)時(shí)又調(diào)用了genericoptions.NewServerRunOptions().WithEtcdOptions()接口,先來(lái)看下與上面接口名字一樣的NewServerRunOptions():

func NewServerRunOptions() *ServerRunOptions {
    return &ServerRunOptions{
        // 以逗號(hào)作為分隔符的Admission Control插件的排序列表
        AdmissionControl:                         "AlwaysAdmit",
        AnonymousAuth:                            false,
        // 授權(quán)模式
        AuthorizationMode:                        "AlwaysAllow",
        AuthorizationWebhookCacheAuthorizedTTL:   5 * time.Minute,
        AuthorizationWebhookCacheUnauthorizedTTL: 30 * time.Second,
        // apiserver綁定的網(wǎng)卡地址
        BindAddress:                              net.ParseIP("0.0.0.0"),
        // 證書(shū)目錄
        CertDirectory:                            "/var/run/kubernetes",
        // 默認(rèn)的對(duì)象存儲(chǔ)類(lèi)型
        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系統(tǒng)中Master的數(shù)量
        MasterCount:                              1,
        MasterServiceNamespace:                   api.NamespaceDefault,
        MaxRequestsInFlight:                      400,
        MinRequestTimeout:                        1800,
        // k8s運(yùn)行時(shí)環(huán)境配置
        RuntimeConfig:                            make(config.ConfigurationMap),
        // 安全端口
        SecurePort:                               6443,
        ServiceNodePortRange:                     DefaultServiceNodePortRange,
        StorageVersions:                          registered.AllPreferredGroupVersions(),
    }
}

可以看到初始化的時(shí)候會(huì)有SecurePort、InsecurePort,實(shí)際就是對(duì)應(yīng)HTTP、HTTPS的綁定端口。
我們可以看到這里的控制還是很全面的,包括安全控制(CertDirectory, HTTPS默認(rèn)啟動(dòng))、權(quán)限控制(AdmissionControl,AuthorizationMode)、服務(wù)限流控制(MaxRequestsInFlight)等。
具體的參數(shù)前面介紹結(jié)構(gòu)體時(shí)基本都有提到。
繼續(xù)后端存儲(chǔ)etcd的配置初始化WithEtcdOptions():

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

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

#/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

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

func Run(s *options.ServerRunOptions) error {
    // 檢查etcd后端存儲(chǔ)相關(guān)參數(shù)的有效性
    genericvalidation.VerifyEtcdServersList(s.GenericServerRunOptions)
    // 檢查一些運(yùn)行參數(shù)的有效性,并會(huì)設(shè)置一些默認(rèn)值
    // 比如options.AdvertiseAddress參數(shù)沒(méi)有設(shè)置,并且bind-address也沒(méi)有設(shè)置,
    // k8s將會(huì)獲取默認(rèn)網(wǎng)卡的地址給該成員
    genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions)
    // 根據(jù)之前初始化的GenericServerRunOptions對(duì)象來(lái)初始化創(chuàng)建genericapiserver.config
    // NewConfig()是初始化了一個(gè)默認(rèn)的config,
    // ApplyOptions()根據(jù)GenericServerRunOptions進(jìn)行再一遍的初始化
    // Complete()對(duì)一些沒(méi)填充的字段,可以根據(jù)別的字段進(jìn)行初始化
    // 實(shí)際NewConfig()中也調(diào)用了ApplyOptions()接口,只是參數(shù)是default值
    genericConfig := genericapiserver.NewConfig(). // create the new config
                            ApplyOptions(s.GenericServerRunOptions).
                            Complete()

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

    // 有需要的話(huà)設(shè)置網(wǎng)絡(luò)隧道
    var tunneler genericapiserver.Tunneler
    var proxyDialerFn apiserver.ProxyDialerFunc
    // 如果運(yùn)行在云平臺(tái)中,則需要安裝本機(jī)的SSH Key到Kubernetes集群中所有節(jié)點(diǎn)上
    // 可以用于通過(guò)該用戶(hù)名和私鑰,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}

    // 后端存儲(chǔ)etcd的反序列化緩存沒(méi)有設(shè)置的話(huà),根據(jù)TargetRAMMB值進(jìn)行恰當(dāng)?shù)脑O(shè)置
    // TargetRAMMB:用戶(hù)手動(dòng)輸入的apiServer的內(nèi)存限制(單位:MB)
    // 小于1000MB的話(huà)按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
        }
    }
    // 存儲(chǔ)組版本
    storageGroupsToEncodingVersion, err := s.GenericServerRunOptions.StorageGroupsToEncodingVersion()
    if err != nil {
        glog.Fatalf("error generating storage version map: %s", err)
    }
    // 創(chuàng)建api工廠(chǎng),包括請(qǐng)求頭、解析工具、編碼格式、API配置
    // 創(chuàng)建了一個(gè)DefaultStorageFactory對(duì)象
    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(水平自動(dòng)擴(kuò)容)的接口
    storageFactory.AddCohabitatingResources(batch.Resource("jobs"), extensions.Resource("jobs"))
    storageFactory.AddCohabitatingResources(autoscaling.Resource("horizontalpodautoscalers"), extensions.Resource("horizontalpodautoscalers"))
    // 根據(jù)用戶(hù)輸入的etcd-servers-overrides參數(shù),設(shè)置對(duì)應(yīng)groupResource對(duì)應(yīng)的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], ";")
        // 上面都是解析用戶(hù)輸入的字符串,并生成對(duì)應(yīng)的groupResource
        // 設(shè)置對(duì)應(yīng)groupResource的etcdLocation
        storageFactory.SetEtcdLocation(groupResource, servers)
    }

    // 授權(quán)認(rèn)證有關(guān)
    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
    // 判斷是否設(shè)置為true,是的話(huà)則創(chuàng)建接口用于從etcd驗(yàn)證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")))
    }

    // 安全認(rèn)證相關(guān)
    apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{
        Anonymous:                   s.GenericServerRunOptions.AnonymousAuth,
        AnyToken:                    s.GenericServerRunOptions.EnableAnyToken,
        // 指定basicauthfile文件所在的位置,當(dāng)這個(gè)參數(shù)不為空的時(shí)候,
        // 會(huì)開(kāi)啟basicauth的認(rèn)證方式,這是一個(gè).csv文件,
        // 三列分別是password,username,useruid
        BasicAuthFile:               s.GenericServerRunOptions.BasicAuthFile,
        // 用于給客戶(hù)端簽名的根證書(shū),當(dāng)這個(gè)參數(shù)不為空的時(shí)候,
        // 會(huì)開(kāi)啟https的認(rèn)證方式,會(huì)通過(guò)這個(gè)根證書(shū)對(duì)客戶(hù)端的證書(shū)進(jìn)行身份認(rèn)證
        ClientCAFile:                s.GenericServerRunOptions.ClientCAFile,
        // 用于Token文件所在的位置,當(dāng)這個(gè)參數(shù)不為空的時(shí)候,會(huì)采用token的認(rèn)證方式,
        // 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,
        // 當(dāng)不為空的時(shí)候,采用ServiceAccount的認(rèn)證方式,這其實(shí)是一個(gè)公鑰方式。
        // 發(fā)過(guò)來(lái)的信息是客戶(hù)端使用對(duì)應(yīng)的私鑰加密,服務(wù)端使用指定的公鑰來(lái)解密信息
        ServiceAccountKeyFiles:      s.ServiceAccountKeyFiles,
        // 默認(rèn)為false。如果為true的話(huà),就會(huì)從etcd中取出對(duì)應(yīng)的ServiceAccount與
        // 傳過(guò)來(lái)的信息進(jìn)行對(duì)比驗(yàn)證,反之不會(huì)
        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)
    // 準(zhǔn)入控制器
    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在該接口最開(kāi)始進(jìn)行了創(chuàng)建并初始化
    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,
    }
    // 判斷是否對(duì)watch cache進(jìn)行了使能,默認(rèn)是true
    // 是true的話(huà),會(huì)初始化watchCacheSize,然后設(shè)置各個(gè)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)
    }
    // 創(chuàng)建master
    // Complete()完善了config的初始化
    // New()進(jìn)行resources的初始化及RESTful-api注冊(cè)
    m, err := config.Complete().New()
    if err != nil {
        return err
    }

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

該接口調(diào)用主要用于生成master實(shí)例對(duì)象,各種api的請(qǐng)求最后都是通過(guò)master對(duì)象來(lái)處理的。
在最后APIServer會(huì)啟動(dòng)HTTP/HTTPS服務(wù)。

基本的啟動(dòng)流程就介紹完了,這里不進(jìn)入細(xì)講,由于大致了解下啟動(dòng)流程。
后面會(huì)繼續(xù)分章節(jié)介紹各個(gè)關(guān)鍵點(diǎn)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/32558.html

相關(guān)文章

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

    摘要:它包括一組和一個(gè)對(duì)象,使用進(jìn)行請(qǐng)求派發(fā)。流程基本就是這樣,接著我們直接進(jìn)入接口看實(shí)現(xiàn)拼裝然后填充并返回一個(gè)對(duì)象創(chuàng)建一個(gè)這個(gè)是關(guān)鍵,會(huì)對(duì)各種進(jìn)行注冊(cè)增加一個(gè)的將該加入到前兩個(gè)調(diào)用函數(shù)比較簡(jiǎn)單,這里不進(jìn)行介紹了。 源碼版本 Kubernetes v1.5.0 go-restful 簡(jiǎn)介 go-restful是用于構(gòu)建REST-style web服務(wù)的golang包。它是出現(xiàn)時(shí)因?yàn)橐粋€(gè)jav...

    Doyle 評(píng)論0 收藏0
  • Kubernetes1.5源碼分析(四) apiServer資源的etcd接口實(shí)現(xiàn)

    摘要:為所有對(duì)外提供服務(wù)的資源實(shí)現(xiàn)了一套通用的符合要求的操作接口,每個(gè)服務(wù)接口負(fù)責(zé)處理一類(lèi)資源對(duì)象。該接口最終返回了的和清除操作資源的接口。 源碼版本 Kubernetes v1.5.0 簡(jiǎn)介 k8s的各個(gè)組件與apiServer交互操作各種資源對(duì)象,最終都會(huì)落入到etcd中。k8s為所有對(duì)外提供服務(wù)的Restful資源實(shí)現(xiàn)了一套通用的符合Restful要求的etcd操作接口,每個(gè)服務(wù)接口負(fù)...

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

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

    imccl 評(píng)論0 收藏0
  • kubeadm源碼分析(kubernetes離線(xiàn)安裝包,三步安裝)

    摘要:離線(xiàn)安裝包三步安裝,簡(jiǎn)單到難以置信源碼分析說(shuō)句實(shí)在話(huà),的代碼寫(xiě)的真心一般,質(zhì)量不是很高。然后給該租戶(hù)綁定角色。 k8s離線(xiàn)安裝包 三步安裝,簡(jiǎn)單到難以置信 kubeadm源碼分析 說(shuō)句實(shí)在話(huà),kubeadm的代碼寫(xiě)的真心一般,質(zhì)量不是很高。 幾個(gè)關(guān)鍵點(diǎn)來(lái)先說(shuō)一下kubeadm干的幾個(gè)核心的事: kubeadm 生成證書(shū)在/etc/kubernetes/pki目錄下 kubeadm 生...

    Eirunye 評(píng)論0 收藏0
  • kubeadm源碼分析(kubernetes離線(xiàn)安裝包,三步安裝)

    摘要:離線(xiàn)安裝包三步安裝,簡(jiǎn)單到難以置信源碼分析說(shuō)句實(shí)在話(huà),的代碼寫(xiě)的真心一般,質(zhì)量不是很高。然后給該租戶(hù)綁定角色。 k8s離線(xiàn)安裝包 三步安裝,簡(jiǎn)單到難以置信 kubeadm源碼分析 說(shuō)句實(shí)在話(huà),kubeadm的代碼寫(xiě)的真心一般,質(zhì)量不是很高。 幾個(gè)關(guān)鍵點(diǎn)來(lái)先說(shuō)一下kubeadm干的幾個(gè)核心的事: kubeadm 生成證書(shū)在/etc/kubernetes/pki目錄下 kubeadm 生...

    Heier 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<