Kubernetes 核心架构与高可用集群详解(含 100%部署成功的方案)
高可用方案
为了表述更加清晰,集群内各服务器情况如下:
部署高可用负载均衡器
为三个API Server服务部署HAProxy和Keepalived,使用VIP 192.168.233.18作为Mater结点的唯一入口地址,供客户端访问。
将HAProxy和Keepalived分别部署两个实例,组成高可用架构以避免单点故障。HAProxy负责将客户端请求转发到后端的3个kube-apiserver实例上,Keepalived负责维护VIP 192.168.233.18的高可用。
Kubernetes简介
Kubernetes是Google开源的一个容器编排引擎,一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,采用声明式配置[1],支持自动化部署、大规模可伸缩、应用容器化管理。
举个例子说明:通常情况下,在生产环境中部署一个应用程序时我们需要部署该应用的多个实例以便进行负载均衡,传统方式需要我们逐台服务器进入Docker进行部署,而如果使用Kubernetes,我们就可以将全部服务器建立一个集群,在集群中任意一个Master节点创建一个Service与多个容器Pod,每个容器Pod内运行一个应用实例,然后通过Kubernetes内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些过程的细节无需运维人员自行配置和处理,Kubernetes将全部自动完成。除此之外,运维或开发人员可以指定Pod的数量,Kubernetes将自动监控并确保集群始终处于预期的工作状态。
Kubernetes核心架构简析
Kubernetes是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则执行用户的程序。在Kubernetes中,主节点一般被称为Master Node 或者 Head Node,而从节点则被称为Worker Node 或者 Node。
Master节点通常包括API Server、Scheduler、Controller Manager等组件(他们在官方文档中被称为Control Plane Components[2],我们通常用Master组件代替),Node节点通常包括Kubelet、Kube-Proxy等组件(在官方文档中被称为Node组件)。
图1 Kubernetes 集群组件架构图(官网图)
Kubernetes可简称K8S,是用8代替名字中间的8个字符“ubernete”而成的缩写。为读者阅读方便,在下文中,我们将以K8S代替Kubernetes,除非特别说明,否则K8S均指代Kubernetes。
Kubernetes API server
K8S控制层的核心,是整个系统的数据总线和数据中心。K8S通过kube-apiserver这一进程API Server提供服务,该进程运行在K8S的Master节点上,默认有两个端口。API Server负责提供Http API,以供用户、集群中的不同部分和集群外部组件相互通信。[3]
K8S API Server在负责集群各功能模块之间的通信时,各模块通过API Server将信息存入ETCD,当需要获取和操作这些数据时,再通过API Server提供的REST接口(GET\LIST\WATCH方法)来进行操作,从而实现各模块之间的信息交互。
通过API Server用户可以查询和操纵K8S API 中对象(如:Pod、Namespace、ConfigMap 和 Event)的状态。[3]用户大部分操作都可以通过 kubectl 命令行接口或类似 kubeadm 这类命令行工具来执行,这些工具在背后也是调用 API,此外用户也可以使用 REST 调用来访问这些 API。[3]
Kubernetes Scheduler
K8S所有Worker Node 的调度器。K8S Scheduler 运行在Master节点上,它通过监听API Server将发现的每一个未调度的 Pod (PodSpec.NodeName为空的Pod)通过创建Binding 指示调度到一个合适的Worker Node上来运行。调度器会依据下文的调度原则来做出调度选择。
在一个集群中,满足一个Pod调度请求的所有 Node 称之为可调度节点。如果没有任何一个Node能满足Pod的资源请求,那么这个Pod将一直停留在未调度状态直到调度器能够找到合适的Node。[4]调度器先在集群中找到一个Pod的所有可调度节点,然后根据一系列函数对这些可调度节点打分,选出其中得分最高的Worker Node来运行Pod。之后,调度器将这个调度决定通知给API Server,这个过程即为Binding。[4]
Kubernetes Controller Manager
K8S所有Worker Node的监控器。Controller Manager作为集群内部的管理控制中心,运行在Master节点上,是一个永不休止的循环。它实质上是群内的Node、Pod、服务(Server)、端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的监视与守护进程的合集,每个资源的Controller通过API Server提供的接口实时监控每个资源对象的当前状态,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
ETCD
K8S的存储服务。ETCD是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。[2]K8S集群中只有API server有ETCD的读写权限。
Kubelet
K8S中Master节点在每个Worker Node节点上运行的主要“节点代理”,也可以说是Master 的“眼线”。它会定期向Master Node汇报自己Node上运行服务的状态,并接受来自Master Node的指示采取调整措施。负责控制由 K8S 创建的容器的启动停止,保证节点工作正常。
Kubelet基于PodSpec来工作的,每个PodSpec是一个描述Pod的YAML或JSON对象。Kubelet接受通过各种机制(但主要是通过 API Server)提供的一组 PodSpec,并确保这些 PodSpec中描述的容器处于运行状态且运行状况良好。[5]
Kube-Proxy
K8S的网络代理,在每个节点上运行,负责Node在K8S的网络通讯、以及对外网络流量的负载均衡。Kube-proxy维护节点上的网络规则,实现了K8S Service 概念的一部分,它的作用是使发往Service的流量负载均衡到正确的Pod。由于性能问题,目前大部分企业用K8S进行实际生产时,都不会直接使用Kube-proxy作为服务代理,而是通过Ingress Controller来集成HAProxy, Nginx来代替Kube-proxy。
Kubernetes高可用(HA)分析
Kubernetes 采用的是中心辐射型(Hub-and-Spoke)API 模式。 所有从集群(或所运行的 Pods)发出的 API 调用都终止于 API server,[6]而API Server直接与ETCD数据库通讯。若仅部署单一的API server ,当API server所在的 VM 关机或者 API 服务器崩溃将导致不能停止、更新或者启动新的 Pod、服务或副本控制器[7];而ETCD存储若发生丢失,API 服务器将不能启动。若要实现Kubernetes高可用,则Master组件必须是冗余的,尤其是ETCD、ApiServer必须部署在多个节点上。
根据这一核心要求,我们尝试构建如图2所示的集群,包含几个负载均衡的主节点,每个主节点包含完整的主组件和ETCD组件:
图2 Kubernetes 集群HA架构图
Node可靠性:Systemd作为Linux CentOS系统的管理守护进程,可确保Docker 后台支撑服务和Kubelet在发生故障时自动重启,以此确保Worker Node可靠。
集群状态维持:K8S集群状态信息存储在ETCD集群中,该集群非常可靠,且可以分布在多个节点上。需要注意的是,在ETCD群集中至少应该有3个节点,且为了防止2网络分裂,节点的数量必须为奇数。
API服务器冗余灾备:K8S的API server服务器是无状态的,从ETCD集群中能获取所有必要的数据。这意味着K8S集群中可以轻松地运行多个API服务器,而无需要进行协调,因此我们可以把负载均衡器(LB)放在这些服务器之前,使其对用户、Worker Node均透明。
Master选举:一些主组件(Scheduler和Controller Manager)不能同时具有多个实例,可以想象多个Scheduler同时进行节点调度会导致多大的混乱。由于Controller Manager等组件通常扮演着一个守护进程的角色,当它自己失败时,K8S将没有更多的手段重新启动它自己,因此必须准备已经启动的组件随时准备取代它。高度可扩展的Kubernetes集群可以让这些组件在领导者选举模式下运行。这意味着虽然多个实例在运行,但是每次只有一个实例是活动的,如果它失败,则另一个实例被选为领导者并代替它。[8]
K8S高可用:只要K8S集群关键结点均高可用,则部署在K8S集群中的Pod、Service的高可用性就可以由K8S自行保证。
特别的,负载均衡节点承担着Worker Node集群和Master集群通讯的职责,同时Load Balance没有部署在K8S集群中,不受Controller Manager的监控,倘若Load Balance发生故障,将导致Node与Master的通讯全部中断,因此需要对负载均衡做高可用配置。Load Balance同样不能同时有多个实例在服务,因此使用Keepalived对部署了Load Balance的服务器进行监控,当发生失败时将虚拟IP(VIP)飘移至备份结点,确保集群继续可用。
经过上述分析,可知在正式环境中确保Master高可用,并启用访问安全机制,至少应包括以下几个方面:[9]
-
Master的kube-apiserver、kube-controller-mansger和kube-scheduler服务至少三个结点的多实例方式部署。
-
ETCD至少以3个结点的集群模式部署。
-
Master、ETCD集群启用基于CA认证的HTTPS安全机制,Master启用RBAC授信机制。
-
Load Balance使用双机热备,向Node暴露虚拟IP作为入口地址,供客户端访问。
Kubernetes核心架构与高可用集群详解(含100%部署成功的方案)
相关文章:
Kubernetes核心架构与高可用集群详解(含100%部署成功的方案)
手把手从零搭建 k8s 集群系列(三)高可用(灾备)切换
使用 KubeKey 内置 HAproxy 创建高可用集群
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)