基本概念

基本架构

Mesos用于管理分布式集群,简单来讲就是隐藏底层硬件设施细节,让开发人员能够将一个集群当成一台高性能计算机。 Mesos将所有资源汇集到一个资源池来避免静态划分以提高资源利用率。

Mesos架构分为如下几个部分:master、slave、框架、通信、附属服务。

  1. master负责给不同框架分配资源并管理任务的生命周期,资源以offer为单位,每个offer属于一个slave,一个slave可以提供多个offer。
  2. slave负责执行框架下发的任务,以及对任务的隔离。还需要保证不多不少的给予承诺的资源。 slave资源是指master管理的资源,即运行任务会消耗的元素; slave属性是指slave的相关信息,它们不会被任务消耗,如操作系统、软件版本等。 --resources--attributes分别用于表示资源和属性。
  3. 框架运行在Mesos之上,因此需要向Mesos注册。框架用于发起任务请求,任务会消耗资源并最终在slave上执行。框架由两部分组成,调度器负责协调任务执行,执行器启动任务。
  4. Mesos利用libprocess来异步通信,下列API用到了通信机制:
    • 调度器API,调度器和master通信
    • 执行器API,执行器和slave通信
    • 内部API,master和slave通信
    • 运维API,同步通信,主要为运维人员准备
  5. 附属服务包括:
    • 共享文件系统:通过共享文件系统实现统一资源视图,如HDFS、NFS等
    • 一致性服务:故障恢复依赖于一致性服务,如ZooKeeper、etcd等
    • 服务编排(service fabric):包括多框架上的服务相互发现和连接,框架和用户相互连接等
    • 运维服务:Mesos部署、升级、监控、报警、日志和安全等

安装部署

编译安装-Ubuntu

编译安装不是很环保,建议直接用二进制安装。

安装依赖:

sudo apt-get install tar wget git
sudo apt-get install openjdk-7-jdk
sudo apt-get install autoconf libtool
sudo apt-get install build-essential python-dev libcurl4-nss-dev \
     libsasl2-dev libsasl2-modules maven libapr1-dev libsvn-dev

配置JAVA_HOME

# file: /etc/evironment or .profile
export JAVA_HOME=/usr/lib/jvm/default-java
PATH="$JAVA_HOME/bin:$PATH"

下载mesos:http://mesos.apache.org/downloads/

wget http://mirror.bit.edu.cn/apache/mesos/1.0.0/mesos-1.0.0.tar.gz
./bootstrap                             # Only required if from git repository
mkdir build
cd build
../configure
make
make check                              # Run test suite
make install

构建完成后在build/bin目录下有一系列命令可用,直接以root权限运行mesos-local.sh即可启动本地集群,然后通过 http://127.0.1.1:5050/ 就能访问集群服务。

启动master:

sudo mkdir /var/lib/mesos
sudo chown `whoami` /var/lib/mesos/
mesos-master --work_dir=/var/lib/mesos

启动slave

mesos-slave --work_dir=/var/lib/mesos --master=127.0.1.1:5050

测试框架在build/src下有三个版本,可以分别尝试如下命令运行:

./test-framework --master=127.0.1.1:5050 # C++ framework, build/src
./test-framework 127.0.1.1:5050          # build/src/java, build/src/python

二进制安装-CentOS

yum install mesos-1.0.0-2.0.89.centos65.x86_64.rpm

注意mesos-1.0需要在CentOS6.5以上的版本运行,否则会出现如下错误提示:

warning: mesos-1.0.0-2.0.89.centos65.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID e56151bf: NOKEY
error: Failed dependencies:
      subversion is needed by mesos-1.0.0-2.0.89.centos65.x86_64
      cyrus-sasl-md5 is needed by mesos-1.0.0-2.0.89.centos65.x86_64
      libevent2-devel is needed by mesos-1.0.0-2.0.89.centos65.x86_64

这种情况可以从网上下载安装如下文件来解决依赖问题。

serf-1.3.7-1.x86_64.rpm
subversion-1.8.16-3.x86_64.rpm
libevent2-2.0.21-2.el6.x86_64.rpm
libevent2-devel-2.0.21-2.el6.x86_64.rpm

如果安装过程遇到如下错误提示,可以直接删除提示的文件或目录再重试:

error: unpacking of archive failed on file xxx: cpio: rename

多节点部署

以下操作都在master所在主机上执行:

ssh-keygen -f ~/.ssh/mesos -P ""
ssh-copy-id -i ~/.ssh/mesos.pub USER@SLAVE1
ssh-copy-id -i ~/.ssh/mesos.pub USER@SLAVE2
scp -R build slave1:PREFIX
scp -R build slave2:PREFIX
edit PREFIX/var/mesos/deploy/masters
edit PREFIX/var/mesos/deploy/slaves
mesos-start-cluster.sh

常见问题

Failed to create directory '/sys/fs/cgroup/freezer'

# mesos-slave --work_dir=/var/lib/mesos --master=10.23.10.20:5050
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0812 13:30:33.992420  2107 main.cpp:243] Build: 2016-07-27 20:33:59 by root
I0812 13:30:33.992513  2107 main.cpp:244] Version: 1.0.0
I0812 13:30:33.992521  2107 main.cpp:247] Git tag: 1.0.0
I0812 13:30:33.992527  2107 main.cpp:251] Git SHA: c9b70582e9fccab8f6863b0bd3a812b5969a8c24
I0812 13:30:33.997602  2107 containerizer.cpp:196] Using isolation: posix/cpu,posix/mem,filesystem/posix,network/cni
Failed to create a containerizer: Could not create MesosContainerizer: Failed to create launcher: Failed to create Linux launcher: Failed to mount cgroups hierarchy at '/sys/fs/cgroup/freezer': Failed to create directory '/sys/fs/cgroup/freezer': No such file or directory

在CentOS6.5上遇到此问题,解决办法:

yum install libcgroup
/etc/init.d/cgconfig status             # show Stopped
/etc/init.d/cgconfig start

Failed to obtain the IP address for 'xxx'

# mesos-slave --work_dir=/var/lib/mesos --master=masterip:5050
WARNING: Logging before InitGoogleLogging() is written to STDERR
I0812 14:42:33.579213  8441 main.cpp:243] Build: 2016-07-27 20:33:59 by root
I0812 14:42:33.579406  8441 main.cpp:244] Version: 1.0.0
I0812 14:42:33.579406  8441 main.cpp:247] Git tag: 1.0.0
I0812 14:42:33.579406  8441 main.cpp:251] Git SHA: c9b70582e9fccab8f6863b0bd3a812b5969a8c24
Failed to obtain the IP address for 'xxx'; the DNS service may not be able to resolve it: Temporary failure in name resolution

在CentOS6.5上遇到此问题,解决办法:添加hostname即可,无需重启网络,立即生效。

# edit /etc/hosts
x.x.x.x a-hostname

内部机制

通信机制

Mesos四个组件master、slave、scheduler和executor采用actor model通信,协议用protobuf,基于libprocess库实现。每个模块都是一个服务,监听其他模块的消息。计算框架想接入Mesos只需要写Scheduler和Executor即可。

线路1:master分配资源,提供给framework scheduler,scheduler将资源分配给任务,返回任务给master、master转发给slave。

线路2:scheduler可以将任务直接发送给slave。

线路3:slave负责管理framework executor并分配资源

注册所有消息处理函数的文件分别在:master.cpp、slave.cpp、sched.cpp、exec.cpp。通过如下命令就能找出所有注册函数。

git grep install\<.*\>

资源分配

Mesos在各个框架之间进行粗粒度资源分配,框架内部需要实现细粒度任务调度。 Mesos这种调度模式称为双层调度,调度器并不知道全局资源利用率,因此难以实现最优资源分配。

Mesos框架事件典型流程:

  1. 框架调度器在master注册
  2. master从slave获取offer,分配模块决定给哪个框架
  3. 框架调度器从master接收资源
  4. 框架调度器接受资源,向master返回执行器列表;框架也可以拒绝资源
  5. slave分配资源并运行执行器
  6. 框架调度器接收任务运行状态
  7. 框架调度器从master注销,该操作对于持久服务是不必要的

资源预留

静态预留通过--resources指定,要改变静态预留需要删除slave的所有检查点,并重启slave。

动态预留能够将offer预留下来,以后只能分配给同一框架。框架在接受资源时发送Offer::Operations::ReserveOffer::Operations::Unreserve 来管理预留资源。

资源隔离

资源隔离简单来讲是通过接口分层来实现的,隔离机制都是在slave上实现。 slave进程调用容器机API,容器机调用隔离器API,隔离器就是容器,容器运行在slave操作系统之上,操作系统之下即为硬件资源。

容器机API目的用于支持多种容器机,因此可以提供自己的容器机和隔离器。

docker容器机

DockerContainerizer用于将任务或执行器启动销毁翻译成docker CLI,使用docker容器机典型步骤:

  1. 执行器将CommandInfo中指定文件放入沙箱
  2. 执行docker pull获取镜像
  3. 利用DockerExecutor运行docker镜像,将沙箱目录映射到容器并设置MESOS.SANDBOX为目录映射
  4. 将docker运行日志输出到沙箱stdout/stderr文件
  5. 在容器机退出时,停止并删除所有docker容器

准备工作:

  • 在slave上安装docker CLI
  • --containerizers指定docker
  • containerInfo.DockerInfo.image指定镜像
  • .dockercfg文件包含登录私有仓库信息

容错机制

slave宕机或升级,master会向框架发送slave宕机事件,当slave修复时,会重新向master注册。

master宕机会由选主来保证master高可用性,选主后slave和框架会重新注册。 Mesos只支持ZooKeeper选主服务。

配置文件zoo.cfg基本配置项:

tickTime=2000                           # ZK之间或ZK和客户端心跳间隔
dataDir=/tmp/zookeeper                  # 数据目录,如日志
clientPort=2181                         # 客户端连接ZK的端口
initLimit=5                             # slave初始化上限心跳数
syncLimit=2                             # master和slave应答上限心跳数
# A 服务器编号
# B 服务器IP
# C 服务器与master通信端口
# D 选举端口
server.A=B:C:D