kubernetes kube-apiserver源码阅读8之Hook
阅读kube-apiserver的过程中,会发现很多的AddPostStartHook的代码,这部分代码用于执行kube-apiserver启动之后的逻辑,因为他们放在启动后执行更适合,所以就提供了两种钩子(Hook), PostStartHook和PreShutdownHook。这里只看PostStartHook,并且只看bootstrap-controller对应的钩子函数。
阅读kube-apiserver的过程中,会发现很多的AddPostStartHook的代码,这部分代码用于执行kube-apiserver启动之后的逻辑,因为他们放在启动后执行更适合,所以就提供了两种钩子(Hook), PostStartHook和PreShutdownHook。这里只看PostStartHook,并且只看bootstrap-controller对应的钩子函数。
从前文我们已经了解到kube-apiserver内部有三个组件,分别是apiExtensionsServer,kubeAPIServer,aggregatorServer, 为了方便用户扩展,所以存在apiExtensionsServer, 因为k8s有自己的核心资源,所以需要kubeAPIServer, 为了将两者结合起来所以需要aggregatorServer, 那么aggregatorServer怎么两者的资源集中在一起并提供给用户查询呢? 本文尝试从k8s的源代码中找到问题的答案。
之前看过kube-apiserver请求处理链的相关内容,知道一些通用逻辑,如认证,鉴权,审计之类的内容都以一种链条的方式组合在一起依次调用,但是这些处理函数中并不包含准入的业务逻辑,之所以这样,我想是因为准入只针对修改请求,所以放在通用的处理链中会不太和谐,再者就是准入是比较重要的抽象,所以单独抽离出来了。
这里一节主要看kube-apiserver的路由注册和最终映射到后端存储的处理函数是怎么构造的,kube-apiserver中一共有三个组件,apiExtensionsServer,kubeAPIServer, aggregatorServer,每个组件都有路由注册,但其实核心逻辑是差不多的。
如果认证成功,那么客户端的可以标识成了一个用户了,而这个用户一般至少拥有两个信息,用户和用户组。通过这两个信息就可以给用户鉴权了。
kubernetes代码版本: v1.20.2
从前文我们知道,认证,鉴权,审计等操作的并没有集成在GenericServer里面,所以本文看看这个请求链是怎么工作的。
kubernetes代码版本: v1.20.2
前一节大致看了一下apiserver 的启动流程,以及组成kube-apiserver的三个组件,这一节看看三个组件都会用到的一个非常重要的对象GenericAPIServer, 它是一个HTTP Server的抽象, 虽然这么说很抽象。它会提供注册路由的入口以及各种钩子函数的注册入口。
kubernetes代码版本: v1.20.2
个人认为kube-apiserver是k8s中最核心的组件,承上启下,无论是k8s其他组件还是是外部客户端都需要跟kube-apiserver组件进行交互,kube-apiserver负责接受请求并将数据持久化到后端存储(一般来说就是etcd.)。
书接上回,继续看kubectl 删除, 更新, 查询操作的源代码。因为之前已经介绍了kubectl一些常用的设计模式和代码结构,所以本文会比较快的阅读其他操作的代码。
如果不知道怎么用client-go,那就看看kubectl的代码吧,kubectl除了是一个比较优秀的命令行工具之外,还提供了比较好的代码实现,通过看kubectl的代码我们可以抄到很多有用的代码片段。
只要读k8s源代码一定会读informer的代码的,因为informer相当优秀,大多数分布式项目(比如OpenStack)在解决组件间通信的问题时都会选择如kafka,rabbitmaq之类的消息队列,但是k8s不走寻常路,选择了自己解决,解决的方案是informer。
client-go提供了许多有用的工具,其中就包括选举,通过选举的功能,我们可以同时运行多个业务实例,多个实例之间互为备份,并且同一时刻只有一个实例运行。
虽然k8s的发现客户端可以实时的获取k8s集群的所有资源,但是并不是直接面向用户的接口,因为解析这些资源组版本是一个乏味和无趣的过程,所以在此基础上client-go提供了RESTMapper来帮助用户映射和发现要找的资源。
之前介绍了client-go的静态客户端,动态客户端,本文主要讲解一下发现客户端的源代码,发现客户端用于发现k8s集群现有的资源,包括但不限于内置资源,可以获取当时k8s集群中的所有资源,通过发现客户端我们可以确定当前器群存在哪些资源及其对应的版本。
本文主要讲解k8s源码中基于Scheme的编解码机制, Scheme就像一个类型大管家,内部注册了各种GVK, 所以使用静态客户端的时候,我们才能无感的直接得到静态类型的指定对象,而不是像动态客户端得到一个Unstructured。