Openshift API部分源码学习笔记(一)

Openshift API简介

Openshift API包含了两部分,一部分是Kubernetes v1 REST API,另一部分是OpenShift v1 REST API,这些RESTful API都是通过HTTP(s)来访问OpenShift Container Platform的master服务器来调用的。这些API可用于管理终端用户的应用程序,集群和集群用户。

Openshift里面Kubernetes api的前缀是 /api,而OpenShift 自己开发了一些api,它们的前缀是 /oapi,kubernetes原生api已有的功能Openshift并没有重新写接口而是直接用的kubernetes的原生apii,只不过开发了一些kubernetes原先没有的功能和api接口。

源码分析

github地址:https://github.com/openshift/origin(此文中代码对应1.3版本)

sourcegraph网站地址:https://sourcegraph.com/github.com/openshift/[email protected]/-/blob/cmd/openshift/openshift.go

代码入口

--》openshift/origin/cmd/openshift/openshift.go

openshift.go里面的main方法有启动服务逻辑,通过调用CommandFor获取哪些启动命令需要执行。

CommandFor方法里面根据传入的basename参数来决定获取哪些命令,默认是调用NewCommandOpenShift方法获取所有命令

NewCommandOpenShift方法先创建一个Command结构root,然后往root里面添加命令。逻辑里会首先调用NewCommandStartAllInOne方法获取一些主要命令集。

--》openshift/origin/pkg/cmd/server/start/start_allinone.go

NewCommandStartAllInOne方法里面添加命令的主要逻辑如下:

此处会拿到master,node等等的启动命令,还有kubernetes相关服务组件的启动。

1).这里我先从获取kubernetes相关命令的方法开始看

--》openshift/origin/pkg/cmd/server/start/kubernetes/kubernetes.go

NewCommand方法里面主要逻辑如下:

这里包含了好几部分kubernetes组件的启动命令,我们主要关注api部分,因此是NewAPIServerCommand方法

--》openshift/origin/pkg/cmd/server/start/kubernetes/apiserver.go

这后面的逻辑跟kubernetes源码里面api这部分的逻辑大致相同,先根据默认参数新建一个APIServer

然后通过server.go里面的run方法启动指定的APIServer

--》openshift/origin/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go

run方法里面启动api server的主要逻辑如下,先根据配置新建一个server然后启动

--》openshift/origin/vendor/k8s.io/kubernetes/pkg/master/master.go

master里面的new方法先根据配置信息返回一个api server的实例,然后调用InstallAPIs方法初始化所有的api

InstallAPIs方法里面会根据条件来创建好几个apiGroupsInfo结构并将它们添加到一个apiGroupsInfo组中间去,这些不同的apiGroupsInfo对应不同的版本信息,例如v1,v1beta1等等。添加到数组中去好了之后会调用InstallAPIGroups方法来安装所有的apiGroupsInfo中的api。这里我们拿v1这个group来看,逻辑里面会先调用initV1ResourcesStorage方法来初始化v1这个group的所有storage,例如podStorage,nodeStorage

新建好这些storage之后会将它们配置到一个map中去,此map即相当于一个配置文件去管理要用到哪些storage以及对应的路径path,这些即决定了后面会提供哪些api

m.v1ResourcesStorage = 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,
        "securityContextConstraints":    securityContextConstraintsStorage,
        "persistentVolumes":             persistentVolumeStorage,
        "persistentVolumes/status":      persistentVolumeStatusStorage,
        "persistentVolumeClaims":        persistentVolumeClaimStorage,
        "persistentVolumeClaims/status": persistentVolumeClaimStatusStorage,
        "configMaps":                    configMapStorage,

        "componentStatuses": componentstatus.NewStorage(func() map[string]apiserver.Server { return m.getServersToValidate(c) }),
    }

然后新建一个APIGroupInfo,将前面的这个map放到这个新建的APIGroupInfo中去。等所有APIGroupInfo放好之后调用InstallAPIGroups方法

--》openshift/origin/vendor/k8s.io/kubernetes/pkg/genericapiserver/genericapiserver.go

InstallAPIGroups方法里面会循环调用InstallAPIGroup方法去安装每个APIGroup

InstallAPIGroup方法先取得api路径前缀,这里我们还是拿v1这个group举例,所以这里拿到的前缀apiPrefix会是 /api,然后根据APIGroupInfo结构的信息来获取一个apiGroupVersion结构对象,再调用apiGroupVersion的InstallREST方法来注册REST api。

--》openshift/origin/vendor/k8s.io/kubernetes/pkg/apiserver/apiserver.go

InstallREST方法会新建一个webService,此webService会处理指定的path下面的所有请求,vi这个group的webService所对应的path就是/api/v1,然后调用Install方法去安装初始化所有route

--》openshift/origin/vendor/k8s.io/kubernetes/pkg/apiserver/api_installer.go

Install方法里面主要逻辑如下,循环遍历所有前面那个记录path和storage的map里的路径path,然后注册每个path对应的handler

registerResourceHandlers方法里面先根据当前的storage获取各种action方法,例如create,get方法

然后根据当前storage对应的resource是否是有namespace的来分别创建action并放到actions这个数组中

这里的不同action方法用到的api路径不尽相同,像LIST,POST方法都是path里面不需要item name的,而GET,PUT都是需要item name的

然后循环actions数组将每种action对应的方法转化成route并添加到webService中去,这里截取GET的处理代码

所有这些都处理好之后将此webService添加到container中去,至此kubernetes的API Server注册启动命令就创建好了

时间: 2024-11-10 11:36:03

Openshift API部分源码学习笔记(一)的相关文章

Openshift API部分源码学习笔记(二)

前面一篇文章将openshift里面启动kubernetes组件部分解析了一下,本文将对openshift启动master服务的代码解析一下 上一篇文章链接:http://www.cnblogs.com/zard/p/7767112.html 源码分析 前面将kubernetes的API Server注册启动命令创建好了之后回到NewCommandStartAllInOne方法中,这次看下NewCommandStartMaster方法,此方法即为获取启动openshift master的命令 -

jQuery源码学习笔记:扩展工具函数

// 扩展工具函数 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控制权 // 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样. // 在 jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性. // 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noC

jQuery源码学习笔记五 六 七 八 转

jQuery源码学习笔记五 六 七 八 转 Js代码   <p>在正式深入jQuery的核心功能选择器之前,还有一些方法,基本都是数组方法,用于遴选更具体的需求,如获得某个元素的所有祖选元素啦,等等.接着是其缓存机制data.</p> <pre class="brush:javascript;gutter:false;toolbar:false"> //@author  司徒正美|なさみ|cheng http://www.cnblogs.com/ru

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

Hadoop源码学习笔记(4) ——Socket到RPC调用

Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要学的就是Socket编程,这是网络编程中最底层的程序接口,分为服务器端和客户端,服务器负责监听某个端口,客户端负责连接服务器上的某个端口,一旦连接通过后,服务器和客户端就可以双向通讯了,我们看下示例代码: ServerSocket server = new ServerSocket(8111); S

Spring源码学习笔记(6)

Spring源码学习笔记(六) 前言-- 最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. 上一篇中我们梳理到 Spring 加载 XML 配置文件, 完成 XML 的解析工作,接下来我们将进入 Spring 加载 bean 的逻辑. 我们使用 Spring 获取 XML

Spring源码学习笔记(3)

Spring源码学习笔记(三) 前言----     最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. DispatcherServlet 实现核心功能 和普通的 Servelt 类一样, DispatcherServlet 中的 doGet() 和 doPost() 方法

Hadoop源码学习笔记(3) ——初览DataNode及学习线程

Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Configured implements InterDatanodeProtocol,       ClientDatanodeProtocol, FSConstants, Runnable {      public static DataNode createDataNode(String args[],

菜鸟的jQuery源码学习笔记(二)

jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: 1 jQuery.fn = jQuery.prototype = { 2 //成员变量和方法 3 } 这里给原型对象起了一个别名叫做jQuery.fn.要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的.如果你在控制台敲$().fn的话输出的结果会是undefined.接下来看看原型对象里面有些