上图是Kubernetes的架构图,内部繁多的组件和集群让人眼花缭乱,但是如果我们按步骤慢慢解读,从外到内依次解读,其实Kubernetes的架构设计并不难理解。
Control Plane(Master)
控制平面(Control Plane)是负责调度整个Kubernetes的中枢,也是程序与Kubernetes的交互区域,由程序发送指令给到Kubernetes的Control Plane,,再由Control Plane 下达指令给指定的Node节点或者所有Node,Node根据其指令进行自我调整。Control Plane内部组件如下:
kube-api-server
该组件的核心功能是统一管理和开放Kubernetes暴露的API,kubectl
命令其实就是其中一种发送API请求的方式,当然,我们也可以通过其他程序通过远程调用的方式来访问API。
etcd
该组件是Kubernetes的存储组件,我们定义的Deployment配置就被存储在etcd中。
scheduler
负责资源调度,根据资源环境按照某种策略将Pod分配到指定Node节点上。
Controller Manager
资源的自动化控制中心。
它通过 kube-api-server 监视集群的共享状态,并进行更改,尝试将当前状态移至所需状态。目前 Kubernetes 附带的控制器下图所示:
从上图中可以看出,Cotroller Manager 就是将我们定义的yaml资源描述文件形成真正的运行机制的执行者。其内部有八大管理器,每一个管理器都关注自身的管理职责,例如,Replication Controller就是对资源的管理,也就是我们定义的Deployment,在早期定义中,并没有Deployment的概念,只有Replication Controller(RC)的资源描述类型,在Kubernetes1.2中为了更好的解决容器的编排问题才引入Deployment概念,与RC的相似度高达90%。
Node
工作节点(Node)是真正执行具体任务的区域,由它来保证整个程序的运行环境,一般一台物理机(虚拟机)放置一个节点。
kubelet
负责Pod中容器的创建、启停等工作。
kube-proxy
实现Kubernetes Service的通讯和负载均衡,不同的Pod集群或者Node节点的IP和端口都不相同,如果没有一个统一的代理地址来进行对外暴露,资源访问的维护会变得非常困难,所以,通过代理来统一收发请求,并通过负载均衡打到最适合的节点和Pod上,是非常合适的方案。
Pod
在《体验Kubernetes》中曾经说过:我们可以将Pod当作容器来看待,但其实和容器还是存在差异的,更直接的讲,Pod应该承载着一组紧耦合的容器。
从上图中可以看到,Pod中存在两个容器,分别是File Puller 和 Web Server,其中,File Puller的职责是将文件下载到某个文件存储区域中,而Web Server的职责是将文件暴露给消费者或者客户端。
两个容器均需要对同一个存储区域进行操作,因此,这两个容器我们认为是紧耦合的。
因此,我们可以将Pod定义为一组容器的集合,但它是Kubernetes的最小执行单元。
值得注意的是,Kubernetes不直接操作某个容器,而是通过操作Pod来间接操作容器。
若Pod中的某个容器出现了异常情况,此时如何定义Pod的状态?
在Pod的内部结构中,除了用户定义的容器之外,还存在一个根容器(Pause),该容器是谷歌的定制容器,其最大的特点就是不易死亡其与其他容器资源共享(包括网络和挂载),这样,我们就可以根据该容器的状态来定义整个Pod的状态。
CRI(容器运行时接口:Container Runtime Interface)
我们知道,Kubernetes的前提是需要安装docker,当然,对于Kubernetes来说,它并不希望将自己的价值都体现在docker之上,难道脱离了docker就无法使用Kubernetes了吗?
Google当然不会允许这种情况发生(具体可以了解Kubernetes与Docker Swarm的商业斗争),因此,Kubernetes设计了一套容器标准接口,用来兼容任何容器化技术。
kubectl apply -f file
究竟发生了什么
我们看到的
当我们执行kubectl apply -f mysql-deploy.yaml
后,最终会形成一个mysql容器运行,在此期间,Kubernetes做了大量工作以保证容器按找我们定义的yaml期望状态进行容器创建,以下就是它的整个执行流程。
- 文件解析:
kubectl
解析指定的 YAML 或 JSON 文件,该文件包含 Kubernetes 资源的定义,如 Pod、Service、Deployment 等。 - API 请求:
kubectl
将解析后的资源定义转换为相应的 API 请求,然后通过 Kubernetes API 服务器向集群发送这些请求。 - 认证和授权: Kubernetes API 服务器接收到请求后,会进行身份验证(authentication)和授权(authorization)的过程。身份验证验证请求的来源,而授权确定请求是否具有执行所请求操作的权限。
- ETCD (存储): 一旦通过认证和授权,API 服务器将请求提交到集群中的 etcd 存储系统。etcd 是 Kubernetes 集群的分布式键值存储,用于保存整个集群的状态信息,包括所有的配置数据、状态和元数据。
- Controller Manager (控制器管理器): 控制器管理器是 Kubernetes 系统组件之一,它负责监控集群状态,并确保实际状态与期望状态一致。控制器管理器会检测到新的或更改的资源定义,然后采取必要的步骤来使实际状态与定义的状态一致。
- Scheduler (调度器): 如果是新的 Pod 资源,调度器(Scheduler)将决定在集群中的哪个节点上运行该 Pod。调度器会考虑节点资源、约束条件等因素来做出决策。
- CRI (容器运行时): 一旦调度器选择了节点,容器运行时会在该节点上启动容器。Kubernetes 支持多种容器运行时,如 Docker、containerd 等。
- 监控和反馈: Kubernetes 会监控运行中的 Pod 和其他资源,以确保它们按照预期运行。如果有任何问题发生,Kubernetes 将采取措施来恢复正常状态,例如重新调度 Pod、自动缩放等。