Kubernetes集群分为两部分(官网介绍):
- 控制平面(Master components provide the cluster’s control plane)
- etcd分布式持久化存储
- API服务器(kube-apiserver)
- 调度器(kube-scheduler)
- 控制器管理器(kube-controller-manager)
- 工作节点(Node components run on every node)
- kubelet
- kube-proxy
- 容器运行时(Container Runtime)
附加组件:
- Kubernetes DNS服务器
- Web UI (Dashboard)
- Ingress Controller
- 容器集群监控(Heapster)
- 容器网络接口插件
组件关系图:
etcd
Kubernetes所创建的对象(Pod、ReplicationController、Service、Secret等)需要以持久化方式存储到某个地方,这样它们在API服务器重启或者失败的时候才不会丢失,因此引入了etcd
etcd是一个响应快、分布式、一致的kv存储,可以运行多个etcd实例来获取高可用性和更好的性能,etcd 是Kubernetes存储集群状态和元数据的唯一的地方
唯一能直接和 etcd 通信的是API服务器,所有其他组件通过API服务器间接地读取、写入数据到 etcd,这带来一些好处:
- 增强乐观锁系统、验证系统的健壮性
- 通过把实际存储机制从其他组件抽离,未来替换起来也更容易
etcd 使用 RAFT 一致性算法(要求集群大部分节点参与才能进行到下一个状态),确保在任何时间点,每个节点的状态要么是大部分节点的当前状态,要么是之前确认过的状态(部署奇数实例数)
api server
api server 作为中心组件,其他组件或者客户端(如kubectl)都会去调用它(以Restful API形式):
- 通过认证插件认证客户端
API 服务器会轮流调用这些插件,直到有一个能确认是谁发送了该请求,这是通过检查HTTP请求实现的
- 通过授权插件授权客户端
它们的作用是决定认证的用户是否可以对请求资源执行请求操作
- 通过准入控制插件验证AND/OR修改资源请求
如果请求尝试创建、修改或者删除一个资源,请求需要经过准入控制插件的验证,服务器会配置多个准入控制插件,这些插件会因为各种原因修改资源,可能会初始化资源定义中漏配的字段为默认值甚至重写它们,插件甚至会去修改并不在请求中的相关资源,同时也会因为某些原因拒绝一个请求。资源需要经过所有准入控制插件的验证(读取数据不会做准入控制的验证)
准入控制插件包括:AlwaysPullImages、ServiceAccount、NamespaceLifecycle等,具体查看官网 - 验证资源以及持久化存储
其它客户端通过创建到 api server 的 HTTP 连接来监听变更,每当更新对象,api server会将新对象发送给监听了该对象的客户端(比如Controller、Kubectl等等),客户端接收到后执行相应任务
调度器(schedule)
通常我们不会去指定pod应该运行在哪个集群节点上,而是交给调度器来完成,调度器不会命令选中的节点(或者节点上的Kubelet)去运行pod,而是通过api server更新pod的定义,然后通知kubelet去创建并且运行pod的容器
调度器最为重要的是调度算法,找到pod最优节点,这个其它篇幅中说明
在集群中可以运行多个调度器,在pod中可以通过设置 schedulerName
属性来指定调度器,未设置由默认调度器调度(default-scheduler)
控制器(controller)
Kubernetes中主要有以下控制器:
- Replication管理器 (ReplicationController资源的管理器)
- ReplicaSet、 DaemonSet 以及 Job 控制器
- Deployment控制器
- StatefulSet控制器
- Node控制器
- Service控制器
- Endpoints控制器
- Namespace控制器
- PersistentVolume控制器
- …
总的来说,控制器执行一个“调和“循环,将实际状态调整为期望状态(在资源spec部分定义),然后将新的实际状态写入资源的 status 部分。 控制器利用监听机制来订阅变更,但是由于使用监听机制并不保证控制器不会漏掉事件, 所以仍然需要定期执行重列举操作来确保不会丢掉什么
Kubelet
Kubelet 运行在工作节点上,负责所有运行在工作节点上的组件:
- 在api server中创建一个node资源来注册该节点
- 持续监控api server是否把该节点分配给pod,启动pod
- 持续监控运行的容器,向api server报告它们的状态、事件和资源消耗
- 它也是运行容器存活探针的组件,当探针报错时它会重启容器
- 当pod从api server删除时,Kubelet终止容器,并通知api server该pod已经被终止
Kubelet也可以基于本地指定目录下的pod清淡来运行pod
kube-proxy
运行在每个节点上,监听 api server 中服务对象的变化,再通过管理 iptables 来实现网络的转发
支持三种模式:
- userspace(k8s v1.2 后就已经淘汰)
- iptables(默认方式)
- ipvs(需要安装ipvsadm、ipset 工具包和加载 ip_vs 内核模块)
参考博客:Kube-Proxy简述