k8s原理——关键组件

2021-08-01  本文已影响0人  雅阁驸马

1. master节点上的组件:

etcd:
API Server:
Scheduler:
Controller Manager:
为了保证高可用,master节点的组件可以多实例运行,但是只有etcd和API Server可以同时并行工作,Scheduler和Controller Manager在同一时间内只能有一个实例处于运行状态,其他实例处于待命模式。

1.1 etcd

1.1.1

k8s里的所有对象:pod,ReplicationContorller,service,secret等等的元数据都需要以持久化的方式存储到某个地方,这样组件重启了元数据才不会丢失。

1.1.2

唯一能和etcd通信的组件是API server,其他组件要和etcd通信都要通过API Server。这样也保证了API Server能通过乐观锁的方式更新etcd。

1.1.3 etcd存储资源的方式:

etcd v2: 类似于文件系统,每个key要么是一个目录(包含其他key),要么是一个常规key,对应一个value。例子:

/registry/pods     //pods是一个目录
/registry/namespace
...

etcd v3: 不支持目录,但是key可以包含斜杠,其实就跟目录差不多。例子(etcd v3不支持 ls命令):

/registry/pods/default/kubia-159041347-xk0vc //直接列出key,没有目录
...

获取key对应的value:

{"kind":"Pod","apiVersion":"v1"....} //可以看出其实它就是我们创建pod时用的那个yml文件

1.1.4 HA

etcd是可以通过运行多个etcd实例来达到HA的。通常对于大集群,etcd有5个或者7个就够了,可以允许2-3个宕机(因为必须保证超过半数的机器还活着)
由于必须保证超过半数的机器还活着,所以etcd集群的实力个数通常都是奇数个。

1.2 API Server

其他组或者客户端(如kubectl)都会去调用它。以RESTful API的形式提供了可以查询,修改集群状态的接口(CRUD)。并把最终状态存到etcd。它是唯一一个能与etcd交互的组件。所有其他组件要与etcd通信来改变资源的配置时都需要通过apiServer。

提供三个功能:

  1. 作为统一的接口取访问etcd。
  2. 将资源描述文件(yml)存入etcd之前,对文件做校验。这样客户端kubectl就无法存入非法对象了
  3. 提供了乐观锁机制,这样多个客户端kubectl并发更新的情况下,不会出现先更新的覆盖后更新的。

1.2.1 一个请求从客户端kubectl发出来之后,在api server中的流程

  1. API Server上会被配置一个或者多个认证插件(Authentication plugin), 轮流调用这些插件对客户端kubectl发过来的请求做认证,以确认是哪个用户发送的该请求。
  2. 同上,会配置多个授权插件(Authorization plugin),轮流调用这些插件,判断是否授权客户端执行相应的请求。
  3. 同上,多个准入控制插件(Admission control plugin),对创建,修改,删除资源的操作,进行校验,其实就是看看你的yml文件写的对不对,是不是有语法错误(有语法错误就拒绝请求),给你漏配的字段填写默认值等。注意如果只是读数据,则不会做准入控制的验证。

1.2.2 API Server提供了监听的功能,以通知各个组件,当前资源发生了改变。

比如说客户端kubectl创建一个pod,api server收到请求后把它存入etcd。那controller manager是怎么知道现在它需要去创建一个pod的呢?答案是controller manager注册了对api server的监听。一旦有资源的变化,api server都会回调controller manager。

//这个命令就可以创建kubectl对api server的监听,一旦有新的pod创建,
//api server就会回调到这里
kubectl get pods --watch  

1.3 Scheduler

利用API Server的监听机制,等待新创建的pod,然后给每个新的pod分配Node。

注意:Scheduler不会去命令某个node运行pod。

1.3.1 Scheduler最核心的其实就是调度算法了,调度算法分2步:

1.3.2 Scheduler也是可以有多个的

在给pod定义的时候就可以指定SchedulerName来指定这个pod被哪个Scheduler调度。没配的话就会用k8s默认的调度器,default-scheduler。

1.4 Controller Manager控制器管理器

包括:
ReplicationController Controller
ReplicaSet/DaemonSet/Job controller
Deployment Controller
StatefulSet Controller
Node Controller
等等...
它们的主要的作用就是确保集群里的资源的真实状态,朝着跟yml中定义的期望状态收敛。

1.4.1 ReplicationController

比如说某个ReplicationController中定义了pod的个数是3个,当前只有2个pod的话,ReplicationController Controller就需要通过API Server再创建一个pod。如果有4个,就需要删除一个。
需要注意的是,ReplicationController并不会去轮询所有pod,而是通过API Server的监听机制订阅可能影响期望值的replica数量或者符合pod数量变化的事件。ReplicationController收到这些事件的通知后就会去检测期望的replica的数量和实际pod的数量,然后作出相应操作(创建/删除pod)。

大概流程:

  1. 通过kubectl apply创建一个replicationController资源。
  2. API Server收到请求,并将yml文件写入etcd。
  3. ReplicationController组件收到回调,然后查看当前pod个数(此时当前pod个数肯定是0了),然后通过API Server创建pod。
  4. API Server把创建pod的 yml文件写入etcd.
  5. scheduler收到监听,给pod找匹配的Node。
  6. scheduler找到匹配的node后,通过API Server更新pod的yml,写入etcd。
  7. node上的kubelet收到监听消息,开始创建pod。

其他的控制器跟replicationController差不多,都是确保集群里的资源的真实状态,朝着跟yml中定义的期望状态收敛。

1.4.2 DeploymentController

每次Deployment对象修改后,如果修改会影响到部署的pod,DeploymentController都会创建一个新的replicaSet,然后按照Deployment中定义的策略同时伸缩新,旧的replicaSet。

2. 工作节点上的组件:

kube-proxy:
kubelet:
容器;

2.1 kubelet

功能:

2.2 kube-proxy

kube-proxy的作用是用来确保客户端的请求(客户端通过service的IP+端口)可以顺利到达对应的pod。
之前说过,service创建后,对应会创建endpoint。客户端的请求过来后,kube-proxy会根据endpoint中的ip+port列表选择一个,然后转发请求。

kube-proxy有2种模式:
userspace代理模式
iptables代理模式(性能更好)

上一篇 下一篇

猜你喜欢

热点阅读