docker集群——介绍Mesos+Zookeeper+Marathon的Docker管理平台

容器为用户打开了一扇通往新世界的大门,真正进入这个容器的世界后,却发现新的生态系统如此庞大。在生产使用中,不论个人还是企业,都会提出更复杂的需求。这时,我们需要众多跨主机的容器协同工作,需要支持各种类型的工作负载,企业级应用开发更是需要基于容器技术,实现支持多人协作的持续集成、持续交付平台。即使Docker只需一条命令便可启动一个容器,一旦试图将其推广到软件开发和生产环境中,麻烦便层出不穷,容器相关的网络、存储、集群、高可用等就是不得不面对的问题。从容器到容器云的进化应运而来。

什么是容器云?

容器云以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员提供用于构建、发布和运行分布式应用的平台。当容器云专注于资源共享与隔离、容器编排与部署时,它是一种IaaS;当容器云渗透到应用支撑与运行时环境时,它是一种PaaS。

一个软件项目的成功常常需要依托其衍生的生态系统,围绕或基于核心技术而构建的相关项目日臻丰富和完善,软件本身的功能和易用性也随之增加,Docker的迅猛发展与其强大的生态系统息息相关。

这里要介绍的就是在这个庞大的docker生态系统中的“编排/调度/监控”——zookeeper+Mesos+Marathon

Zookeeper介绍

Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。Zookeeper是hadoop的一个子项目,在分布式应用中,由于工程师不能很好地使用锁机制,以及基于消息的协调机制不适合在某些应用中使用,因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此。

角色

Zookeeper中的角色主要有以下三类:

系统模型如图所示:

设计目的

  1. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
  2. 可靠性:具有简单、健壮、良好的性能,如果消息被一台服务器接受,那么它将被所有的服务器接受。
  3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
  4. 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
  5. 原子性:更新只能成功或者失败,没有中间状态。
  6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

工作原理

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

每个Server在工作过程中有三种状态:

  • LOOKING:当前Server不知道leader是谁,正在搜寻
  • LEADING:当前Server即为选举出来的leader
  • FOLLOWING:leader已经选举出来,当前Server与之同步

选主流程

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举法为fast paxos。先介绍basic paxos流程:

  1. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2. 选举线程首先向所有Server发起一次询问(包括自己);
  3. 选举现成收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1. 每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。

选主的具体流程图所示:

fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。

其流程图如下所示:

同步流程

选完leader以后,zk就进入状态同步过程。

  1. leader等待server连接;
  2. Follower连接leader,将最大的zxid发送给leader;
  3. 完成同步后通知follower已经成为uptodate状态;
  4. Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

流程图如下所示:

工作流程

Leader工作流程

  Leader主要有三个功能:

    • 恢复数据;
    • 维持Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
    • Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。 

  PING消息是指Learner的心跳消息;

  REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;

  ACK消息是Follower的对象提议回复,超过半数的Follower通过,则commit该提议;

  REVALIDATE消息是用来延长SESSION有效时间。

  Leader的工作流程简图如下所示,在实际实现中,流程要比下图复杂得多,启动了三个线程来实现功能。

Follower工作流程

  Follower主要有四个功能:

    • 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDA消息);
    • 接受Leader消息并进行处理;
    • 接收Client的请求,如果为写请求,发送给Leader进行投票;
    • 返回Client结果。

  Follower的消息循环处理如下几种来自Leader的消息:

    • PING消息:心跳消息;
    • PROPOSAL消息:Leader发起的提案,要求Follower投票;
    • COMMIT消息:服务端最新一次提案的消息;
    • UPTODATE消息:表明同步完成;
    • REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
    • SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。

  Follower的工作流程简图如下,在实际实现中,Follower是通过5个线程来实现功能的。

 对于observer的流程不再叙述,observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。

Mesos介绍

Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos能够在同样的集群机器上运行多种分布式系统类型,更加动态有效率低共享资源。提供失败侦测,任务发布,任务跟踪,任务监控,低层次资源管理和细粒度的资源共享,可以扩展伸缩到数千个节点。Mesos已经被Twitter用来管理它们的数据中心。

Apache mesos中的基本术语解释

  • Mesos-master:Mesos master,主要负责管理各个framework和slave,并将slave上的资源分配给各个framework
  • Mesos-slave:Mesos slave,负责管理本节点上的各个mesos-task,比如:为各个executor分配资源
  • Framework:计算框架,如Hadoop,Spark等,通过MesosSchedulerDiver接入Mesos
  • Executor:执行器,安装到mesos-slave上,用于启动计算框架中的task。

当用户试图添加一种新的计算框架到Mesos中时,需要实现一个Framework sheduler和executor以接入Mesos。

  1. Mesos-master是这个系统的核心,负责管理接入Mesos的各个framework(由frameworks_manager管理)和slave(slaves_manager管理),并将slave上的资源按照某种策略分配给framework(有独立插拔模块Allocator管理)。
  2. Mesos-slave负责接收并执行来自mesos-master的命令、管理节点上的mesos-task,并为各个task分配资源。mesos-slave将自己的资源量发送给mesos-master,由mesos-master中的Allocator模块决定将资源分配给哪个framework,当前考虑的资源有CPU和内存两种,也就是说,mesos-slave会将CPU个数和内存量发送给mesos-master,而用户提交作业时,需要制定每个任务需要的CPU个数和内存量,这样,当任务运行时,mesos-slave会将任务放到包含固定资源的linux container中运行,以达到资源隔离的效果。很明显,master存在单点故障的问题,为此,mesos采用了zookeeper解决该问题。
  3. Framework是指外部的计算框架,如Hadoop,Mesos等,这些计算框架可通过注册的方式接入mesos,以便mesos进行统一管理和资源分配。Mesos要求可接入的框架必须有一个调度器模块,该调度器负责框架内部的任务调度。当一个framework想要接入mesos时,需要修改自己的调度器,以便向mesos注册,并获取mesos分配给自己的资源,这样再由自己的调度器将这些资源分配给框架中的任务,也就是说,整个mesos系统采用了双层调度框架:第一层,由mesos将资源分配给框架;第二层,框架自己的调度器将资源分配给自己内部的任务。当前Mesos支持三种语言编写的调度器,分别是C++,Java和python,为了向各种调度器提供统一的接入方式,Mesos内部采用C++实现一个MesosScheduleDriver(调度器驱动),framework的调度器可调用该driver中的接口与Mesos-master交互,完成一系列功能(如注册,资源分配等)。
  4. Executor主要用于启动框架内部的task。由于不同的框架,启动task的接口或者方式不同,当一个新的框架要接入mesos时,需要编写一个executor,告诉mesos如何启动该框架中的task。为了向各种框架提供统一的执行器编写方式,Mesos内部采用C++实现了一个MesosExecutorDiver(执行器驱动器),framework可通过该驱动器的相关接口告诉mesos启动task的方法。

Mesos基础架构

首先Mesos是一个Master / Agent的架构方式,其中:

  1. Master负责资源的统一管理跟任务的分发;
  2. Agent负责起停执行器,汇报主机资源、执行器状态等信息;
  3. 一般情况下,会启动3个以上Master,以确保高可用,Master的状态由Zookeeper维护;
  4. Framerwork是Mesos上的调度框架,Marathon Hadoop Chonous都是比较常见的任务调度框架。

这样的架构给人的整体感受就清晰明朗。另外:

  1. 每台机器上都会部署一个Mesos-Agent,Agent会把信息汇报给Master。
  2. 调度器scheduler向Mesos-Master请求资源,Mesos-Master把所有可用的资源都反馈给Scheduler,Scheduler根据自己的规则决定该部署到哪一台。

Mesos总体架构

上图展示了Mesos的重要组成部分:

1)mesoso由一个master进程管理运行着每个客户端节点的salve进程和跑任务的mesos计算框架。master进程通过计算框架可以很细致的管理cpu和内存等,从而提供资源。每个资源提供与包含了一个清单(slave ID, resource1: amount1, resource2, amount2, …),master会根据现有的政府决定提供每个计算框架多少资源,例如公平分享或者根据优先级分享。 为了支持不同种的政策,master通过插件机制新增了一个allocation模块使之分配资源更简单方便。   

2)一个计算框架运行在两个组件之上,一个是scheduler,他是master提供资源的注册中心,另一个是executor程序,用来发起在slave节点上运行计算框架的任务。master决定给每个计算框架提供多少计算资源,计算框架的的调度去选择使用哪个资源。当一个计算框架接受了提供的资源,他会通过mesos的任务描述运行程序,mesos也会在相应的slave上发起任务。

从上面图中可以看到,Mesos有Framework(Framework里面有Scheduler), Master(Master里面有Allocator)、Agent、Executor、Task几部分组成。

这里面有两层的Scheduler,一层在Master里面,Allocator会将资源公平的分给每一个Framework,二层在Framework里面,Framework的Scheduler将资源按规则分配给Task。

Mesos的这几个角色在一个任务运行的生命周期中,相互关系如下:

Agent会将资源汇报给Master,Master会根据Allocator的策略将资源offer给Framework的Scheduler。Scheduler 可以accept这个资源,运行一个Task,Master将Task交给Agent,Agent交给Executor去真正的运行这个Task。

Mesos资源提供的例子:

简单梳理一下上图的流程步骤:

  1. slave 1 报告给master他拥有4核cpu和4G剩余内存,matser调用allocation政策模块,告诉salve 1 计算框架1应该被提供可用的资源。
  2. master给计算框架1发送一个在slave1上可用的资源描述。
  3. 计算框架的调度器回复给master运行在slave上两个任务的相关信息,任务1需使用2个cpu,内存1G,任务2需使用1个cpu,2G内存。
  4. 最后,master发送任务给slave,分配适当的给计算框架执行器,继续发起两个任务(图上虚线处),因为仍有1个cpu和1G内存未分配,allocation模块现在或许提供剩下的资源给计算框架2。
  5. 除此之外,当任务完成,新的资源成为空闲时,这个资源提供程序将会重复。

Mesos框架式一个在Mesos上运行分布式应用的应用程序,它有两个组件:

  • 调度器:与Mesos交互,订阅资源,然后在mesos从服务器中加载任务。
  • 执行器:从框架的环境变量配置中获得信息,在mesos从服务器中运行任务。

下面看看其是如何实现资源调用?Mesos通过“resources offers”分配资源,资源其实是当前可用资源的一个快照,调度器使用这些资源在mesos从服务器上运行任务。

Mesos主从服务器调度资源的顺序如下图:

首先由Mesos主服务器查询可用资源给调度器,第二步调度器向主服务器发出加载任务,主服务器再传达给从服务器,从服务器向执行器命令加载任务执行,执行器执行任务以后,将状态反馈上报给从服务器,最终告知调度器 。
从服务器下管理多个执行器,每个执行器是一个容器,以前可以使用Linux容器LXC,现在使用Docker容器。

Mesos失败恢复和高可用性

  • Mesos主服务器使用Zookeeper进行服务选举和发现。它有一个注册器记录了所有运行任何和从服务器信息,使用MultiPaxos进行日志复制实现一致性。
  • Mesos有一个从服务器恢复机制,无论什么时候一个从服务器死机了,用户的任务还是能够继续运行,从服务器会将一些关键点信息如任务信息状态更新持久化到本地磁盘上,重新启动时可以从磁盘上恢复运行这些任务(类似Java中的钝化和唤醒)

Marathon介绍

Marathon是一个成熟的,轻量级的,扩展性很强的Apache Mesos的容器编排框架,它主要用来调度和运行常驻服务(long-running service),提供了友好的界面和Rest API来创建和管理应用。marathon是一个mesos框架,能够支持运行长服务,比如web应用等,它是集群的分布式Init.d,能够原样运行任何Linux二进制发布版本,如Tomcat Play等等,可以集群的多进程管理。也是一种私有的Pass,实现服务的发现,为部署提供提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡。

这样,我们可以如同一台Linux主机一样管理数千台服务器,它们的对应原理如下图,使用Marathon类似Linux主机内的init Systemd等外壳管理,而Mesos则不只包含一个Linux核,可以调度数千台服务器的Linux核,实际是一个数据中心的内核:

Marathon中重要的概念介绍:

  • Application是Marathon中一个重要的核心概念,它代表了一个长服务。
  • Application definition表示一个长服务的定义,规定了一个Application启动和运行时的所有行为。Marathon提供了两种方式让你来定义你的长服务,第一种通过Portal来定义,它方便终端用户的理解和使用,另一种是通过JSON格式的文件来定义,并通过RestAPI的方式来创建和管理这个Application,这种方式方便和第三方的系统进行集成,提供了再次的可编程接口。 
  • Application instance表示一个Application的实例,也称作Mesos的一个task。Marathon可以为一个Application创建和管理多个实例,并可以动态的增大和减小某个Application实例的个数,并且通过Marathon-lb实现服务发现和负载均衡。 
  • Application Group:Marathon可以把多个Application组织成一棵树的结构,Group称为这个树的树枝,Application称为这个树的叶子。同一个Group中的Application可以被Marathon统一管理。
  • Deployments:对Application或者Group的definition的一次修改的提交称为一次deployment。它包括创建,销毁,扩容缩容Application或者Group等。多个deployments可以同时进行,但是对于一个应用的deployments必须是串行的,如果前一个deployment没有结束就执行下一个deployment,那么它将会被拒绝。
原文地址:https://www.cnblogs.com/Bourbon-tian/p/7155054.html