3 8
深入学习Kubernetes(二):基础组件与概念

Kubernetes 是Google开源的一种基于容器的开源服务编排解决方案(orchestration system),它提供的是一种比Fleet更加高度抽象的调度和管理模式,对使用者屏蔽服务部署底层的细节信息,但它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,它来帮助你的系统达到和维持在这个状态。从这个角度上说,可以将Kubernetes看作是一个平台既服务(Platform as a Service,PaaS)工具。Kubernetes构建于容器之上,使用Go语言开发,为应用提供资源调度、部署运行、服务发现、扩容缩容等一套功能。

官网介绍:《What is Kubernetes》

dk

Kubernetes为我们解决哪方面问题

根本上说,Kubernetes能让处于物理机或虚拟机上的应用容器提供调度与运行管理。对于运行在生产上的应用,它主要带来如下好处:

使用Kubernetes就是在全面拥抱微服务架构。微服务架构的核心是将一个巨大的单体应用分解为很多小的互相连接的微服务,一个微服务背后可能有多个实例副本在支撑,副本的数量可能会随着系统的负荷变化而进行调整,内嵌的负载均衡器在这里发挥了重要作用。微服务架构使得每个服务都可以由专门的开发团队来开发,开发者可以自由选择开发技术,这对于大规模团队来说很有价值,另外每个微服务独立开发、升级、扩展,因此系统具备很高的稳定性和快速迭代进化能力。

然后,我们的系统可以随时随地整体“搬迁”到公有云上。Kubernetes初的目标就是运行在谷歌自家的公有云GCE中,未来会支持更多的公有云及基于OpenStack的私有云。同时,在Kubernetes的架构方案中,底层网络的细节完全被屏蔽,基于服务的ClusterIP甚至都无须我们改变运行期的配置文件,就能将系统从物理机环境中无缝迁移到公有云中,或者在服务高峰期将部分服务对应的Pod副本放入公有云中以提升系统的吞吐量,不仅节省了公司的硬件投入,还大大改善了客户体验。

最后,Kubernetes系统架构具备了超强的横向扩容能力。一个Kubernetes集群即可从只包含几个Node的小集群平滑扩展到拥有上百个Node的大规模集群,我们利用Kubernetes提供的工具,甚至可以在线完成集群扩容。只要我们的微服务设计得好,结合硬件或者公有云资源的线性增加,系统就能够承受大量用户并发访问所带来的巨大压力。

集群架构

关于Kubernetes集群,官方是这样宣传的:

“Kubernetes coordinates a highly available cluster of computers that are connected to work as a single unit. ”

Kubernetes由两种节点组成:Master节点和Minion节点,前者是集群的管理节点,后者是容器运行的工作节点。

我们若有计划想去了解Kubernetes集群的工作流程,先要熟悉它的组织架构,下面是官方的架构图:

ka

  • APIServer:其中Master节点有一个重要的组件叫APIServer,负责响应用户的管理请求,进行指挥调度工作,任何对资源进行增删改查的操作都会交给APIServer处理后才提交给Etcd。

  • Scheduler:作用是根据特定的调度算法(round robin)将Pod(后文会介绍)调度到指定的Minion上。这一过程在项目文档里也叫绑定。

  • Controller Manager:运行在集群的Master节点上,是基于pod API上的一个独立服务,它重点实现了service Endpoint(服务端点)的动态更新,管理着Kubernetes集群中的各种控制器,包括下文会提到的replication controller和Node Controller。相比之下,APIServer负责接受用户的请求并创建出对应的资源,而Controller Manager则在系统中扮演的角色是在一旁默默地管控这些资源,确保它们永远保持在预期的状态。

  • Kubelet:也是运行在Kubernetes集群的工作节点的重要组件,负责管理和维护在这台机上运行着的所有容器,说白了就是一个针对运行容器的Agent。

  • Kube-proxy:即支持Http,也支持TCP和UDP连接,默认情况下提供Round Robin算法将客户端流量负载到Service对应的一组后端Pod的组件。在服务发现上,Kube-proxy使用etcd的watch机制监控集群Service和Endpoint对象的数据动态变化,并且维护一个从Service到Endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。

抽象概念

Master

Kubernetes里的Master指的是集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都是发给它,它来负责具体的执行过程,我们后面所有的执行命令基本都是在Master上运行的,它就是整个集群的“首脑”。

Master节点上运行着以下的一组进程

  • Kubernetes API Server,提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增删改查等操作的唯一入口,也是集群控制的入口进行。

  • Kubernetes Controller Manager,Kubernetes里所有资源对象的自动化控制中心,也可以理解为资源对象的“大总管”。

  • Kubernetes Scheduler,负责资源调度(Pod调度)的进程。

其实Master节点上还启动了一个Etcd Server进程,因为Kubernetes里的所有资源对象全部是保存在etcd中的。

Node

除了Master,Kubernetes集群中的其它机器被称为Node节点,是Kubernetes集群中的工作负载节点,每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,其上的工作负载会被Master自动转移到其它节点上。

每个Node节点上都运行着以下的一组关键进程:

  • Kubelet:负责Pod对应的容器的创建,启动等任务,同时与Master节点密切协作。

  • Kube-peoxy:实现Kubernetes Service的通信与负载均衡机制的重要组件。

  • Docker Engine:负责本机的容器创建和管理工作。

Pod

在Kubernetes中,能够被创建、调度和管理的最小部署单元是Pod,而非单个容器。

Pod里的容器是共享网络和存储的。

Pod是为了解决“如何合理使用容器支撑企业级复杂应用”这个问题而诞生的。一旦某个pod被分配到指定的工作节点上,那么这个pod就会在这个工作节点上一直运行到生命周期结束,中途不会被调度到其他节点上再次运行。

Pod与其他组件关系示意图如下:

kp

Label

Label是Kubernetes系统中的另外一个核心概念,一个Label是一个key=label的键值对,其中key与value由用户指定。Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上。

Label通常在资源定义时确定,也可以在对象创建后动态添加或者删除。

K8s使用Label的目的是:面向用户,使之成为用户级别的Kubernetes对象标识属性,因为label应该要包含对象的功能性和特战描述的特性。这样比UUID更加用户友好和更有意义。

label selector是Kubernetes的核心的分组机制

目前,Kubernetes支持两类资源使用label selector来监控和管理它们的pod资源 --- services和replication controller (RC)

Replication Controller

Replication Controller(简称 RC)是Kubernetes系统中的核心概念之一,决定了一个pod有多少个同时运行的副本。简单来说,它其实是定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个期望值,所以RC的定义包括如下的几个部分。

所以,只要创建了一个pod,一般都推荐同时给pod创建一个replacation controller,让这个rc一直守护pod,直到pod删除
  • Pod期待的副本数(replicas)

  • 用于筛选目标Podde Label Selector。

  • 当Pod的副本数量小于预期数量的时候,用于创建新的Pod模板

要注意的是,删除RC并不会影响通过该RC已经创建好的Pod。为了删除所有的Pod,可以设置replicas的值为0,然后更新该RC。另外,kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod。

RC 对pod数量和监控情况的控制是通过replica selector, label selector 的一种来实现的。

replica selector定义了RC和它所控制的pod之间的一种松耦合关系。这种松耦合关系可以通过修改pod的label将一个pod从replication controller的控制集中移除。比如可以把出现故障的pod从工作集群中移除,然后对pod进行debug。

Deployment

Deployment是Kubernetes1.2引入的新概念,引入的目的是为了更好解决Pod的编排问题。

Deployment相对于RC的一个最大升级是我们可以随时知道当前Pod“部署”的进度。

Deployment的典型使用场景有以下几个:

  • 创建一个Deployment对象生成对应的Replica Set并完成Pod副本的创建过程

  • 检查Deployment的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)

  • 更新Deployment以创建新的Pod(比如镜像升级)

  • 如果当前Deployment不稳定,则回滚到一个早先的Deployment版本

  • 挂起或者恢复一个Deployment

Service

Service相当于我们微服务架构中的一个“微服务”。

Service这个概念存在的意义在于pod在Kubernetes中的IP地址不是固定的,因此需要一个代理来确保需要使用pod的应用不需要知晓pod的真实IP地址。另外一个原因是当使用rc创建了多个pod副本时,需要一个代理为这些pod做负载均衡。

设计原则:任何一个kube-proxy都能将流量正确导向任何一个被代理的pod,而这个kube-proxy不需要和被代理的pod在同一个宿主机上。

目前,kubernetes主要支持两种service的发现机制:环境变量和DNS。

总结

上述这些组件是Kubernetes系统的核心组件,它们共同构成了Kubernetes系统的框架和计算模型,通过对它们进行灵活组合,用户就可以快速、方便地对容器集群进行配置、创建和管理。

如果不特别指明Namespace, 用户创建的pod、rc、service都讲被系统创建到这个默认的名为default的Namespace中。