2. kubernetes集群部署篇

kubernetes的master节点和node节点

Master

kubernetes集群中的master节点是集群的控制节点, 负责整个集群的管理和控制。执行的控制命令都是发送给master节点。 Master节点上运行的主要组件如下:

  • kube-apiserver apiserver提供了资源操作的唯一入口, 并提供认证、授权、访问控制、API组册和发现机制

  • Kube-controller-manager Controller Manager作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。

  • kube-scheduler 资源调度负责决定将Pod调度到合适的node上

Node

Node节点时kubernetes集群中的工作负责节点,Node上的工作负载由master分配, 当某个Node宕机时,Master会将上面的工作负载转移到其他节点上去, Node节点上运行的主要组件如下:

  • kubelet 负责pod的创建、启动、监控、重启、销毁等工作, 同时也负责Volume(CVI)和网络(CNI)的管理

  • kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡;

  • container runtime负责镜像管理以及Pod和容器的真正运行(CRI);

节点通信

上图为kubernetes中所有组件一起工作时的示意图,由此我们可以得出以下几个通信流程,

  • 集群到master节点

    所有组件都要要和apiserver交互, 其他的master组件不对外暴漏服务都仅和apiserver进行通信

  • apiserver到kubelet

    apiserver到kubelet的连接用于获取pod的日志, 使用kubectl连接运行中的pods, 以及kubelet的端口转发功能

  • apiserver到node、pods and services

    从apiserver到节点,pod或服务的连接默认为纯HTTP连接,因此既未经过身份验证也未加密。它们可以通过前缀https:到 API URL中的节点。

根据上面节点通信的介绍我们会产生一个疑问, 这个看起来好复杂的样子。 臣妾看不懂呀。 如果想进一步了解集群中详细的工作流程请移驾 kubectl创建pod背后发生了什么探索背后的秘密

集群高可用实现策略

要求结果为所有的Kubernetes Master服务器没有单点故障,任何一台服务器当机均不影响Kubernetes的正常工作。

为了实现没有单点故障的目标,需要为以下几个组件建立高可用方案:

  • etcd

  • kube-apiserver

  • kube-controller-manager与kube-scheduler

  • kube-dns

etcd高可用

etcd是Kubernetes当中唯一带状态的服务,也是高可用的难点。Kubernetes选用etcd作为它的后端数据存储仓库正是看重了其使用分布式架构,没有单点故障的特性。

虽然单节点的etcd也可以正常运行。但是推荐的部署方案均是采用3个或者5个节点组成etcd集群,供Kubernetes使用。

etcd的高可用基本有三种思路:

一是使用独立的etcd集群,使用3台或者5台服务器只运行etcd,独立维护和升级。甚至可以使用CoreOS的update-enginelocksmith,让服务器完全自主的完成升级。这个etcd集群将作为基石用于构建整个集群。 采用这项策略的主要动机是etcd集群的节点增减都需要显式的通知集群,保证etcd集群节点稳定可以更方便的用程序完成集群滚动升级,减轻维护负担。

二是在Kubernetes Master上用static pod的形式来运行etcd,并将多台Kubernetes Master上的etcd组成集群。 在这一模式下,各个服务器的etcd实例被注册进了Kubernetes当中,虽然无法直接使用kubectl来管理这部分实例,但是监控以及日志搜集组件均可正常工作。在这一模式运行下的etcd可管理性更强。

三是使用CoreOS提出的self-hosted etcd方案,将本应在底层为Kubernetes提供服务的etcd运行在Kubernetes之上。 实现Kubernetes对自身依赖组件的管理。在这一模式下的etcd集群可以直接使用etcd-operator来自动化运维,最符合Kubernetes的使用习惯。

这三种思路均可以实现etcd高可用的目标,但是在选择过程中却要根据实际情况做出一些判断。简单来讲预算充足但保守的项目选方案一, 想一步到位并愿意承担一定风险的项目选方案三。折中一点选方案二。各个方案的优劣以及做选择过程中的取舍在这里就不详细展开了,对这块有疑问的朋友可以私下联系交流。

kube-apiserver高可用

apiserver本身是一个无状态服务,要实现其高可用相对要容易一些,难点在于如何将运行在多台服务器上的apiserver用一个统一的外部入口暴露给所有Node节点。

说是难点,其实对于这种无状态服务的高可用,我们在设计业务系统的高可用方案时已经有了相当多的经验积累。需要注意的是apiserver所使用的SSL证书要包含外部入口的地址,不然Node节点无法正常访问apiserver。

apiserver的高可用也有三种基本思路:

一是使用外部负载均衡器,不管是使用公有云提供的负载均衡器服务或是在私有云中使用LVS或者HaProxy自建负载均衡器都可以归到这一类。 负载均衡器是非常成熟的方案,在这里略过不做过多介绍。如何保证负载均衡器的高可用,则是选择这一方案需要考虑的新问题。

二是在网络层做负载均衡。比如在Master节点上用BGPECMP,或者在Node节点上用iptables做NAT都可以实现。采用这一方案不需要额外的外部服务,但是对网络配置有一定的要求。

三是在Node节点上使用反向代理对多个Master做负载均衡。这一方案同样不需要依赖外部的组件,但是当Master节点有增减时,如何动态配置Node节点上的负载均衡器成为了另外一个需要解决的问题。

从目前各个集群管理工具的选择来看,这三种模式都有被使用,目前还没有明确的推荐方案产生。建议在公有云上的集群多考虑第一种模式,在私有云环境中由于维护额外的负载均衡器也是一项负担,建议考虑第二种或是第三种方案。

kube-controller-manager与kube-scheduler高可用

这两项服务是Master节点的一部分,他们的高可用相对容易,仅需要运行多份实例即可。这些实例会通过向apiserver中的Endpoint加锁的方式来进行leader election, 当目前拿到leader的实例无法正常工作时,别的实例会拿到锁,变为新的leader。

Kube-dns高可用

严格来说kube-dns并不算是Master组件的一部分,因为它是可以跑在Node节点上,并用Service向集群内部提供服务的。但在实际环境中, 由于默认配置只运行了一份kube-dns实例,在其升级或是所在节点当机时,会出现集群内部dns服务不可用的情况,严重时会影响到线上服务的正常运行。

为了避免故障,请将kube-dns的replicas值设为2或者更多,并用anti-affinity将他们部署在不同的Node节点上。这项操作比较容易被疏忽,直到出现故障时才发现原来是kube-dns只运行了一份实例导致的故障。

总结

上面介绍了Kubernetes Master各个组件高可用可以采用的策略。其中etcd和kube-apiserver的高可用是整个方案的重点。由于存在多种高可用方案,集群管理员应当根据集群所处环境以及其他限制条件选择适合的方案。

这种没有绝对的通用方案,需要集群建设者根据不同的现状在多个方案中做选择的情况在Kubernetes集群建设过程中频频出现, 也是整个建设过程中最有挑战的一部分。容器网络方案的选型作为Kubernetes建设过程中需要面对的另外一个大问题也属于这种情况,今后有机会再来分享这个话题。

在实际建设过程中,在完成了上述四个组件的高可用之后,最好采取实际关机检验的方式来验证高可用方案的可靠性,并根据检验的结果不断调整和优化整个方案。

此外将高可用方案与系统自动化升级方案结合在一起考虑,实现高可用下的系统自动升级,将大大减轻集群的日常运维负担,值得投入精力去研究。

虽然本篇主要在讲Kubernetes Master高可用的方案,但需要指出的是,高可用也并不是必须的,为了实现高可用所付出的代价并不低, 需要有相应的收益来平衡。对于大量的小规模集群来说,业务系统并没有实现高可用,贸然去做集群的高可用收益有限。这时采用单Master节点的方案,做好etcd的数据备份,不失为理性的选择。

最后更新于