Kubernetes 的架构为什么是这样的?

Google 使用 Linux 容器有超过 15 年的时间,期间共创建了三套容器调度管理系统,分别是 Borg、Omega 和 Kubernetes。虽然是出于某些特殊诉求偏好先后开发出来的,但是在差异中我们仍然可以看到,后代系统中存在着前一代系统的影子,也就是说,它们之间传承了很多优良的设计。这也是为什么 Kubernetes 在登场之初,就可以吸引到诸多大厂的关注,自此一炮而红,名震江湖。

 

Kubernetes 的架构


Kubernetes 借鉴了 Borg 的整体架构思想,主要由 Master 和 Node 共同组成。

我们需要注意 Master 和 Node 两个概念。其中 Master 是控制节点,部署着 Kubernetes 的控制面,负责整个集群的管理和控制。Node 为计算节点,或者叫作工作负载节点,每个 Node 上都会运行一些负载容器。

跟 Borg 一样,为了保证高可用,我们也需要部署多个 Master 实例。根据我的生产实践经验,最好为这些 Master 节点选择一些性能好且规格大的物理机或者虚拟机,毕竟控制面堪称 Kubernetes 集群的大脑,要尽力避免这些实例宕机导致集群故障。

同样在 Kubernetes 集群中也采用了分布式存储系统 Etcd,用于保存集群中的所有对象以及状态信息。有的时候,我们会将 Etcd 集群也一起部署到 Master 上。但是在集群节点资源足够的情况下,我个人建议可以考虑将 Etcd 集群单独部署,因为Etcd中的数据可是至关重要的,必须要保证 Etcd 数据的安全。Etcd 采用 Raft 协议实现,和 Borg 中基于 Paxos 的存储系统不太一样。关于 Raft 和 Paxos 这两个协议的差异对比,我们在这里就不展开讲了,你可以通过《Paxos 和 Raft 的前世今生》这篇文章了解一二。

 

 

 

Kubernetes 的组件(Master)


Kubernetes 的控制面包含着 kube-apiserver、kube-scheduler、kube-controller-manager 这三大组件,我们也称为 Kubernetes 的三大件。下面我们逐一来讲一下它们的功能及作用。

首先来看 kube-apiserver

  • 它是整个 Kubernetes 集群的“灵魂”,是信息的汇聚中枢,提供了所有内部和外部的 API 请求操作的唯一入口。
  • 同时也负责整个集群的认证、授权、访问控制、服务发现等能力。
  • 用户可以通过命令行工具 kubectl 和 APIServer 进行交互,从而实现对集群中进行各种资源的增删改查等操作。
  • APIServer 跟 BorgMaster 非常类似,会将所有的改动持久到 Etcd 中,同时也保存着一份内存拷贝。

这也是为什么我们希望 Master 节点可以性能好、资源规格大,尤其是当集群规模很大的时候,APIServer 的吞吐量以及占用的 CPU 和内存都要很大。APIServer 还提供很多可扩展的能力,方便增强自己的功能。

再来看Kube-Controller-Manager,它负责维护整个 Kubernetes 集群的状态,比如多副本创建、滚动更新等。Kube-controller-manager 并不是一个单一组件,内部包含了一组资源控制器,在启动的时候,会通过 goroutine 拉起多个资源控制器。这些控制器的逻辑仅依赖于当前状态,因为在分布式系统中没办法保证全局状态的同步。

同时在实现的时候避免使用过于复杂的状态机,因此每个控制器仅仅对自己对应的资源对象做操作。而且控制器做了很多容错处理,比如增加 retry 机制等。

最后来看Kube-scheduler,它的工作简单来说就是监听未调度的 Pod,按照预定的调度策略绑定到满足条件的节点上。这个工作虽说看起来是三大件中最简单的,但是做的事情可一点不少。

这个调度器是 Kubernetes 的默认调度器,可插拔,你可以根据需要使用其他的调度器,或者通过目前调度器的扩展功能增加自己的特性进去。

 

Kubernetes 的组件(Slave)


了解完了控制面组件,我们再来看看 Node 节点。一般来说 Node 节点上会运行以下组件。

容器运行时主要负责容器的镜像管理以及容器创建及运行。大家都知道的 Docker 就是很常用的容器,此外还有 Kata、Frakti等。只要符合 CRI(Container Runtime Interface,容器运行时接口)规范的运行时,都可以在 Kubernetes 中使用。

Kubelet 负责维护 Pod 的生命周期,比如创建和删除 Pod 对应的容器。同时也负责存储和网络的管理。一般会配合 CSI、CNI 插件一起工作。

Kube-Proxy 主要负责 Kubernetes 内部的服务通信,在主机上维护网络规则并提供转发及负载均衡能力。

除了上述这些核心组件外,通常我们还会在 Kubernetes 集群中部署一些 Add-on 组件,常见的有:

  • CoreDNS 负责为整个集群提供 DNS 服务;
  • Ingress Controller 为服务提供外网接入能力;
  • Dashboard 提供 GUI 可视化界面;
  • Fluentd + Elasticsearch 为集群提供日志采集、存储与查询等能力。

 

Master 和 Node 的交互方式


在这一点上,Kubernetes 和 Borg 完全相反。Kubernetes 中所有的状态都是采用上报的方式实现的。APIServer 不会主动跟 Kubelet 建立请求链接,所有的容器状态汇报都是由 Kubelet 主动向 APIServer 发起的。 

当集群资源不足的时候,可以按需增加Node 节点。一旦启动 Kubelet 进程以后,它会主动向 APIServer 注册自己,这是 Kubernetes 推荐的 Node 管理方式。当然你也可以在Kubelet 启动参数中去掉自动注册的功能,不过一般都是默认开启这个模式的。 

一旦新增的 Node 被 APIServer 纳管进来后,Kubelet 进程就会定时向 APIServer 汇报“心跳”,即汇报自身的状态,包括自身健康状态、负载数据统计等。当一段时间内心跳包没有更新,那么此时 kube-controller-manager 就会将其标记为NodeLost(失联)。这也是 Kubernetes 跟 Borg 有区别的一个地方。 

Kubernetes 中各个组件都是以 APIServer 为中心,通过松耦合的方式进行。借助声明式 API,各部件通过 watch 的机制就可以根据各个对象的变化,很快地做出相应的处理操作。(声明方式API:打个比方,你现在想吃鱼。声明式API 就是给服务员下单,我想要盘酸菜鱼,就OK了,其他不用操心,静静等待上桌即可。那命令式API就是自己去follow所有的流程,从买鱼,杀鱼,片鱼,清洗,下锅等等流程。套用比较火的台词,声明式API就是“我不管你怎么想,我就要这个”,命令式API就是“我不管你怎么想,照我说的做”。)

 

总结


虽说 Kubernetes 跟 Borg 系统有不少差异,但是总体架构还是相似的。从Kubernetes的架构以及各组件的工作模式可以看到,Kubernetes 系统在设计的时候很注重容错性和可扩展性。

它假定有发生任何错误的可能,通过 backoff retry、多副本、滚动升级等机制,增强集群的容错性,提高 Kubernetes 系统的稳定性。同时对各个组件增加可扩展能力,保证 Kubernetes 对新功能的接入能力,让人们可以对 Kubernetes 进行个性化定制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值