kube-apiserver
目录:
kube-apiserver
kube-apiserver是Kubernetes与etcd交互的组件,主要有几个功能
- 提供Kubernetes API,包括认证授权,数据校验,集群状态变更等,提供Client和其他组件调用
- 代理集群中的一些附加组件组件,如Kubernetes UI、metrics-server、npd等
- 创建kubernetes服务,即提供apiserver的Service,kubernetes Service
- 资源在不同版本的转换
kube-apiversion的处理流程
kube-apiserver的接口有三种
- core group:主要在
/api/v1
下,例如/api/v1/nodes, /api/v1/pods, /api/v1/service
- named group:path为
/apis/$NAME/$VERSION
,例如/apis/bratch/v1/jobs
- 暴露的系统状态API:
/metrics
和/healthz
等
一个POST请求举例,到达apiserver
- 执行
http filter chain
中注册的过滤器链,进行过滤,包括认证和鉴权等 - 进入route对应的handler,handler的主要操作是与etcd交互
- 解码(decoder)传入的参数,转为internal version
- 检查是否使用全局约束条件(Admission)来检查是否可以创建或更新对象
- 检查字段合法性
- 转换写入etcd
http filter chain
在代码的server/config.go主要方法有
- WithRequestInfo
- MaxInfightLimit
- TimeoutForNonLongRunningRequests
- PanicRecovery
- CORS
- Authentication
- Audit
- Impersonation
- Authorization
decoder
kubernetes的resource会有一个internal version
因为在开发过程中,一个resource会对应多个version,为了避免kube-apiserver必须知道如何在每个版本转换,使用internal version作为通用的version,会包含所有version的字段。在decoder过程中将object转化为internal version,最后转为一个storage version,存储在etcd中
解码的过程是获取path中期待的version,使用scheme以正确的version创建对象,再使用json或protobuf解码转化,并补全省略的字段
Admission
在解码完成后,需要通过验证集群的全局约束来检查是否可以创建或更新对象,并根据集群配置设置默认值。在k8s.io/kubernetes/plugin/pkg/admission
目录下可以看到kube-apiserver可以使用的所有全局约束插件,kube-apiserver在启动时通过设置--enable-admission-plugins
参数来开启需要使用的插件,通过ValidatingAdmissionWebhook或MutatingAdmissionWebhook添加的插件也都会在此处进行工作。
kube-apiserver的组件
包括三个组件
- Aggregator
- KubeAPIServer,用于通用认证,授权和处理内建资源的Rest请求
- APIExtensionServer,用于CRD和CR的Rest请求
Aggregator
Aggregator包括一个GenericAPIServer和维护自身状态的Controller
GenericAPIServer主要是处理apiregistration.k8s.io下的资源请求
- apiserviceRegistrationController 负责APIServer中的资源注册与删除
- availableConditionController 维护APIServer的可用状态
- autoRegistrationController 保持API中一组特定的APIServices
- crdRegistrationController CRD字段的注册
- openAPIAggregationController 资源变化同步到Openapi文档
metrics-server也是通过Aggregator进行扩展的,官方工具apiserver-builder
KubeApiServer
提供对API的操作请求的接收,注册API的路由,暴露Restful接口
APIExtensionServer
负责处理使用CRD定义的资源
- openapiController 负责crd资源的变化同步至提供的OpenAPI文档,path为
/openapi/v2
- crdController 将CRD注册到apiVersions和apiResources中,可以通过
kubectl api-versions
和kubectl api-resources
查看 - namingController 检查CRD是否存在命名冲突
- establishingController 检查CRD是否正常
- nonStructuralSchemaController 检查CRD结构是否正常
- apiApprovalController 检查CRD是否遵循Kubernetes API声明
- finalizingController 删除CRD相关
kube-apiserver启动流程
Run方法的逻辑
k8s.io/kubernetes/cmd/kube-apiserver/app/server.go
的Run方法
- 调用CreateServerChain构建服务调用链,判断是否使用https,并为server注册路由
- 调用
server.PrepareRun
进行服务启动前的准备,包括健康检测,存活检测和openapi的注册 - 调用
prepared.Run
启动http服务
CreateServerChain完成初始化的方法,分别初始化APIExtensionsServer,KubeAPIServer和AggregatorServer
- 调用CreateKubeAPIServerConfig创建KubeAPIServer的配置
- 如果启动了扩展APIServer调用createAPIExtensionsConfig创建APIExtensionsServer的配置
- 调用createAPIExtensionsServer初始化apiExtensionsServer
- 调用CreateKubeAPIServer初始化kubeAPIServer
- 调用createAggregatorConfig创建aggregatorServer的配置
- 调用createAggregatorServer初始化aggregatorServer
- 判断是否使用https
CreateKubeAPIServerConfig的配置初始化操作
- 主要使用buildGenericConfig构建
- 设置genericConfig默认值
- 初始化storageFactory
- 初始化RESTOptionsGetter(etcd的操作句柄)
- 设置使用protobufs用来内部交互,并且禁用压缩功能
- 创建clientset
- 创建认证实例BuildAuthenticator,包括Header,Auth文件,Ca证书,Token,ServiceAccount认证,BootstrapToken认证等
- 创建鉴权实例BuildAuthorizer,包括Node,RBAC,AlwaysAllow,AlwaysDeny,Webhook
- 审计插件的初始化Audit.ApplyTo()
- 准入插件的初始化Admission.ApplyTo()
createAPIExtensionsServer的初始化调用apiextensionsConfig.Complete().New完成初始化
- 调用c.GenericConfig.New按照restful模式初始化genericServer
- 初始化APIGroup,为APIGroup指定需要暴露的API
- 调用s.GenericAPIServer.InstallAPIGroup在路由中注册API Resources
- 初始化CRD的informer
- 初始化Controller例如openapiController、crdController、namingController、establishingController、nonStructuralSchemaController、apiApprovalController、finalizingController
- 将Controller和informer加入到PostStartHook
CreateKubeAPIServer的初始化调用的kubeAPIServerConfig.Complete().New
- 调用c.GenericConfig.New按照restful模式初始化genericServer
- 判断是否支持/log的路由
- m.InstallLegacyAPI将核心API Resource添加到路由,path为
/api
- m.InstallAPIs将扩展API Resource添加到路由,path为
/apis
m.InstallLegacyAPI的逻辑
- legacyRESTStorageProvider为资源创建RESTStorage,将访问路径和后端存储操作对应起来
- 初始化bootstrap-controller
- m.GenericAPIServer.InstallLegacyAPIGroup在路由中注册API Resources
createAggregatorServer的初始化
- 调用aggregatorConfig.Complete().NewWithDelegate初始化aggregatorServer
- 调用crdregistration.NewCRDRegistrationController初始化crdRegistrationController(用于注册CRD)
- 调用autoregister.NewAutoRegisterController初始化autoRegistrationController(将CRD对应的APIServices注册到apiserver)
- 调用aggregatorServer.GenericAPIServer.AddPostStartHook将crdRegistrationController和autoRegistrationController加入到PostStartHook
prepared.Run启动服务调用s.NonBlockingRun
- s.AuditBackend判断是否启动审计日志
- s.SecureServingInfo.Serve启动http服务
- s.RunPostStartHooks(stopCh)执行PostStartHooks
- 发送ready信号到systemd
Kube-api包含三个server,流程都是创建config,初始化http服务
初始化httpserver流程
- 初始化GoRestfulContainer
- 为每个Resource创建后端存储RESTStorage
- 为每个Resource支持的verbs添加handler,并将handler注册到route,最后注册到webservice
apiserver的handler都是以store结构保存,通过NewLegacyRESTStorage创建资源对应的RESTStorage
- LegacyAPI下RESTStorage初始化
- 初始化资源的RESTStorage,例如pod使用podstore.NewStorage
- podstore.NewStorage调用store.CompleteWithOptions创建后端存储,最后使用newETCD3Storage完成存储的写入
- restStorageMap保存url和RESTStorage的对应关系
kubernetes service
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d22h
$ kubectl get endpoints kubernetes
NAME ENDPOINTS AGE
kubernetes 192.168.99.113:6443 4d22h
endpoint的配置地址由--advertise-address
和--secure-port
配置
kubernetes service由kube-apiserver创建和维护,由bootstrap controller维护
bootstrap controller的功能
- 创建kubernetes service
- 创建默认的命名空间default、kube-system和kube-public
- 基于Service ClusterIP的修复及检查功能
- 基于Service NodePort的修复及检查功能
bootstrap controller的初始化是在InstallLegacyAPI中调用c.NewBootstrapController,启动和停止分别在PostStartHook和ShutdownHook
bootstrapController.Start启动
- createEndpointPortSpec创建endpoint
- epairClusterIPs(保证ClusterIP唯一不会超出范围)和repairNodePorts初始化
- async.NewRunner(c.RunKubernetesNamespaces, c.RunKubernetesService, repairClusterIPs.RunUntil, repairNodePorts.RunUntil).Start()
- c.RunKubernetesNamespaces 创建kube-system和kube-public命名空间,之后每分钟检查一次
- c.RunKubernetesService 通过/healthz接口获apiserver状态,并更新kubernetes service状态
- c.UpdateKubernetesService 创建default命名空间,创建kubernetes service,更新endpoint
- c.EndpointReconciler.ReconcileEndpoints 管理多个apiserver的endpoint