Mesos-优秀的集群资源调度平台
- 15.1 Mesos简介
- 15.2 Mesos安装与使用
- 1. 安装
- 1. 源码编译
- 2. 软件源安装
- 3. Docker方式安装
- 2. 配置说明
- 1. ZooKeepr
- 2. Mesos
- 3. Marathon
- 3.访问Mesos图形界面
- 4.访问Marathon图形界面
- 1. 通过界面方式
- 2. REST API方式
- 15.3 原理与架构
- 1. 架构
- 2. 基本单元
- 3. 调度
- 4. 高可用性
What is Mesos? A distributed systems kernel
Mesos is built using the same principles as the Linux kernel, only at a different level of abstraction. The Mesos
kernel runs on every machine and provides applications (e.g., Hadoop, Spark, Kafka, Elasticsearch) with API’s for
resource management and scheduling across entire datacenter and cloud environments.
mesos
15.1 Mesos简介
Mesos最初由UCBerkeley的AMP实验室于2009年发起,遵循Apache协议,目前已经成立了Mesosphere公司进行运营。
Mesos可以将整个数据中心的资源(包括CPU、内存、存储、网络等)进行抽象和调度,使得多个应用同时运行在集群中分享资源,并无须关心资源的物理分布情况。
如果把数据中心中的集群资源看做一台服务器,那么Mesos要做的事情,其实就是今天操作系统内核的职责:抽象资源+调度任务。
Mesos拥有许多引人注目的特性,包括:
- 支持数万个节点的大规模场景(Apple、Twitter、eBay等公司使用);
- 支持多种应用框架,包括Marathon、Singularity、Aurora等;
- 支持HA(基于ZooKeeper实现);
- 支持Docker、LXC等容器机制进行任务隔离;
- 提供了多个流行语言的API,包括Python、Java、C++等;
- 自带了简洁易用的WebUI,方便用户直接进行操作。
值得注意的是,Mesos自身只是一个资源抽象的平台,要使用它往往需要结合运行其上的分布式应用(在Mesos中称为框架,framework)
比如Hadoop、Spark等可以进行分布式计算的大数据处理应用;
比如Marathon可以实现PaaS,快速部署应用并自动保持运行;
比如ElasticSearch可以索引海量数据,提供灵活的整合和查询能力…
大部分时候,用户只需跟这些框架打交道即可,完全无须关心底层的资源调度情况,因为Mesos已经自动帮你实现了。这大大方便了上层应用的开发和运维。
当然,用户也可以基于Mesos打造自己的分布式应用框架。
15.2 Mesos安装与使用
以Mesos结合Marathon应用框架为例,来看一下如何快速搭建一套Mesos平台。
Marathon是可以与Mesos一起协作的一个框架,基于Scala实现,可以实现保持应用的持续运行。
另外,Mesos默认利用ZooKeeper来进行多个主节点之间的选举,以及从节点发现主节点的过程。一般在生产环境中,需要启动多个Mesos master服务(推荐3或5个),并且推荐使用Supervisord等进程管理器来自动保持服务的运行。
ZooKeeper是一个分布式集群中信息同步的工具,通过自动在多个节点中选举leader,保障多个节点之间的某些信息保持一致性。
1. 安装
安装主要需要Mesos、ZooKeeper和Marathon三个软件包。
Mesos也采用了经典的“主-从”结构,一般包括若干主节点和大量从节点。其中,Mesos master服务和ZooKeeper需要部署到所有的主节点,Mesos slave服务需要部署到所有从节点。Marathon可以部署到主节点。
安装可以通过源码编译、软件源或者Docker镜像方式进行,下面分别进行介绍。
1. 源码编译
源码编译方式可以保障获取到最新版本,但编译过程比较费时间。
首先,从apache.erg开源网站下载最新的源码:
git clone https://git-wip-us.apache.org/repos/asf/mesos.git
其中,主要代码在src目录下,应用框架代码在frameworks目录下,文档在docs目录下,include中包括了跟Mesos打交道使用的一些API定义头文件。
安装依赖主要包括Java运行环境、Linux上的自动编译环境等:
apt-get update
apt-get install -y openjdk-8-jdk autoconf libtool \
build-essential python-dev python-boto libcurl4-nss-dev \
libsasl2-dev maven libaprl-dev libsvn dev
后面就是常规C++项目的方法,配置之后利用Makefile进行编译和安装:
cd mesas
./bootstrap
mkdir build
cd build && ../configure --with-network-isolator
make
make check && sudo make install
2. 软件源安装
通过软件源方式进行安装相对会省时间,但往往不是最新版本。这里以Ubuntu系统为例,首先添加软件源地址:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF
DISTRO=$(lsb_release -is | tr '[ :upper: ]' '[ :lower: ]')
CODENAME=$(lsb_release -cs)
echo "deb http://repos.mesosphere.io/${DISTRO} ${CODENAME} main" |\
sudo tee /etc/apt/sources.list.d/mesosphere.list
刷新本地软件仓库信息并安装ZooKeeper、Mesos、Marathon三个软件包:
apt-get - y update && sudo apt-get -y install zookeeper mesos marathon
注意,Marathon最新版本需要jdk1.8+的支持。如果系统中有多个Java版本,需要检查配置默认的JDK版本是否符合要求:
update-alternatives --config java
安装Mesos成功后,会在/usr/sbin/下面发现mesas-master和mesas-slave两个二进制文件,分别对应主节点上需要运行的管理服务和从节点上需要运行的任务服务。用户可以手动运行二进制文件启动服务,也可以通过service命令来方便进行管理。例如,在主节点上重启Mesos管理服务:
service mesos-master restart
通过service命令来管理,实际上是通过调用/usr/bin/mesos-init-wrapper 脚本文件进行处理。
3. Docker方式安装
需要如下三个镜像:
ZooKeeper: https://registry.hub.docker.com/u/garland/zookeeper/
Mesos: https://registry.hub.docker.com/u/garland/mesosphere-docker-mesos-master/
Marathon: https://registry.hub.docker.com/u/garland/mesosphere-docker-marathon/
其中mesas-master镜像在后面将分别作为master和slave角色进行使用。首先,拉取三个镜像:
[root@dbc-server-554 spark_cluster]# docker pull garland/zookeeper
Using default tag: latest
latest: Pulling from garland/zookeeper
I...
Digest: sha256:52e3be393804c650c33f6c0e7e45bc383cacedb45e3c869387eacbeb632238e5
Status: Downloaded newer image for garland/zookeeper:latest
docker.io/garland/zookeeper:latest
[root@k8s-node-02 local]# docker pull garland/mesosphere-docker-marathon
[root@localhost ~]# docker pull garland/mesosphere-docker-mesos-master
在各节点机,导出主节点机器的地址到环境变量:
[root@dbc-server-554 spark_cluster]# export HOST_IP=192.168.5.54
[root@dbc-server-554 spark_cluster]# env
...
HOST_IP=192.168.5.54
...
在主节点上启动ZooKeepr容器:
docker run -d -p 2181:2181 -p 2888:2888 -p 3888:3888 garland/zookeeper
在主节点上启动Mesos Master服务容器:
[root@dbc-server-554 mesos]# docker run --net="host" -p 5050:5050 -e "MESOS_HOSTNAME=${HOST_IP}" -e "MESOS_IP=${HOST_IP}" -e "MESOS_ZK=zk://${HOST_IP}:2181/mesos" -e "MESOS_PORT=5050" -e "MESOS_LOG_DIR=/var/log/mesos" -e "MESOS_QUORUM=1" -e "MESOS_REGISTRY=in_memory" -e "MESOS_WORK_DIR=/var/lib/mesos" -d garland/mesosphere-docker-mesos-master
在主节点上启动Marathon:
[root@dbc-server-554 mesos]# docker run -d -p 8080:8080 garland/mesosphere-docker-marathon --master zk://${HOST_IP}:2181/mesos --zk zk://${HOST_IP}:2181/marathon
[root@dbc-server-554 compose]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f5c823dd175 garland/mesosphere-docker-marathon "/opt/marathon/bin/s…" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp vibrant_jang
54ad7482e96f garland/mesosphere-docker-mesos-master "mesos-master" About a minute ago Up About a minute crazy_moore
5fe561ba37a2 garland/zookeeper "/opt/run.sh" 3 minutes ago Up 3 minutes 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 0.0.0.0:2888->2888/tcp, :::2888->2888/tcp, 0.0.0.0:3888->3888/tcp, :::3888->3888/tcp heuristic_kilby
在从节点上启动Mesos slave容器:
[root@localhost ~]# docker run -d --name mesos_slave_1 --entrypoint="mesos-slave" -e "MESOS_MASTER=zk://${HOST_IP}:2181/mesos" -e "MESOS_LOG_DIR=/var/log/mesos" -e "MESOS_LOGGING_LEVEL=INFO" garland/mesosphere-docker-mesos-master:latest
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89e1dcde16da garland/mesosphere-docker-mesos-master:latest "mesos-slave" 2 seconds ago Up 2 seconds mesos_slave_1
2. 配置说明
下面以本地通过软件源方式
安装为例,解释如何修改各个配置文件。
1. ZooKeepr
ZooKeepr 是一个分布式应用的协调工具,用来管理多个主节点的选举和冗余,监听在 2181 端口。推荐至少布置三个主节点来被 ZooKeeper 维护。
配置文件默认都在 /etc/zookeeper/conf/ 目录下。比较关键的配置文件有两个:myid 和 zoo.cfg。
myid 文件会记录加入 ZooKeeper 集群的节点的序号(1-255之间)。/var/lib/zookeeper/myid 文件其实也是软连接到了该文件。
比如配置某节点序号为 1,则需要在该节点上执行:
$ echo 1 | sudo dd of=/etc/zookeeper/conf/myid
节点序号在 ZooKeeper 集群中必须唯一,不能出现多个拥有相同序号的节点。
另外,需要修改 zoo.cfg 文件,该文件是主配置文件,主要需要添加上加入 ZooKeeper 集群的机器的序号和对应监听地址。
例如,现在 ZooKeeper 集群中有三个节点,地址分别为 10.0.0.2、10.0.0.3、10.0.0.4,序号分别配置为 2、3、4。
则配置如下的三行:
server.2=10.0.0.2:2888:3888
server.3=10.0.0.3:2888:3888
server.4=10.0.0.4:2888:3888
其中第一个端口 2888 负责从节点连接到主节点的;第二个端口 3888 则负责主节点进行选举时候通信。
也可以用主机名形式,则需要各个节点 /etc/hosts 文件中都记录地址到主机名对应的映射关系。
完成配置后,启动 ZooKeeper 服务。
$ sudo service zookeeper start
2. Mesos
Mesos 的默认配置目录有三个:
/etc/mesos/:主节点和从节点都会读取的配置文件,最关键的是 zk 文件存放主节点的信息;
/etc/mesos-master/:只有主节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项;
/etc/mesos-slave/:只有从节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项。
最关键的是需要在所有节点上修改 /etc/mesos/zk,写入主节点集群的 ZooKeeper 地址列表,例如:
zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos
此外,/etc/default/mesos、/etc/default/mesos-master、/etc/default/mesos-slave 这三个文件中可以存放一些环境变量定义,Mesos 服务启动之前,会将这些环境变量导入进来作为启动参数。格式为 MESOS_OPTION_NAME
。
下面分别说明在主节点和从节点上的配置。
- 主节点
一般只需要关注 /etc/mesos-master/ 目录下的文件。默认情况下目录下为空。
该目录下文件命名和内容需要跟 mesos-master 支持的命令行选项一一对应。可以通过 mesos-master --help 命令查看支持的选项。
例如某个文件 key 中内容为 value,则在 mesos-master 服务启动的时候,会自动添加参数 --key=value 给二进制命令。
例如,mesos-master 服务默认监听在 loopback 端口,即 127.0.0.1:5050,我们需要修改主节点监听的地址,则可以创建 /etc/mesos-master/ip 文件,在其中写入主节点监听的外部地址。
为了正常启动 mesos-master 服务,还需要指定 work_dir 参数(表示应用框架的工作目录)的值,可以通过创建 /etc/mesos-master/work_dir 文件,在其中写入目录,例如 /var/lib/mesos。工作目录下会生成一个 replicated_log 目录,会存有各种同步状态的持久化信息。以及指定 quorum 参数的值,该参数用来表示 ZooKeeper 集群中要求最少参加表决的节点数目。一般设置为比 ZooKeeper 集群中节点个数的半数多一些(比如三个节点的话,可以配置为 2)。
此外,要修改 Mesos 集群的名称,可以创建 /etc/mesos-master/cluster 文件,在其中写入集群的别名,例如 MesosCluster。
总结下,建议在 /etc/mesos-master 目录下,配置至少四个参数文件:ip、quorum、work_dir、cluster。
修改配置之后,需要启动服务即可生效。
$ sudo service mesos-master start
主节点服务启动后,则可以在从节点上启动 mesos-slave 服务来加入主节点的管理。
- 从节点
一般只需要关注 /etc/mesos-slave/ 目录下的文件。默认情况下目录下为空。
文件命名和内容也是跟主节点类似,对应二进制文件支持的命令行参数。
建议在从节点上,创建/etc/mesos-slave/ip
文件,在其中写入跟主节点通信的地址。
修改配置之后,也需要重新启动服务。
$ sudo service mesos-slave start
3. Marathon
Marathon 作为 Mesos 的一个应用框架,配置要更为简单,必需的配置项有 --master
和 --zk
。
安装完成后,会在 /usr/bin 下多一个 marathon shell 脚本,为启动 marathon 时候执行的命令。
配置目录为 /etc/marathon/conf(需要手动创建),此外默认配置文件在 /etc/default/marathon。
我们手动创建配置目录,并添加配置项(文件命名和内容跟 Mesos 风格一致),让 Marathon 能连接到已创建的 Mesos 集群中。
$ sudo mkdir -p /etc/marathon/conf
$ sudo cp /etc/mesos/zk /etc/marathon/conf/master
同时,让 Marathon 也将自身的状态信息保存到 ZooKeeper 中。创建 /etc/marathon/conf/zk 文件,添加 ZooKeeper 地址和路径。
zk://10.0.0.2:2181,10.0.0.2:2181,10.0.0.2:2181/marathon
启动 marathon 服务。
$ sudo service marathon start
3.访问Mesos图形界面
Mesos自带了Web图形界面,可以方便用户查看集群状态。用户在Mesos主节点服务和从节点服务都启动后,可以通过浏览器访问主节点5050端口,看到的界面如图所示,已经有两个slave节点加入了。
通过Slaves标签页能看到加入集群的从节点的信息。如果没有启动Marathon服务,在Frameworks标签页下将看不到任何内容。
4.访问Marathon图形界面
Marathon服务启动成功后,在Mesos的Web界面的Frameworks标签页下面将能看到名称为marathon的框架出现。同时可以通过浏览器访问8080端口,看到Marathon自己的管理界面,如图所示
此时,可以通过界面或者REST API来创建一个应用,Marathon会保持该应用的持续运行。
1. 通过界面方式
可以看到各任务支持的参数(包括资源、命令、环境变量、健康检查等,如图所示),同时可以很容易地修改任务运行实例数进行扩展,非常适合进行测试。
2. REST API方式
一般情况下,启动新任务需要先创建一个定义模板(json格式),然后发到指定的API。例如,示例任务basic1的定义模板为:
[root@dbc-server-554 compose]# cat basic1.json
{
"id": "basic1",
"cmd": "while true; do echo 'Hello marathon'; sleep 5; done",
"cpus": 0.1,
"mem": 10.0,
"instances": 1
}
该任务申请资源为0.1个单核CPU资源和10MB的内存资源,具体命令为每隔五秒钟用shell打印一句Hello Marathon。
可以通过如下命令发出basic1任务到Marathon框架,框架会分配任务到某个满足条件的从节点上,成功会返回一个json对象,描述任务的详细信息:
curl -X POST http://marathon_host:8080/v2/apps -d @basic1.json -H "Content-type: application/json"
null
由于从节点连接到zookeeper超时,笔者只得到null,正常应该得到json串
Marathon自由更多REST API可以参考本地自带的文档:http://marathon_host:8080/api-con-sole/index.html
。
此时,如果运行任务的从节点出现故障,任务会自动在其他可用的从节点上启动。此外,目前也已经支持基于Docker容器的任务。需要先在Mesos slave节点上为slave服务配置--containerizers=docker,mesos
参数。例如,下面的示例任务:
{
"idd":"basic-3",
"cmd": "python3 -m http.server 8080",
"cpus": 0.5,
"mem" : 32.0,
"container": {
"type": "DOCKER",
"volumes": [],
"docker": {
"image": "python:3",
"network": "BRIDGE",
"portMappings": [
{
"containerPort": 8080,
"hostPort": 31000,
"servicePort": 0,
"protocol": "tcp"
}
],
"privileged": false,
"parameters": [],
"forcePullimage": true
}
}
}
该任务启动一个python:3容器,执行python3 -m http.server 8080
命令,作为一个简单的Web服务,实际端口会映射到宿主机的31000端口
注意区分hostPort和servicePort,前者代表任务映射到的本地可用端口(可用范围由Mesosslave汇报,默认为31000~32000);后者作为服务管理的端口,可作为一些服务发行机制使用进行转发,在整个Marathon集群中是唯一的。
任务执行后,也可以在对应slave节点上通过Docker命令查看容器运行情况,容器将以mesos-SLAVE_ID开头
15.3 原理与架构
首先需要强调,Mesos自身只是一个资源调度框架,并非一整套完整的应用管理平台,所以只有Mesos自己是不能干活的。但是基于Mesos,可以比较容易地为各种应用管理框架或者中间件平台(作为Mesos的应用)提供分布式运行能力;同时多个框架也可以同时运行在一个Mesos集群中,提高整体的资源使用效率。
Mesos对自己定位范围的划分,使得它要完成的任务很明确,其他任务框架也可以很容易与它进行整合。
1. 架构
可以看出,Mesos采用了经典的“主 - 从”架构,其中主节点(管理节点)可以使用ZooKeeper来做HA。Mesos master服务将运行在主节点上,Mesos slave服务则需要运行在各个计算任务节点上。负责完成具体任务的应用框架,与Mesos master进行交互,来申请资源。
2. 基本单元
Mesos有三个基本的组件:管理服务(master)、任务服务(slave)以及应用框架(framework)。
- 管理服务 – master:跟大部分分布式系统中类似,主节点起到管理作用,将看到全局的信息,负责不同应用框架之间的资源调度和逻辑控制。应用框架需要注册到管理服务上才能被使用。用户和应用需要通过主节点提供的API来获取集群状态和操作集群资源。
- 任务服务 – slave:负责汇报本从节点上的资源状态(空闲资惊、运行状态等等)给主节点,并负责隔离本地资源来执行主节点分配的具体任务。隔离机制目前包括各种容器机制,包括LXC、Docker等。
- 应用框架 – framework:应用框架是实际干活的,包括两个主要组件:
调度器(scheduler):注册到主节点,等待分配资源;
执行器(executor):在从节点上执行框架指定的任务(框架也可以使用Mesos自带的执行器,包括shell脚本执行器和Docker执行器)。
应用框架可以分两种:一种是对资源的需求会扩展(比如Hadoop、Spark等),申请后还可能调整;另一种是对资源的需求将会固定(MPI等),一次申请即可。
3. 调度
对于一个资源调度框架来说,最核心的就是调度机制,怎么能快速高效地完成对某个应用框架资源的分配,是核心竞争力所在。最理想情况下(大部分时候都无法实现),最好是能猜到应用们的实际需求,实现最大化的资源使用率。
Mesos为了实现尽量优化的调度,采取了两层(two-layer)的调度算法
- 算法基本过程
调度的基本思路很简单,master先全局调度一大块资源给某个framework,framework自己再实现内部的细粒度调度,决定哪个任务用多少资源。两层调度简化了Mesos master自身的调度过程,通过将复杂的细粒度调度交由framework实现,避免了Mesos master成为性能瓶颈。
调度机制支持插件机制来实现不同的策略。默认是Dominant Resource Fairness (DRF,其核心思想是对不同类型资源的多个请求,计算请求的主资源类型,然后根据主资源进行公平分配) - 调度过程
调度通过offer发送的方式进行交互。一个offer是一组资源,例如<1 CPU, 2 GB Mem>。基本调度过程如下:
- slave节点会周期性汇报自己可用的资源给master;
- 某个时候,master收到应用框架发来的资源请求,根据调度策略,计算出来一个资源offer给framework;
- framework收到offer后可以决定要不要,如果接受的话,返回一个描述,说明自己希望如何使用和分配这些资源来运行某些任务(可以说明只希望使用部分资源,则多出来的会被master收回);
- master则根据framework答复的具体分配情况发送给slave,以使用framework的executor来按照分配的资源策略执行任务。
具体给出一个例子,某从节点向主节点汇报自己有<4 CPU, 8 GB Mem>的空闲资源,同时,主节点看到某个应用框架请求<3 CPU, 6 GB Mem>,就创建一个offer < slave#1,4 CPU, 8 GB Mem>把满足的资源发给应用框架。应用框架(的调度器)收到offer后觉得可以接受,就回复主节点,并告诉主节点希望运行两个任务:一个占用<1 CPU, 2 GB Mem>,一个占用<2 CPU, 4 GB Mem>。主节点收到任务信息后分配任务到从节点上进行运行(实际上是应用框架的执行器来负责执行任务)。任务运行结束后资源可以被释放出来。剩余的资源还可以继续分配给其他应用框架或任务。
应用框架在收到offer后,如果offer不满足自己的偏好(例如希望继续使用上次的slave节点),则可以选择拒绝offer,等待master发送新的offer过来。另外,可以通过过滤器机制来加快资源的分配过程。
- 过滤器
framework可以通过过滤器机制告诉master它的资源偏好比如希望分配过来的offer有哪个资源,或者至少有多少资源等。过滤器可以避免某些应用资源长期分配不到所需要的资源的情况,加速整个资源分配的交互过程。 - 回收机制
为了避免某些任务长期占用集群中资源,Mesos也支持回收机制。主节点可以定期回收计算节点上的任务所占用的资掘,可以动态调整长期任务和短期任务的分布。
4. 高可用性
从架构上看,最为核心的节点是master节点。除了使用ZooKeeper来解决单点失效问题之外,Mesos的master节点自身还提供了很高的鲁棒性。
Mesos master节点在重启后,可以动态通过slave和framework发来的消息重建内部状态,虽然可能导致一定的时延,但这避免了传统控制节点对数据库的依赖。
当然,为了减少master节点的负载过大,在集群中slave节点数目较多的时候,要避免把各种通知的周期配置得过短。实践中,可以通过部署多个Mesos集群来保持单个集群的规模不要过大。