kubernetes apiserver源码分析二之路由

apiserver的man函数在 k8s.io/kubernetes/cmd/kube-apiserver 目录。
但是大部分源码却在 k8s.io/apiserver 这个库里面。
cmd 目录下的kube-apiserver只是提供了一些启动参数。
所以路由代码我们要从 k8s.io/apiserver/server目录开始看
kubernetes apiserver源码分析二之路由
pkg目录下
admission 提供了一些权限管理的控制器
apis 是由code-generator自动生成的一些api包装器。
audit 是授权信息提取模块。给其他服务组件用的。
authentication 是角色管理的组件
authorization 是认证模块
endpoinsts 处理请求的http/https端点。
features
registry 跟etcd打交道的
server apiserver的 web模块
storage 跟etcd打交道的
utils
plugin/pkg

从k8s.io/kubernetes/cmd/kube-apiserver/servrr.go的run函数开始看
kubernetes apiserver源码分析二之路由
最后一行 server 是 k8s.io/apiserver/pkg/server/genericapiserver.go 里面的。
genericapiserver.go 文件有两个主要结构 preparedGenericAPIServer 和 GenericAPIServer。

GenericAPIServer.PrepareRun() 里面创建了preparedGenericAPIServer 结构, 并且把自己(GenericAPIServer)作为了preparedGenericAPIServer的匿名子结构。 也就是说 preparedGenericAPIServer里面包含了 GenericAPIServer

PrepareRun() 创建了preparedGenericAPIServer 后紧接着调用了preparedGenericAPIServer.Run()
而 preparedGenericAPIServer又在NonBlockingRun() 里面调用了 SecureServingInfo.Server()函数,
在接着调用了secure_serving.go的 RunServer() —> server.Serve(listener) 走完了整个启动流程.

写过go web的同学都知道 go的 web sever有一个handler结构 。当go的http模块接受到最原始一个http请求后,都会调用handler.ServeHTTP 。 然后ServeHTTP 里面路由到用户的处理函数。

而 preparedGenericAPIServer 的handler 在它的子结构GenericAPIServer里面
kubernetes apiserver源码分析二之路由
APIServerHandler 是 github.com/emicklei/go-restful, go-restful 路由的一个封装
kubernetes apiserver源码分析二之路由
我们重点管旭这个 GoRestfulContainer 。

在 NewAPIServerHandler() 里面
kubernetes apiserver源码分析二之路由
把这个 go-restful的handler交给了 director对象,director.ServeHTTP()函数调用了,最终进入了 go-restful的路由goRestfulContainer.Dispatch() 。

director创建后 handlerChainBuilder 函数包装了下。
handlerChainBuilder 其实是 = k8s.io/apiserver/pkg/server/config.go 里面的 DefaultBuildHandlerChain 函数。
这个函数对 director.ServeHTTP 进行了层层封装, 在 director.ServeHTTP前面加入了 recovery cors 认证, 授权… 等等 一系列的提前处理。
handlerChainBuilder 包装后 把 director 给了APIServerHandler.FullHandlerChain 。 而FullHandlerChain 作为最底层的ServeHTTP 被调用
请求在都到 director的 ServeHTTP 在进入 goRestfulContainer.Dispatch() 。

到这里所有的路由流程都明白了 。 画个图如下。
kubernetes apiserver源码分析二之路由
很简单。 就是进入go-restful 之前插入了一些k8s的验证流程。
之后的路由逻辑完全是 github.com/emicklei/go-restful 这个库的路由逻辑了。

用过 go-restful的同学都知道。 用户创建了请求处理函数后。 要注册到 go-restful里面去。 那apiserver又是在哪里注册请求的呢?

对于apiserver来说要注册到 go-restful 就是我们经常用的 kubectl cteate, kubectl get, kubectl delete请求apiserver的处理函数。 这些函数都在 k8s.io/apiserver/pkg/endpoints/handlers 目录下面。
这些函数在 k8s.io/apiserver/pkg/endpoints/install.go 的 APIInstaller.registerResourceHandlers构造成restful.WebService 后在 APIInstaller.Install加入到 GoRestfulContainer 路由里面。

APIInstaller.Install 是被
kubernetes apiserver源码分析二之路由
调用的, 参数 container 正是我们之前在 APIServerHandler结构里面看到的GoRestfulContainer字段。
而 InstallREST 当然是在 k8s.io/apiserver/pkg/server/genericapiserver.go的 GenericAPIServer.installAPIResources 。 被调用啦。

我们重点关注下 k8s.io/apiserver/pkg/endpoints/installer.go里面的 registerResourceHandlers 函数吧,
从 369行开始可以看到 大部分的kubectl请求的api接口都被加入到了 actions 里面。
然后在533行循环遍历 actions 根据 操作 把对应的函数很对应的请求路径,注册到estful.WebService 里面。

好啦。接下来我们就可以到对应的操作函数里面去看看apiserver到底是如果操作请求资源了啦。