设为首页 收藏本站
查看: 639|回复: 0

[经验分享] Kubernetes API源码学习笔记

[复制链接]

尚未签到

发表于 2018-1-4 19:16:56 | 显示全部楼层 |阅读模式
  API Server简介
  在 kubernetes 集群中,API Server 有着非常重要的角色。API Server 负责和 etcd 交互(其他组件不会直接操作 etcd,只有 API Server 这么做),是整个 kubernetes 集群的数据中心,所有的交互都是以 API Server 为核心的。简单来说,API Server 提供了以下的功能:


  • 整个集群管理的 API 接口:所有对集群进行的查询和管理都要通过 API 来进行
  • 集群内部各个模块之间通信的枢纽:所有模块之前并不会之间互相调用,而是通过和 API Server 打交道来完成自己那部分的工作
  • 集群安全控制:API Server 提供的验证和授权保证了整个集群的安全
  API Server源码分析
  github地址:https://github.com/kubernetes/kubernetes(当前master对应版本1.8)
  sourcegraph网站地址:https://sourcegraph.com/github.com/kubernetes/kubernetes@master
  入口:kubernetes/kubernetes/cmd/kube-apiserver/apiserver.go
  apiserver.go里面的main方法调用server.go里面的run方法来启动指定的API Server

  --》kubernetes/kubernetes/cmd/kube-apiserver/app/server.go
  server.go里面的run方法如下:

  可以看到先是调用CreateServerChain方法去创建一些server然后去启动这些server
  CreateServerChain方法里面主要创建了两个server,一个是kubeAPIServer,一个是apiExtensionsServer。kubeAPIServer是kubernetes独有的API Server,它负责的是kubernetes最主要的api,官方文档里面不建议在这个里面添加和修改api,如果我们有自己编写的api可以放在apiExtensionsServer里面,这个server是负责一些扩展的api。

  创建kubeAPIServer用到了CreateKubeAPIServer方法,此方法里面的创建server的关键代码如下:

  kubeAPIServerConfig是创建server所用到资源(resource)和配置,complete方法自动填充那些不能为空的字段值,new方法根据传入的config返回一个Server的实例。
  --》kubernetes/kubernetes/pkg/master/master.go
  new方法里面先根据配置创建一个名字为kube-apiserver的server

  然后生成一个Master结构体,此结构体的API Server为刚刚创建的kube-apiserver

  然后先注册核心api即LegacyAPI(此方法后面会注册其他的API,例如扩展API和验证所用的API,本文章这里记录注册核心API的过程)

  InstallLegacyAPI方法里面先调用NewLegacyRESTStorage方法来新建核心api所需用到的Storage,比如nodeStorage,podStorage(rest.Storage结构是用于对接etcd存储的,每个Storage都有操作ETCD的增删改查方法,比如PodStorage,NodeStorage就是操作对应pod和node在ETCD里面数据的结构,利用它们来实现对ETCD里面数据的操作)。
  --》kubernetes/kubernetes/pkg/registry/core/rest/storage_core.go

  这里只截取了node和pod的storage创建代码

  所有核心API所需用到的Storage新建好之后都添加到restStorageMap 里面去,此map相当于一个配置文件,里面列出了所有api路径和storage的对应关系,当然这里的path路径并不是完整的路径,后面还需加上 /api/v1 这样的前缀才能构成完整的api请求路径。
  

restStorageMap := map[string]rest.Storage{"pods":             podStorage.Pod,"pods/attach":      podStorage.Attach,"pods/status":      podStorage.Status,"pods/log":         podStorage.Log,"pods/exec":        podStorage.Exec,"pods/portforward": podStorage.PortForward,"pods/proxy":       podStorage.Proxy,"pods/binding":     podStorage.Binding,"bindings":         podStorage.Binding,  

"podTemplates": podTemplateStorage,  

"replicationControllers":        controllerStorage.Controller,"replicationControllers/status": controllerStorage.Status,  

"services":        serviceRest.Service,"services/proxy":  serviceRest.Proxy,"services/status": serviceStatusStorage,  

"endpoints": endpointsStorage,  

"nodes":        nodeStorage.Node,"nodes/status": nodeStorage.Status,"nodes/proxy":  nodeStorage.Proxy,  

"events": eventStorage,  

"limitRanges":                   limitRangeStorage,"resourceQuotas":                resourceQuotaStorage,"resourceQuotas/status":         resourceQuotaStatusStorage,"namespaces":                    namespaceStorage,"namespaces/status":             namespaceStatusStorage,"namespaces/finalize":           namespaceFinalizeStorage,"secrets":                       secretStorage,"serviceAccounts":               serviceAccountStorage,"persistentVolumes":             persistentVolumeStorage,"persistentVolumes/status":      persistentVolumeStatusStorage,"persistentVolumeClaims":        persistentVolumeClaimStorage,"persistentVolumeClaims/status": persistentVolumeClaimStatusStorage,"configMaps":                    configMapStorage,  

"componentStatuses": componentstatus.NewStorage(componentStatusStorage{c.StorageFactory}.serversToValidate),  }
  

  后面将此map放入到apiGroupInfo结构里面去并返回apiGroupInfo

  --》kubernetes/kubernetes/pkg/master/master.go
  InstallLegacyAPI方法得到NewLegacyRESTStorage方法返回的apiGroupInfo后调用InstallLegacyAPIGroup方法

  --》kubernetes/kubernetes/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
  InstallLegacyAPIGroup方法先调用installAPIResources方法去注册所有前面拿到的storage

  installAPIResources方法里面主要处理逻辑就是下面这段,apiGroupVersion结构里面包含了所有的storage

  InstallREST方法注册所有的REST处理器handler(包括storage, watch, proxy和redirect)到restful Container
  restful.Container代表一个http rest服务对象(restful.Container来自于一个第三方库github.com/emicklei/go-restful),包括一组restful.WebService(每个webserver处理一个对应路径下的所有请求。比如/api/v1/),restful.WebService由多个restful.Route组成,处理这些路径下所有的特殊的MIME类型等,restful.Route为路径(处理函数映射map)

  第一段代码生成url前缀字符串,比如/api/vi/。然后新建一个APIInstaller结构并调用它的install方法
  --》kubernetes/kubernetes/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
  install方法里面首先新建一个webService结构

  然后将所有前面集合里面的api路径path放到一个数组里面并将数组排序,接着循环遍历path数组将path路径与对应的storage注册到handler里面,注册好之后放到前面新建的webService里

  registerResourceHandlers这个方法比较大,首先里面会调用拿到的storage(比如传入的是podStorage)的动作方法,这些方法可以判断此storage是否支持此动词,比如
  

getter, isGetter := storage.(rest.Getter)  

  若此storage支持get方法则得到getter结构,其他例如create,update,delete这些动作若支持也会得到相应结构体。

  然后新建一个action数组并往此数组里面添加所有的action,这些action即GET,PUT和DELETE这些REST请求对应的actionn

  然后遍历数组actions,在循环每种动作action(例如get)的逻辑里面先创建一个此action对应的处理器handler,然后通过webService和此handler创建一个route结构,此route结构即为当前path对应到此action的一个路由

  循环遍历actions数组之后将所有route添加到当前路径对应的webService中
  --》kubernetes/kubernetes/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go
  然后回到InstallREST方法中将此webService添加到RestfulContainer中
  --》kubernetes/kubernetes/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
  前面的逻辑处理好之后回到InstallLegacyAPIGroup方法,之前调用installAPIResources安装了对应url前缀下的所有rest storage(例如 /api 路径下的所有rest storage),后面接着往RestfulContainer添加另一个控制版本的webService,这个webService枚举了所有支持的api版本(例如 /api/v1, /api/v1bete1),至此API的注册过程全部结束,后面apiServer接收到一个rest请求就会根据RestfulContainer里面的handler来进行处理。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-431635-1-1.html 上篇帖子: (2)Kubernetes基本概念和术语 下篇帖子: Kubernetes服务之StatefulSets简介
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表