kubernetes架构设计解析
背景
之前对kubernetes有过一些简单的了解,但是并没有去深入的去理解每个组件之间是如何工作的,所以正好复习一下。
概要
首先看下官方给出来的架构图:
可以看到架构组件分为两类:
- 控制平面(control plane)
- 节点(node)
控制平面组件如下:
- kube-api-server
- etcd
- scheduler
- Controller Manager
- cloud-controller-manager
节点组件如下:
- kubelet
- kube-proxy
控制平面
kube-api-server
api-server主要作用是负责处理客户端请求,包括但不限于kubectl,client-go等等。并且对外提供 RESTful 的接口,也是唯一一个可以和etcd集群通信的组件。
客户端会使用Kubernetes API来访问集群,API Server在接收请求之后会进行验证:
- 身份认证(Authentication): 检查请求的身份信息(例如,证书、Token)。这确保只有经过身份验证的用户才能执行相应的操作。
- 授权(Authorization): 确保用户有足够的权限执行请求的操作。
- 准入控制(Admission Control): 该阶段可以进行自定义的验证和修改。例如,可以实现资源配额、标签自动填充等功能。
- 调用适当的资源对象:API Server 根据请求的 API 路径和操作,调用相应的资源对象处理请求。这可能涉及到对 etcd 中的资源对象进行增、删、改、查等操作。
- 存储层(etcd)交互:如果请求涉及对资源对象的增、删、改操作,API Server 会与 etcd 进行交互,将操作写入或读取自 etcd 存储。etcd 用于持久化存储整个集群的配置信息。
- 返回结果给客户端: API Server 处理完请求后,将结果返回给客户端。结果中包含了请求的执行状态、资源对象的详细信息等。
这里用创建pod做一个简单的例子,先暂时忽略其他组件,只关心api server和etcd交互:
- 客户端使用 Kubernetes API(例如,通过 kubectl 或自定义的客户端)发送创建 Pod 的 API 请求到 API Server。
- API Server对请求进行校验,包括但不限于身份认证,授权等等。
- API Server根据请求中的路径和操作,调用对应资源处理请求。
- API Server和etcd进行交互,它会构建出创建 Pod 资源对象在 etcd 存储中的键,然后将创建 Pod 的请求写入 etcd 存储。
- etcd 接收到 API Server 的请求后,将创建 Pod 的相关信息持久化到其分布式一致性键值存储中
- 最后,API Server 将创建 Pod 的操作结果返回给客户端。结果中可能包含创建成功的信息、Pod 的详细信息等。
etcd
etcd存储了整个集群的元数据,一般提到K8S高可用设计,也是指对etcd做高可用,所以可以看出来etcd的重要性。以下是etcd为K8S提供的作用:
- 分布式一致性存储: 用来保存和管理 Kubernetes 集群的所有配置数据、状态信息以及元数据。这些数据包括了集群的整体配置、节点信息、服务发现、Pod 状态、网络配置等。etcd 提供了高度一致性和可靠性,确保数据的安全存储和可靠检索。
- 集群状态维护: Kubernetes 中的各个组件需要协同工作以保持整个集群的健康状态。etcd 提供了一个共享的数据存储,使得各组件可以轻松地读取和更新集群的状态。这包括了节点的健康状态、服务的注册和发现、Pod 的分配等。
- Configuration Data: etcd 存储了 Kubernetes 集群的所有配置信息,包括 API Server 的配置、节点信息、网络配置、存储卷配置等。这些配置数据可以在运行时动态地更新,而不需要停止整个集群。
scheduler
scheduler作用是根据request和limit为Pod调度一个合适的节点,每次只调度一个Pod资源对象,为每一个Pod资源对象寻找合适节点的过程就是一个调度周期,以下是scheduler主要作用:
- 节点选择: Scheduler 根据用户定义的调度策略,选择合适的节点来运行新创建的 Pod。这些策略可以包括硬件约束、亲和性(Affinity)和反亲和性(Anti-Affinity)规则、资源需求等。
- 负载均衡: Scheduler 努力确保各个节点的资源负载相对均衡,以充分利用整个集群的计算资源。通过智能地分配 Pod,Scheduler 可以避免资源过度集中在某些节点上,提高整个集群的利用率。
- 调度决策: Scheduler 基于当前集群状态和用户定义的策略,做出调度决策。这可能涉及节点资源的可用性、Pod 的优先级、亲和性规则等多个因素的权衡。
- 动态调度: Kubernetes 的 Scheduler 不仅在 Pod 创建时进行调度,还会监控集群状态的变化,动态地进行重新调度。例如,当节点故障或新节点加入集群时,Scheduler 可以重新调整现有 Pod 的分布,确保它们仍然满足调度策略。
- 可插拔性: Kubernetes 的 Scheduler 是可插拔的,用户可以根据自己的需求实现自定义的调度器,并将其集成到 Kubernetes 中。这样可以根据特定的业务场景或策略来定制调度行为。
Controller Manager
Controller Manager管理K8S集群中节点,Pod副本,服务,端点(Endpoint),命名空间等等。举个稍微复杂的例子,假设K8S是一个房子,房子里面会有各种各样的设备,比如空调,热水器,温度调节器等等。为了让房间内更加舒服。你把温度调节器设置在30度,同时又想洗个热水澡,去把热水器调到50度。这些都是你的期望状态。之后这些设备开始工作,它会确保这些设备达到这些期望状态。这些设备就是控制器(Controller),而Controller Manager就是统一管理这些控制器的。
cloud-controller-manager
这一块和Controller Manager差不多,主要是云厂商关心的比较多,这里就不过多介绍了。
Node
kubelet
kubelet运行在K8S每个节点上,用来接收,处理,上报kube-apiserver组件下发的任务,kubelet进程启动的时候会向kube-apiserver注册节点自身信息。
主要负责所在节点上的Pod资源对象管理,比如说Pod资源对象的创建、修改、监控、删除、驱逐及Pod生命周期管理等。并且周期性的上报节点信息给kube-apiserver组件。kubelet也会对所在节点的镜像和容器做清理工作,保证节点上的镜像不会占满磁盘空间、删除的容器释放相关资源。
除了上报信息之外,它还提供了三种接口:
- Container Runtime Interface:简称CRI(容器运行时接口):提供容器运行时通用插件接口服务。
- Container Network Interface: 简称CNI(容器网络接口): 提供网络通用插件接口服务。
- Container Storage Interface: 简称CSI(容器存储接口): 提供存储通用插件接口服务。
通过以上信息可以大概知道,kubelet主要作用是收集上报信息和通过三种接口去创建对应资源。
kube-proxy
kube-proxy作为节点上的网络代理,和kubelet一样,运行在每个节点上。它监控kube-apiserver的服务和端点资源变化,并通过iptables/ipvs等配置负载均衡器,为一组Pod提供统一的TCP/UDP流量转发和负载均衡功能。
kube-proxy是参与管理Pod-to-Service和External-to-Service网络的最重要的节点组件之一,以下是它的主要功能和作用:
- 服务代理:
kube-proxy
负责监听 Kubernetes 集群中的服务创建和删除事件。当有新的服务创建时,kube-proxy
会为该服务创建对应的代理规则。这些代理规则可以将服务的访问请求转发到正确的 Pod 上。 - 负载均衡: 对于 Service 类型为
LoadBalancer
或NodePort
的服务,kube-proxy
在每个节点上配置相应的规则,以实现负载均衡。这样,外部流量可以通过任何节点访问到服务,并且请求会被均匀分布到后端的 Pod 上。 - 服务发现:
kube-proxy
通过与 Kubernetes API 交互,获取服务的信息,包括服务的 IP 地址和端口号,以及后端 Pod 的 IP 地址和端口号。这样,它能够动态地更新代理规则,确保服务发现的准确性。 - 网络代理: 对于 Service 类型为
ClusterIP
的服务,kube-proxy
通过 iptables 或 IPVS 等技术,创建一组虚拟 IP 和端口规则,将流量代理到后端的 Pod。这样,即使 Pod 的 IP 地址发生变化,服务的虚拟 IP 不会改变,保证了服务的稳定性
总的来说,K8S Service是通过kube-proxy来实现的,它又是使用了iptables ,IPVS等等技术来实现Service。
Pod创建-查看组件之间调用
这里使用Pod创建来查看组件之间是如何配合的,以及它的一个调用链路。