摘要:源碼版本簡(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)換等一系列的功能。
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ò)ApiServer啟動(dòng): /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 }
路徑: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
摘要:它包括一組和一個(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...
摘要:為所有對(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ù)...
摘要:我們先將上面的接口解析放放,先看下是如何初始化的路徑定義了,再看路徑定義空的創(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ú)章的,...
摘要:離線(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 生...
摘要:離線(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 生...
閱讀 2895·2021-11-24 09:39
閱讀 1157·2021-11-02 14:38
閱讀 4141·2021-09-10 11:26
閱讀 2743·2021-08-25 09:40
閱讀 2303·2019-08-30 15:54
閱讀 477·2019-08-30 10:56
閱讀 2738·2019-08-26 12:14
閱讀 3211·2019-08-26 12:13