01-mesos分布式集群入门¶
Mesos简介¶
如果要评价2015年最火的技术,那么非Docker莫属,当你开始使用并部署上Docker之后,那么你会发现想真正用起来,缺少很多组件。比如本文要介绍的分布式集群管理就是其中之一。 本文为实战分享,所以相关理论较少,需要大家自行Google。 Mesos:Mesos采用与Linux Kernel相同的机制,只是运行在不同的抽象层次上。Mesos Kernel利用资源管理和调度的API在整个数据中心或云环境中运行和提供引用(例如,Hadoop、Spark、Kafaka、ElasticSearch)。 ZooKeeper:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和HBase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。 Marathon:Marathon是一个Mesos框架,能够支持运行长服务,比如Web应用等。它是集群的分布式Init.d,能够原样运行任何Linux二进制发布版本,如Tomcat、Play等等。它也是一种私有的PaSS,实现服务的发现,为部署提供提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡。 好的,架构图看起来像这样。 [attach]8[/attach] 下面我们就准备开始实战部署了。首先要说明下实验环境: [attach]14[/attach] Zookeeper伪集群部署 在部署mesos集群之前,我们必须先部署一个可用的zookeeper集群,后面mesos会连接到zookeeper上。
Mesos+Zookeeper+Marathon+Docker分布式集群管理
如果要评价2015年最火的技术,那么非Docker莫属,当你开始使用并部署上Docker之后,那么你会发现想真正用起来,缺少很多组件。比如本文要介绍的分布式集群管理就是其中之
Mesos:Mesos采用与Linux Kernel相同的机制,只是运行在不同的抽象层次上。Mesos Kernel利用资源管理和调度的API在整个数据中心或云环境中运行和提供引用(例如,Hadoop、Spark、Kafaka、ElasticSearch)。
ZooKeeper:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和HBase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
Marathon:Marathon是一个Mesos框架,能够支持运行长服务,比如Web应用等。它是集群的分布式Init.d,能够原样运行任何Linux二进制发布版本,如Tomcat、Play等等。它也是一种私有的PaSS,实现服务的发现,为部署提供提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡。
好的,架构图看起来像这样。
Mesos是Apache下的开源分布式资源管理框架,它被称为分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发,后在Twitter得到广泛使用。
Mesos-Master:主要负责管理各个framework和slave,并将slave上的资源分配给各个framework。
Mesos-Slave:负责管理本节点上的各个mesos-task,比如:为各个executor分配资源。
Framework:计算框架,如:Hadoop、Spark、Kafaka、ElasticSerach等,通过MesosSchedulerDiver接入Mesos
Executor:执行器,就是安装到每个机器节点的软件,这里就是利用docker的容器来担任执行器的角色。具有启动销毁快,隔离性高,环境一致等特点。
Mesos-Master是整个系统的核心,负责管理接入Mesos的各个framework(由frameworks_manager管理)和slave(由slaves_manager管理),并将slave上的资源按照某种策略分配给framework(由独立插拔模块Allocator管理)。
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解决该问题。
Framework是指外部的计算框架,如果Hadoop、Mesos等,这些计算框架可通过注册的方式接入Mesos,以便Mesos进行统一管理和资源分配。Mesos要求可接入的框架必须有一个调度模块,该调度器负责框架内部的任务调度。当一个framework想要接入Mesos时,需要修改自己的调度器,以便向Mesos注册,并获取Mesos分配给自己的资源,这样再由自己的调度器将这些资源分配给框架中的任务,也就是说,整个Mesos系统采用了双层调度框架:第一层,由Mesos将资源分配给框架。第二层,框架自己的调度器将资源分配给自己内部的任务。当前Mesos支持三中语言编写的调度器,分别是C++、Java、Python。为了向各种调度器提供统一的接入方式,Mesos内部采用C++实现了一个MesosSchedulerDriver(调度驱动器),framework的调度器可调用该driver中的接口与Mesos-master交互,完成一系列功能(如注册,资源分配等。)
Executor主要用于启动框架内部的task。由于不同的框架,启动task的接口或者方式不同,当一个新的框架要接入mesos时,需要编写一个Executor,告诉Mesos如何启动该框架中的task。为了向各种框架提供统一的执行器编写方式,Mesos内部采用C++实现了一个MesosExecutorDiver(执行器驱动器),framework可通过该驱动器的相关接口告诉Mesos启动task的方式。
整体架构如图1.1-1所示
图1.1-1展示了Mesos的重要组成部分,Mesos由一个master进程管理运行着每个客户端节点的slave进程和跑任务的Mesos计算框架。
Mesos进程通过计算框架可以很细致的管理cpu和内存等,从而提供资源。每个资源提供都包含了一个清单(slave ID,resource1:amount1,resource2,amount2,…)master会根据现有的资源决定提供每个计算框架多少资源。例如公平分享或者根据优先级分享。
为了支持不同种的政策,master通过插件机制新增额一个allocation模块使之分配资源更简单方便。
一个计算框架运行在两个组建之上,一个是Scheduler,他是master提供资源的注册中心,另一个是Executor程序,用来发起在slave节点上运行计算框架的任务。master决定给每个计算框架提供多少计算资源,计算框架的调度去选择使用哪种资源。当一个计算框架接受了提供的资源,他会通过Mesos的任务描述运行程序。Mesos也会在相应的slave上发起任务。
资源提供案例,如图1.1-2所示
下面我带大家一起熟悉图1.1-2的流程步骤
1、slave1报告给master他拥有4核cpu和4G剩余内存,Marathon调用allocation政策模块,告诉slave1计算框架1应该被提供可用的资源。
2、master给计算框架1发送一个在slave上可用的资源描述。
3、计算框架的调度器回复给master运行在slave上两个任务相关信息,任务1需要使用2个CPU,内存1G,任务2需使用1个CPU,2G内存。
4、最后,master发送任务给slave,分配适当的给计算框架执行器,继续发起两个任务(图1.1-2虚线处),因为任有1个CPU和1G内存未分配,allocation模块现在或许提供剩下的资源给计算框架2。
除此之外,当任务完成,新的资源成为空闲时,这个资源提供程序将会重复。
Zookeeper简介¶
Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chuby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
Zookeeper角色¶
Leader(领导者):负责投票发起和决议,更新系统状态。
follower(跟随者):Follower用于接收客户请求并向客户端返回结果,在选主过程中参与投票。
ObServer(观察者):ObServer可以接受客户端连接,将写请求转发给Leader节点,但ObServer不参加投票过程,只同步Leader的状态,ObServer的目的是为了拓展系统,提高读取速度。
Client(客户端):请求发起方。
Zookeeper工作原理¶
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和Leader的状态同步以后,回复模式就结束了。状态同步保证了Leader和Server具有相同的系统状态。
为了保证事物的顺序一致性,Zookeeper采用了递增的事物ID号(zxid)来标识事物。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识Leader关系是否改变,每次一个Leader被选出来,它都会有每一个Server在工作过程中三中状态。
LOOKING:当前Server不知道Leader是谁,正在搜寻。
LEADING:当前Server即为选举出来的Leader。
FOLLOWING:Leader已经选举出来,当前Server与之同步。
Zookeeper选举流程¶
当Leader崩溃或者Leader失去大多数的Follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的Leader,让所有的Server都恢复到一个正确的状态。ZK的选举算法有两种:
1、基于Basic paxos实现
2、基于fast paxos算法实现
系统默认的选举算法为fast paxos。
Zookeeper同步流程¶
选完Leader以后,zk就进入状态同步过程。
1)Leader等待server连接。
2)Follower连接Leader,将最大的zxid发送给Leader。
3)Leader根据Follower的zxid确定同步点。
4)完成同步后通知Follower已经成为uptodate状态。
5)Follower收到uptodate消息后,又可以重新接受client的请求进行服务。
Zookeeper工作流程¶
*Leader三大功能:*
1)恢复数据
2)维持与learner的心跳,接收learner请求并判断learner的请求消息类型
3)learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
*Follower主要四大功能:*
1)向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息)。
2)接收Leader消息并进行处理。
3)接收Client的请求,如果为写请求,发送给Leader进行投票。
4)返回Client结果。
Follower的消息循环处理如下几种来自Leader的消息:
1)PING消息:心跳消息。
2)PROPOSAL消息:Leader发起的提案,要求Follower投票。
3)COMMIT消息:服务器端最新一次提案的信息。
4)UPTODATE消息:表明同步完成。
5)REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息。
6)SYN消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
Marathon简介¶
Marathon是一个Mesos框架,能够支持运行长服务,比如Web应用等。它是集群的分布式init.d能够原样运行任何Linux二进制发布版本,如Tomcat、Play等等。它也是一种私有的PaSS,实现服务的发现,为部署提供REST API服务,有授权和SSL、配置约束,通过HaProxy实现服务发现和负载平衡。
准备环境¶
主机名称 | IP地址 | 描述 |
---|---|---|
192e168e56e11 | eth0:192.168.56.11 | zookeeper,mesos master, mesos slave, marathon |
192e168e56e12 | eth0:192.168.56.12 | mesos slave |
备注 | zookeeper使用为伪分布式部署,也就是在一台虚拟机上启动三个不同端口的zookeeper实例 |
zookeeper伪集群部署¶
在部署mesos集群之前,我们必须先部署一个可用的zookeeper集群,后面mesos会连接到zookeeper上。
[root@192e168e56e11 ~]# cd /usr/local/src/
[root@192e168e56e11 src]# rz zookeeper-3.4.6.tar.gz
[root@192e168e56e11 src]# tar xf zookeeper-3.4.6.tar.gz
[root@192e168e56e11 src]# mv zookeeper-3.4.6 /usr/local/zookeeper
[root@192e168e56e11 src]# ln -s /usr/local/zookeeper-3.4.6/ /usr/local/zookeeper
[root@192e168e56e11 src]# cd /usr/local/zookeeper/conf/
[root@192e168e56e11 conf]# mv zoo_sample.cfg zoo.cfg
zookeeper配置文件详解
下面就是zoo.cfg配置文件的修改了。那么我们首先要熟悉下zookeeper配置文件。
[root@192e168e56e11 conf]# cat /usr/local/zookeeper/conf/zoo.cfg
dataDir:数据目录
dataLogDir:日志目录
clientPort:客户端连接端口
tickTime:Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
initLimit:Zookeeper的Leader 接受客户端(Follower)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 5个心跳的时间(也就是tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
syncLimit:表示 Leader 与 Follower 之间发送消息时请求和应答时间长度,最长不能超过多少个tickTime 的时间长度,总的时间长度就是 2*2000=4 秒。
server.A=B:C:D:
A 是一个数字,表示这个是第几号服务器;
B 是这个服务器的 ip 地址;
C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;
D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
*Zookeeper配置文件修改*
如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
[root@192e168e56e11 conf]# > zoo.cfg
[root@192e168e56e11 conf]# vim zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zk1
clientPort=2181
server.1=192.168.56.11:3181:4181
server.2=192.168.56.11:3182:4182
server.3=192.168.56.11:3183:4183
创建三个目录用来存放zookeeper数据
mkdir -p /data/zk1 /data/zk2 /data/zk3
echo "1" >/data/zk1/myid
echo "2" >/data/zk2/myid
echo "3" >/data/zk3/myid
生成三份zookeeper配置文件
cp zoo.cfg zk1.cfg
cp zoo.cfg zk2.cfg
cp zoo.cfg zk3.cfg
修改zk2和zk3的配置,使用对应的数据目录和端口。
sed -i 's/zk1/zk2/g' zk2.cfg
sed -i 's/2181/2182/g' zk2.cfg
sed -i 's/zk1/zk3/g' zk3.cfg
sed -i 's/2181/2183/g' zk3.cfg
启动Zookeeper
/usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk1.cfg
/usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk2.cfg
/usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk3.cfg
查看Zookeeper角色
[root@192e168e56e11 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk1.cfg
JMX enabled by default
Using config: /usr/local/zookeeper/conf/zk1.cfg
Mode: follower
[root@192e168e56e11 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk2.cfg
JMX enabled by default
Using config: /usr/local/zookeeper/conf/zk2.cfg
Mode: leader
[root@192e168e56e11 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk3.cfg
JMX enabled by default
Using config: /usr/local/zookeeper/conf/zk3.cfg
Mode: follower
连接Zookeeper测试
[root@192e168e56e11 ~]# /usr/local/zookeeper/bin/zkCli.sh -server 192.168.56.11:2181
WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.56.11:2181(CONNECTED) 0]
提示:通过上面的例子可以看到,目前zk3是leader,其它两个节点是follower。本文由于实验环境局限使用的是伪分布式,注意生产环境不建议使用。
Mesos 集群部署¶
*安装mesosphere仓库*
需要在Mesos Master和MesosSlave节点均安装:
rpm -Uvh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
提示:此方法是通过yum源的方式安装,由于的国外的yum源,安装速度会很慢,请耐心等待
*Mesos Master部署*
[root@192e168e56e11 ~]# yum -y install mesos marathon
安装完毕后,增加zookeeper配置
[root@192e168e56e11 ~]# cat /etc/mesos/zk
zk://192.168.56.11:2181,192.168.56.11:2182,192.168.56.11:2183/mesos
[root@192e168e56e11 ~]# systemctl start mesos-master mesos-slave
[root@192e168e56e11 ~]# systemctl start marathon
*Mesos Slave部署*
[root@192e168e56e12 ~]# cat /etc/mesos/zk
zk://192.168.56.11:2181,192.168.56.11:2182,192.168.56.11:2183/mesos
[root@192e168e56e12 ~]# systemctl start mesos-slave
*Mesos的Web管理界面*
Mesos安装完毕后,Mesos Master会启动一个Web服务,监听在5050端口。
http://${HOST_IP}:5050
这时候你将得到一个像这样的页面但可能在‘Tasks’表格没有任何的条目
下面我们来运行第一mesos任务,注意刷新查看Mesos的Web界面,你会在Active Tasks看到我们测试的任务。
[root@192e168e56e11 ~]# MASTER=$(mesos-resolve `cat /etc/mesos/zk`)
[root@192e168e56e11 ~]# mesos-execute --master=$MASTER --name="cluster-test" --command="sleep 60"
刷新页面查看任务如下:
docker安装部署¶
所有节点安装docker并配置docker源
(1)安装docker软件
[root@docker ~]#yum install -y docker
#安装docker(CentOS7系统CentOS-Extras库中已带Docker)
(2)配置镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://1v0q5mvy.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
(3)启动docker 加入开机自启动
[root@docker ~]#systemctl start docker && systemctl enable docker
(4)下载docker nginx的镜像
docker pull nginx
提示:这里一定要保证所有的节点都要有镜像
Marathon安装部署¶
使用Marathon调用Mesos 运行Docker容器
再所有mesos-slave上增加配置参数,并重启
[root@192e168e56e11 ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers
docker,mesos
[root@192e168e56e11 ~]# systemctl restart mesos-slave
[root@192e168e56e12 ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers
docker,mesos
[root@192e168e56e12 ~]# systemctl restart mesos-slave
接下来,我们要使用我们marathon来创建一个nginx的Docker容器,通过Mesos进行调度。 我们上面安装mesos-master的时候,已经安装了marathon。默认监听在8080端口,通过使用http://{HOST}:8080/来打开marathon。如下图所示:
我相信读者会有疑问,我们并没有对marathon做任何的配置,它是怎么知道Mesos在哪里的呢?答案是通过zookeeper,marathon启动的时候会读取/etc/mesos/zk配置文件,通过Zookeeper来找到Mesos Master。marathon有自己的REST API,我们通过API的方式来创建一个nginx的docker容器:
首先创建如下的配置文件nginx.json:
[root@192e168e56e11 ~]# cat nginx.json
{
"id":"nginx",
"cpus":0.2,
"mem":20.0,
"instances": 1,
"constraints": [["hostname", "UNIQUE",""]],
"container": {
"type":"DOCKER",
"docker": {
"image": "nginx",
"network": "BRIDGE",
"portMappings": [
{"containerPort": 80, "hostPort": 0,"servicePort": 0, "protocol": "tcp" }
]
}
}
}
然后调用
curl -X POST http://192.168.56.11:8080/v2/apps -d @/root/nginx.json -H "Content-type: application/json"
现在你就可以通过31984来访问到nginx了。当然了,你也可以在mesos-slave上来寻找一下这个容器:
如果你想创建同样的容器,可以点击上图中德Scale Application来体验一下。同样的,你也可以通过marathon的Web界面来进行容器的创建、扩展和销毁。