c语言sscanf函数的用法是什么
291
2023-05-19
K8s提供 Aggregated APIServer 的扩展方式,编写 Aggregated APIServer 本质上和K8s构建方式类似,理解 APiServer 资源的加载方式,能更好好的理解如何开发Aggregated APIServer。本文以内置资源的 handler 注册过程为线索介绍了 APiServer 的启动过程和 handler 注册过程。使用k8s代码commit id为c6970e64528ba78b74bf77b86f9b78b7b61bd0cd
APIServer启动过程介绍
图1 APIServer启动流程
图1给出了 ApiServer 的初始化流程,首先通过 CreateServerChain 构造出3个APIServer:
AggregatorServer:拦截Aggregated APIServer 中定义的资源对象请求,并转发给相关的Aggregated APIServer 处理。KubeAPIServer:用于处理 k8s 的内建资源,如:Deployment,ConfigMap 等。APIExtensionServer:负责处理用户自定义资源。它们之间的处理顺序为如下图所示,当用户请求进来,先判断 AggregatorServer 能否处理,否则代理给 kubeApiServer ,如果 kubeApiServer 不能处代理给 ApiExtensionServer 处理,如果都不能处理则交给 notFoundHandler 处理。
图2 三种 APIServer 请求顺序
限于篇幅原因,本文主要分析 kubeapiserver 的启动过程。
CreateApiServerConfig 通过调用 buildGenericConfig 构建 genericapiserver.Config。genericapiserver.Config 中包含了启动Genericapiserver 所需要的配置信息,比如:RequestTimeout 定义了请求的超时时间,AdmissionControl 对象进行准入控制。buildGenericConfig 中需要注意的是 BuildHandlerChainFunc,请求在路由给资源对象的handler前先经过的BuildHandlerChainFunc 中定义的 Filter 。参考图1,通过深入 buildGenericConfig 可以发现 BuildHandlerChainFunc 传入的是 DefaultBuildHandlerChain ,其中 Filter 先定义的后调用。
CreateKubeAPIServer 中调用了kubeAPIServerConfig.Complete().New构造出了 kubeAPIServer 的 GenericServer。kubeAPIServerConfig.Complete().New中通过调用 m.InstallLegacyAPI 初始化核心资源并添加进路由中,对应的是以 api 开头的资源,如:Pod,ConfigMap 等。调用 m.InstallAPI 初始化以 apis 开头的内置资源如:Deployment。
handler的注册过程从图1可以看出 InstallAPI 与 InstallLegacyAPI 的创建过程基本类似,本文主要介绍 InstallAPI 的初始化过程。
在调用 InstallAPI 之前kubeAPIServerConfig.Complete().New会先创建内置资源对象的RESTStorageProvider 作为 InstallAPI 的入参
RESTStorageProvider 是一个接口,通过其 NewRESTStorage 构造出 APIGroupInfo ,APIGroupInfo 包含注册资源所需的基本信息比如编解码器,组下所有资源的 Storage 对象VersionedResourcesStorageMap。
VersionedResourcesStorageMap 需要重点注意,编写 Aggregated APIServer主要逻辑是通过 NewDefaultAPIGroupInfo 初始化 APIGroupInfo 以后设置 VersionedResourcesStorageMap 属性。VersionedResourcesStorageMap的签名是 map[string]map[string]rest.Storage。第一个key是版本号,第二个key是资源名称,资源名称可以是 deployment 这种资源,同时也能是子资源如 pod/status , pod/log 等是pod的子资源有单独的storage。最终构建handler的请求路径是基于 VersionedResourcesStorageMap 中提供的版本号和资源名称确定的 。rest.Storage 用于处理具体的请求,其声明如下:
实现 rest.Storage 的接口最基本的,如果需要支持不同的请求,还需要实现其他的接口,相关定义在 k8s.io/apiserver/pkg/registry/rest/rest.go中,如:
后续的处理中会依据 Creater ,Getter 和 Watcher 等接口生成对应请求的handler,后文会进行具体的分析。k8s的内置资源存储都使用 etcd,因此内置资源的 Storage 是通过 Store 构建。Store 定义在 /k8s.io/apiserver/pkg/registry/generic/registry/store.go文件中,已经实现 Creater , Getter, Watcher等接口,其他的资源只需在初始化 Store 时传入一些必须的参数即可,无需编写存储层的交互代码。下面给出了构造 deployment 的 store 的过程,其他内置资源大同小异。
InstallAPIs 调用链条比较深。参考图1,最终会来到k8s.io/apiserver/pkg/endpoints/groupversion.go的 InstallREST 方法。InstallREST 方法构造出 handler 的前缀,创建APIInstaller,然后调用installer.Install()方法继续handler的注册
installer.Install() 方法会调用registerResourceHandlers 方法,真正开始创建和注册处理请求的 handler,需要说明的是a.group.Storage 是上文提到的VersionedResourcesStorageMap 传入版本号后获得的 map。读者可以自行参考图1的调用链进行分析。a.registerResourceHandlers 就是为每一种Storage注册handlers
registerResourceHandlers 会依据rest.Storage实现的接口生成相关的action。最终根据action生成handler并注册到rest容器中。
registerResourceHandlers 中创建的handler并不是直接调用Creater ,Updater等接口定义的方法,而是在外面包了一层代码进行一些额外的处理,例如对象的编解码,admission control 的处理逻辑,针对 watch 这种长链接需要进行协议的处理等,相关的定义在k8s.io/apiserver/pkg/endpoints/handlers包下。文本以Get和Create例,分析请求的处理逻辑。
Get请求的处理过程比较简单,通过请求的查询串构造出metav1.GetOptions ,然后交给 Getter 接口处理,最后在将查询结果进行转换发回给请求者。
Create的处理逻辑在 createHandler 中,代码较长,主要做以下几件事情:
对查询串进行解码生成 metav1.CreateOptions 。对请求的body体中的数据进行解码,生成资源对象。解码的对象版本是 internal 版本,internal 版本是该资源对象所有版本字段的全集。针对不同版本的对象内部可以使用相同的代码进行处理。 对对象进行修改的准入控制,判断是否修需要修改对象。交给creater接口创建资源对象。将数据转换为期望的格式写入 response 中,调用 creater 接口返回的结果仍然是 internal 版本,编码时,会编码成用户请求的版本返回给用户。Create请求的流程可以总结为下图
图3 create请求处理流程
总结本文介绍了 K8s内置资源的注册过程,对APIServer的访问会先经过 filter,再路由给具体的 handler。filter 在 DefaultBuildHandlerChain 中定义,主要对请求做超时处理,认证,鉴权等操作。handler 的注册则是初始化 APIGoupInfo 并设置其 VersionedResourcesStorageMap 后作为入参,调用 GenericAPIServer.InstallAPIGroups即可完成 handler 的注册。k8s.io/apiserver/pkg/endpoints/handlers包中的代码则是对用户请求做编解码,对象版本转换,协议处理等操作,最后在交给rest.Storage 具体实现的接口进行处理。
参考• https://blog.tianfeiyu.com/source-code-reading-notes/kubernetes/kube_apiserver.html#kube-apiserver-处理流程[1]
• https://hackerain.me/2020/10/05/kubernetes/kube-apiserver-genericapiserver.html
• https://hackerain.me/2020/09/19/kubernetes/kube-apiserver-storage-overview.html
• https://github.com/gosoon/source-code-reading-notes/blob/master/kubernetes/kube_apiserver.md
• https://time.geekbang.org/column/article/41876
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~