当前位置:网站首页>Kubernetes 架构核心组件工作原理解析
Kubernetes 架构核心组件工作原理解析
2022-06-24 19:50:00 【富士康质检员张全蛋】
Kubernetes∶声明式系统
Kubernetes 的所有管理能力构建在对象抽象的基础上,核心对象包括∶
- Node∶计算节点的抽象,用来描述计算节点的资源抽象、健康状态等。
- Namespace∶资源隔离的基本单位,可以简单理解为文件系统中的目录结构。
- Pod∶用来描述应用实例,包括镜像地址、资源需求等。 Kubernetes 中最核心的对象,也是打通应用和基础架构的秘密武器。
- Service∶ 服务如何将应用发布成服务,本质上是负载均衡和域名服务的声明。
Kubernetes采用与borg类似架构
APIServer可以简单理解为Rest server,它接受外部请求的,无论是通过命令行还是浏览器,这些请求都会被转化为rest的调用,发到APIServer里面,APIServer会将请求存放到自己数据库里面就结束了,APIServer就做这些事情,接受请求,并且存储。
etcd本身是个数据库,其次etcd访问有种模式叫做watch模式,也就是当你去get一个对象的时候,你可以加一个watch的参数,那么客户端的这次get请求首先会完成,其次连接不会断掉,客户端会和etcd保持长连接,要请求的对象后续发生任何的变换,etcd会主动的将这个变化以事件的形式推送给客户端。
所以etcd 第一 是一个数据库 第二 是个消息中间件,任何对象的变更都会推送,所以Apiserver会去和etcd做连接,apiserver将数据推送到etcd,etc任何的对象变更,会主动通知apiserver。
apiserver除了去接受客户端和各个组件过来的请求,它也可以将对象的变更推送出去。所以这样的话整个系统就可以联动起来了,api server是简单的rest api,它提供了对象的传输,接受其他所有组件请求(上图可以看到,所有组件都是连接到api server的),也就是其他组件之间不互相通信,其他组件都和api server通信,将请求发送给apiserver,apiserver做认证,鉴权,校验之后将数据存储到etcd,任何对象的变化都会推送给其他的组件。
通过上面消息的机制来驱动整个系统的变化。
在管理节点上面还有两个重要组件,schedule,用户创建pod会被,会被apiserver接收到,apiserver就会告诉schedule有这么一个调度需求去做调度,schedule就会去做调度,先看你的pod需要多少资源,也就是你的需求是什么,然后去看集群里面资源利用状况,这个资源状况哪里来的呢?每个节点上面有个kubelet,第一它会将资源信息上报,报告每个节点的健康状况和资源使用情况,apiserver接收到这些请求之后,同样将数据存放到etcd里面,同时schedule能够接受到变化的请求,所以shcedule是知道集群整个资源利用情况的。
接收到调度请求之后,调度器就有能力帮它选择最适合的节点,完成调度,所谓的完成调度就是将pod和节点绑定,告诉APiserver,apiserver将pod的信息里面nodename属性更新到etcd里面保存下来。
最后kubelet就会去看和我这个节点相关的pod有些哪些,如果新的pod和我相关我就去拉起进程。
上面就是控制面组件的合作关系
各个组件细节
apiserver其实就是整个集群的api 网关,那么就包括认证和鉴权,确保客户端请求是合法的,并不是谁都可以给我发指令,我需要知道你是谁,其次还需要做鉴权,知道你是谁但是不代表你有整个集群的权限,所以要去校验有没有这个权限,最后你有这个权限,但是也不代表你的操作是合法的,所以要做准入控制。
conrtol manager管理了一堆的控制器,比如deployment控制器,replicate,lifecycle控制器,他们分别用来管理不同的对象。
control manager是让整个集群运作起来的核心,它是一个大脑,apiserver里面没有什么业务逻辑,它就接受请求,只要你有权限,请求又是合法的,就存一下,这就是apiserver的动作,这个请求存下来之后,具体怎么做是由control manager去做的。
工作节点上面的kubelet:第一 上报节点的健康状态和资源需求,第二 维护当前节点pod的生命周期,第三 cadvisor收集容器的资源使用情况
kube-proxy:就是你去定义service的时候,发布服务的时候要为这个服务配置负载均衡。
Kubernetes 主节点(Master Node)
kubeadm安装的集群默认将控制面的组件安装到了kube-system下面
[[email protected] ~]# kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-97769f7c7-7md6n 1/1 Running 8 65d
calico-node-445z4 1/1 Running 5 65d
calico-node-5j6fg 1/1 Running 6 65d
calico-node-bjqq6 1/1 Running 5 65d
coredns-6d56c8448f-6zm8m 1/1 Running 5 65d
coredns-6d56c8448f-pltwl 1/1 Running 6 65d
etcd-master 1/1 Running 5 65d
kube-apiserver-master 1/1 Running 3 34d
kube-controller-manager-master 1/1 Running 9 35d
kube-proxy-7ffvg 1/1 Running 5 65d
kube-proxy-j75lv 1/1 Running 5 65d
kube-proxy-npt9k 1/1 Running 6 65d
kube-scheduler-master 1/1 Running 16 65d
metrics-server-b66888848-c2p6b 1/1 Running 11 34d
Kubernetes 工作节点(worker node)
ETCD
etcd是分布式的存储,它一般要做两件事情,一件事情是选主,选出哪个是master,所有的写需求经由master,否则当所有member都接受写操作,那么就会发生冲突.
raft协议保证两个事情,第一个通过投票方式选主,选择一个节点为leader,所有写操作从leader去做,其次leader在接收到写操作的数据之后,会将写的指令下发,下发到其他的节点上面去,其他节点通过某种机制来保证和leader同步,这样才能保住数据的一致性。
第二个etcd支持监听机制的,它也是消息中间件,
直接访问Etcd数据
etcdctl是操作etcd的客户端工具,可以yum安装,也可以进入etcd pod当中自带了。
下面是去get一些值,因为是键值对存储,我要去get所有的key,key一斜杠/开头我就可以将其打印出来,通过这样的方式就可以看到当前集群在etcd当中存储的路径。
[[email protected] etcd]# ETCDCTL_API=3 etcdctl --endpoints https://localhost:2379 --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key --cacert /etc/kubernetes/pki/etcd/ca.crt get --keys-only --prefix / | head -n 10
/registry/apiextensions.k8s.io/customresourcedefinitions/bgpconfigurations.crd.projectcalico.org
/registry/apiextensions.k8s.io/customresourcedefinitions/bgppeers.crd.projectcalico.org
/registry/apiextensions.k8s.io/customresourcedefinitions/blockaffinities.crd.projectcalico.org
/registry/apiextensions.k8s.io/customresourcedefinitions/caliconodestatuses.crd.projectcalico.org
/registry/apiextensions.k8s.io/customresourcedefinitions/clusterinformations.crd.projectcalico.org
如果要监听对象的变化可以使用watch操作来监听,任何对象发生了变化,一旦敲了这条命令,那么就保持在那,一旦有对象发生了变更它就会通知你,这就是它的消息机制。
[[email protected] ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dns-test 1/1 Running 3 36d
nginx-74d69c5bbb-6478r 1/1 Running 3 34d
nginx-74d69c5bbb-mhmsc 1/1 Running 3 34d
nginx-web-0 1/1 Running 4 36d
nginx-web-1 1/1 Running 3 36d
[[email protected] ~]# kubectl delete pod nginx-web-1
pod "nginx-web-1" deleted
[[email protected] etcd]# ETCDCTL_API=3 etcdctl --endpoints https://localhost:2379 --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key --cacert /etc/kubernetes/pki/etcd/ca.crt watch --prefix /registry/statefulsets/default/nginx-web
PUT
/registry/statefulsets/default/nginx-web
k8s
apps/v1
StatefulSet
nginx-webdefault"*$08a540f1-83b9-4575-9441-7e2a1e079e0528..b?
0kubectl.kubernetes.io/last-applied-configuration.{"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"annotations":{},"name":"nginx-web","namespace":"default"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"nginx_test"}},"serviceName":"nginx-test","template":{"metadata":{"labels":{"app":"nginx_test"}},"spec":{"containers":[{"image":"nginx:1.11","name":"nginx-test","ports":[{"containerPort":80,"name":"nginx-web"}]}]}}}}
z.
APIServer
apiserver本身是rest server,所以它的扩展是比较简单的,etcd是一个有状态的,对于有状态的加减一个member还是需要做些配置,对于无状态的apiserver来说就只需要做水平扩展就行了,如果不够了添加一个apiserver实例就行了,前面负载均衡把这个实例加进来就行了。
准入其实又分为两个阶段 mutating:你要建一个对象,这个对象发到apiserver了,但是从集群层面上来说要给这个对象做些变形,给你增加一些属性,或者改变某些值,这个时候就可以通过mytating操作在apiserver接收到请求到存储到etcd过程中给你原始的需求里面添加一些其他的属性,这样方便做平台层面的一些动作。
valiting:前面做了那些操作,你可能mutat了一个对象,变形了,但是对象是否合法呢?后面还有一些校验逻辑的,加一些validting的逻辑,比如一个对象的名称不能超过10,那怎么办,加一个validting的规则,让它去校验一下,如果超过10,就不让它通过,这里就需要实现准入了逻辑,准入不通过,那么就不会存储到etcd当中。
认证,鉴权,准入是三道门,任何一道门不通过请求就被废弃掉了,它不会存储到etcd里面。
apiserverf本身还是一个缓存,apiserver是唯一一个和etcd通信的组件,etcd本身规是分布式的键值对,可想而知性能不好特别的好,如果有海量的需求那么是一定没有办法帮你处理的。
apiserver里面维护了一份数据的缓存,如果是读操作,etcd这边是有cache的,如果在cache当中就直接返回给你了,这个请求不会发送到etcd里面去。
APIserver展开
apiserver是一个rest server,他要去注册每个对象的handle,所以有个api handle的过程,接下来会去做认证,做完认证之后要去做限流,限流就是自我保护,每个apiserver节点都有承受上线的,如果不做限流那么很可能并发就将其打死了,之后来到audit做审计,任何的对象操作会记录log,为了日后的安全审查,在之后authz就是做鉴权的,k8s自己支持RBAC的,另外你也可以编写自己的webhook去做鉴权。
Aggregator:因为本身apiserver作为一个rest api,它其实是有能力和nginx反向代理软件一样来做一些路由配置,比如你是标准的k8s对象,那么你就走默认的k8s apiserver,那么muta valid就继续往下走了,所有路走完了就到etcd了,但是如果我有额外的扩展对象,这些额外的对象我不想在k8s本身实例里面去实现,我希望有自己的逻辑,那么就需要自己去写aggregated apiserver,aggregate会去看你这个对象在另外一个apiserver里面那么就会将请求转到这个aggregated apiserver,在之后的逻辑和上面是一样的,只不过是独立部署的apiserver。
Controller Manager
整个集群的大脑是谁呢?是谁让集群变为声明式的系统,并且可以保证用户的期望和真实状态保持一致呢?就像你设置了空调温度25°,但是总要有空调外机去干活,去干活就要确保室温满足那个要求,在k8s里面由control manager去实现的,control manager是整个集群的大脑。
它里面有很多的控制器,很多的控制器都有不同的职责,所有的控制器都遵循同样的规范,先去读用户的这个抽象对象,这个对象里面有用户的期望状态,它读取到期望状态就需要去干活了,它就需要去做真实的配置,确保系统的真实状态和用户的期望状态保持一致。
控制器的工作流程
针对任何对象,k8s其实他有一些辅助工具叫做codegenerator,会帮你生成对象一些访问框架和代码框架,这个代码框架主要是control interface,分为两个部分,一部分为informer,另外一部分为lister,任何的对象k8s允许你去做监听,所谓的informer就是相当于去监听某个对象,你可以通过informer的框架去监听某个对象,这个对象发生任何的状态变化,比如增删改查这些写的动作,它都会生成新的event。控制器利用这个framework之后就需要去监听这些事件,任何的控制器都是生产者和消费者模型,监听到这些事件之后将Key拿出来(informer上面的部分其实是生产者,生产者去监听这些对象的事件,然后注册你的handle,它做的就是将对象时间的key存放到一个队列里面去,消费者就是worker thread,它要做的就是从队列里面取出数据,取出来去做配置)
lister部分是用来干嘛的呢?相当于所有kuebernetes在list watch之后,它会在客户端那边存一个缓存,也就说通过List可以直接在客户端这边拿到这个对象的缓存状态,而不需要去访问apiserver了。list更多的是提供了接口,让你从clicent-cache里面获取对象。
Informer的内部工作机制
上面是APIserver,shareinformer通过list watch去关注一个对象,所谓list watch就是第一,他会将所有对象list返回回来,第二作为一个长连接,关注它后续的变更,所有这些框架都是通用的。
但是这个框架所关注的不同的对象是怎么转换的呢?就是informer里面有reflector,就是按照你给定的对象的类型,(本身apiserver是个rest server,它传回给你的是json或者protobuffer序列化的对象,那你要做反序列化,要将其转化为指定的对象,那么九通过反射的机制,去转化为不同类型的对象 )这里就有一个delta fifo quenue,这个对象最后会存到thread safe store,就是List部分,这部分对象无论是被list到还是watch到,它的事件变化都会都会通过informer发送到handler,由handler处理这些对象事件。
控制器协同工作原理
当命令敲下去做了什么,第一将deployment创建出来了,就这样结束了,这个请求就被发到apiserver了,加上-v 9。
客户端做的第一件事情是它去读取config file,这个就是默认kubectl读取的配置
这个配置里面有什么呢?
这里面有我的apiserver的地址,已经客户身份的一些认证信息,所以他会将请求发送到api server的地址
所以通过create -f或者apply -f,就将这个deployment发送到apiserver去了,apiserver要做认证,鉴权,准入,做完之后就将请求存放到etcd里面去了,存放好之后这个时候,控制器就开始工作了,(control manager里面是有很多control的),deployment control关注的是deployment这个对象,他会去解析deployment对象,然后利用这个模板去创建一个应用,deployment它就会去创建副本集的对象叫replicaset,replicaset就是副本集,也就是deployment告诉apiserver我创建了一个副本集,这个副本集里面有个对象,然后模板是怎么样的,这个副本集被apiserver接受了之后,一样结果认证,鉴权,准入控制存入到etcd里面。
这个时候replicaset controller会watch apiserver,监听replicaset对象,他发现replicaset对象被创建了,它就需要去解析了,你需要几个副本以及pod的模板是怎么样的,那么replicatset controller就会去创建pod,这个pod一样会提交到apiserver这边,在Pod刚刚创建出来它有一个属性叫做nodename,刚创建出来nodename属性是空的,也就是pod没有经过调度的,它没有和任何节点产生绑定关系,这个时候调度器就去工作了,它去集群节点里面,找一个适合这个pod的节点,并且绑定pod,那么nodename这个值就被调度器填上了。
之后pod就和节点产生了绑定关系,这个节点就会去加载这个pod,通过容器运行时,将容器进程拉起来,(kubernetes将这些都标准化了,抽象为cri cni csi),通过cni插件将网络配置起来通过csi将存储帮它挂载上去,这样就完成了pod应用的加载。
schedule
调度器predict阶段:你一个集群多少个节点,pod有一个pod的资源需求,先将不满足需求的过滤掉,比如资源不足,端口冲突。
过滤出来的节点就要去评分,里面有很多的插件,按照不同的维度,权重去评分,然后选择评分最高的节点,作为pod的被选节点。
最后通过bind的操作将节点和pod产生绑定关系。
Kubelet
Kube-proxy
推荐的Add-Ons
上面是kubernetes的核心组件,kubernetes还有一些Add-Ons组件,最核心的就是kube-dns,就是整个集群的域名服务,没有核心组件集群是启动不起来的,add-on是指有了核心组件,add-ons可以以用户创建pod的方式去启动起来。
边栏推荐
- JDBC —— 数据库连接
- The third generation of power electronics semiconductors: SiC MOSFET learning notes (V) research on driving power supply
- Current situation and development prospect forecast report of global and Chinese tetrahydrofurfuryl alcohol acetate industry from 2022 to 2028
- Outer screen and widescreen wasted? Harmonyos folding screen design specification teaches you to use it
- C program design topic 15-16 final exam exercise solutions (Part 1)
- Analysis report on operation trend and investment strategy of global and Chinese tetrahydrofurfuryl propionate industry from 2022 to 2028
- Analysis report on development mode and investment direction of sodium lauriminodipropionate in the world and China 2022 ~ 2028
- 信号完整性(SI)电源完整性(PI)学习笔记(一)信号完整性分析概论
- vim使用命令
- Related operations of ansible and Playbook
猜你喜欢
5G dtu无线通信模块的电力应用
Color gradient gradient color collection
Use and click of multitypeadapter in recycleview
MySQL log management
After 5 years of software testing in didi and ByteDance, it's too real
Paper review: U2 net, u-net composed of u-net
【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学
无需显示屏的VNC Viewer远程连接树莓派
More pictures | explain the Nacos parameters in detail!
Go crawler framework -colly actual combat (II) -- Douban top250 crawling
随机推荐
MySQL日志管理
Android SQLite database
The new employee of the Department after 00 is really a champion. He has worked for less than two years. The starting salary of 18K is close to me when he changes to our company
Report on operation mode and future development trend of global and Chinese propenyl isovalerate industry from 2022 to 2028
What exactly is Nacos
Transition from digitalization to intelligent manufacturing
How can I persuade leaders to use DDD to construct the liver project?
How does VR panorama make money? Based on the objective analysis of the market from two aspects
MySQL log management
ArcGIS loads free online historical images as the base map (no plug-ins are required)
How to use promise Race() and promise any() ?
Virtual machine - network configuration
5-minute NLP: summary of 3 pre training libraries for rapid realization of NER
Hibernate learning 3 - custom SQL
无人驾驶: 对多传感器融合的一些思考
【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学
Overview of medium and low speed aerospace electronic bus
svg+js键盘控制路径
JPA learning 1 - overview, JPA, JPA core annotations, JPA core objects
Basic summary of MySQL database knowledge