文章索引:
3、docker系列基础课程--如何获取镜像、列出镜像和删除镜像
4、docker系列基础课程:利用commit 理解镜像构成
5、docker系列基础课程:使用 Dockerfile 定制镜像
6、docker系列基础课程:Dockerfile 指令详解(1)
7、docker系列基础课程:Dockerfile 指令详解(2)
8、docker系列基础课程:Dockerfile 指令详解(3)
14、docker中配置docker0网桥以及自定义网桥来连接各个容器
15、Docker容器集群快速编排工具Compose应用实践
16、Docker容器编排工具Compose模板文件介绍以及Django实战案例
Mesos 项目是源自 UC Berkeley 的对集群资源进行抽象和管理的开源项目,类似于操作系统内核,用户可以使用它很容易地实现分布式应用的自动化调度。
同时,Mesos 自身也很好地结合和主持了 Docker 等相关容器技术,基于 Mesos 已有的大量应用框架,可以实现用户应用的快速上线。
本节将介绍 Mesos 项目的安装、使用、以及核心的原理知识。
简介
Mesos 最初由 UC Berkeley 的 AMP 实验室于 2009 年发起,遵循 Apache 协议,目前已经成立了 Mesosphere 公司进行运营。Mesos 可以将整个数据中心的资源(包括 CPU、内存、存储、网络等)进行抽象和调度,使得多个应用同时运行在集群中分享资源,并无需关心资源的物理分布情况。
如果把数据中心中的集群资源看做一台服务器,那么 Mesos 要做的事情,其实就是今天操作系统内核的职责:抽象资源 + 调度任务。Mesos 项目是 Mesosphere 公司 Datacenter Operating System (DCOS) 产品的核心部件。
Mesos 项目主要由 C++ 语言编写,项目官方地址为 https://mesos.apache.org,代码仍在快速演化中,已经发布了正式版 1.0.0 版本。
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 打造自己的分布式应用框架。
Mesos 安装与使用
以 Mesos 结合 Marathon 应用框架为例,来看下如何快速搭建一套 Mesos 平台。
Marathon 是可以跟 Mesos 一起协作的一个 framework,基于 Scala 实现,可以实现保持应用的持续运行。
另外,Mesos 默认利用 ZooKeeper 来进行多个主节点之间的选举,以及从节点发现主节点的过程。一般在生产环境中,需要启动多个 Mesos master 服务(推荐 3 或 5 个),并且推荐使用 supervisord 等进程管理器来自动保持服务的运行。
ZooKeeper 是一个分布式集群中信息同步的工具,通过自动在多个节点中选举 leader,保障多个节点之间的某些信息保持一致性。
安装
安装主要需要 mesos、zookeeper 和 marathon 三个软件包。
Mesos 也采用了经典的主-从结构,一般包括若干主节点和大量从节点。其中,mesos master 服务和 zookeeper 需要部署到所有的主节点,mesos slave 服务需要部署到所有从节点。marathon 可以部署到主节点。
安装可以通过源码编译、软件源或者 Docker 镜像方式进行,下面分别进行介绍。
源码编译
源码编译方式可以保障获取到最新版本,但编译过程比较费时间。
首先,从 apache.org 开源网站下载最新的源码。
$ git clone https://git-wip-us.apache.org/repos/asf/mesos.git
其中,主要代码在 src 目录下,应用框架代码在 frameworks 目录下,文档在 docs 目录下,include 中包括了跟 Mesos 打交道使用的一些 API 定义头文件。
安装依赖,主要包括 Java 运行环境、Linux 上的自动编译环境等。
$ sudo apt-get update $ sudo apt-get install -y openjdk-8-jdk autoconf libtool \ build-essential python-dev python-boto libcurl4-nss-dev \ libsasl2-dev maven libapr1-dev libsvn-dev
后面就是常规 C++ 项目的方法,configure 之后利用 Makefile 进行编译和安装。
$ cd mesos $ ./bootstrap $ mkdir build $ cd build && ../configure --with-network-isolator $ make $ make check && sudo make install
软件源安装
通过软件源方式进行安装相对会省时间,但往往不是最新版本。
这里以 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 三个软件包。
$ sudo apt-get -y update && sudo apt-get -y install zookeeper mesos marathon
注意,Marathon 最新版本需要 jdk 1.8+ 的支持。如果系统中有多个 Java 版本,需要检查配置默认的 JDK 版本符合要求。
$ sudo update-alternatives --config java
安装 Mesos 成功后,会在 /usr/sbin/ 下面发现 mesos-master 和 mesos-slave 两个二进制文件,分别对应主节点上需要运行的管理服务和从节点上需要运行的任务服务。
用户可以手动运行二进制文件启动服务,也可以通过 service 命令来方便进行管理。
例如,在主节点上重启 Mesos 管理服务:
$ sudo service mesos-master restart
通过 service 命令来管理,实际上是通过调用 /usr/bin/mesos-init-wrapper 脚本文件进行处理。
基于 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/
其中 mesos-master 镜像在后面将分别作为 master 和 slave 角色进行使用。
首先,拉取三个镜像。
$ docker pull garland/zookeeper $ docker pull garland/mesosphere-docker-mesos-master $ docker pull garland/mesosphere-docker-marathon
导出主节点机器的地址到环境变量。
$ HOST_IP=10.0.0.2
在主节点上启动 Zookeepr 容器。
docker run -d \ -p 2181:2181 \ -p 2888:2888 \ -p 3888:3888 \ garland/zookeeper
在主节点上启动 Mesos Master 服务容器。
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。
docker run \ -d \ -p 8080:8080 \ garland/mesosphere-docker-marathon --master zk://${HOST_IP}:2181/mesos --zk zk://${HOST_IP}:2181/marathon
在从节点上启动 Mesos slave 容器。
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
接下来,可以通过访问本地 8080 端口来使用 Marathon 启动任务了。
配置说明
下面以本地通过软件源方式安装为例,解释如何修改各个配置文件。
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
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
更多选项可以参考后面的配置项解析章节。
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
访问 Mesos 图形界面
Mesos 自带了 Web 图形界面,可以方便用户查看集群状态。
用户在 Mesos 主节点服务和从节点服务都启动后,可以通过浏览器访问主节点 5050 端口,看到类似如下界面,已经有两个 slave 节点加入了。
图 1.22.2.1 - mesos 界面查看加入的 slave 节点
通过 Slaves 标签页能看到加入集群的从节点的信息。
如果没有启动 Marathon 服务,在 Frameworks 标签页下将看不到任何内容。
访问 Marathon 图形界面
Marathon 服务启动成功后,在 Mesos 的 web 界面的 Frameworks 标签页下面将能看到名称为 marathon 的框架出现。
同时可以通过浏览器访问 8080 端口,看到 Marathon 自己的管理界面。
图 1.22.2.2 - marathon 图形管理界面
此时,可以通过界面或者 REST API 来创建一个应用,Marathon 会保持该应用的持续运行。
图 1.22.2.3 - marathon 查看任务支持的参数
通过界面方式可以看到各任务支持的参数(包括资源、命令、环境变量、健康检查等),同时可以很容易地修改任务运行实例数进行扩展,非常适合进行测试。
如果要更自动化地使用 Marathon,则需要通过它的 REST API 进行操作。
一般的,启动新任务需要先创建一个定义模板(JSON 格式),然后发到指定的 API。
例如,示例任务 basic-0 的定义模板为:
{ "id": "basic-0", "cmd": "while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done", "cpus": 0.1, "mem": 10.0, "instances": 1 }
该任务申请资源为 0.1 个单核 CPU 资源和 10 MB 的内存资源,具体命令为每隔五秒钟用 shell 打印一句 Hello Marathon。
可以通过如下命令发出 basic-0 任务到 Marathon 框架,框架会分配任务到某个满足条件的从节点上,成功会返回一个 json 对象,描述任务的详细信息。
$ curl -X POST http://marathon_host:8080/v2/apps -d @basic-0.json -H "Content-type: application/json" {"id":"/basic-0","cmd":"while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done","args":null,"user":null,"env":{},"instances":1,"cpus":0.1,"mem":10,"disk":0,"executor":"","constraints":[],"uris":[],"storeUrls":[],"ports":[0],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":null,"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"version":"2015-12-28T05:33:05.805Z","tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"3ec3fbd5-11e4-479f-bd17-813d33e43e0c"}],"tasks":[]}%
Marathon 的更多 REST API 可以参考本地自带的文档:http://marathon_host:8080/api-console/index.html。
此时,如果运行任务的从节点出现故障,任务会自动在其它可用的从节点上启动。
此外,目前也已经支持基于 Docker 容器的任务。需要先在 Mesos slave 节点上为 slave 服务配置 --containerizers=docker,mesos 参数。
例如如下面的示例任务:
{ "id": "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,前者代表任务映射到的本地可用端口(可用范围由 Mesos slave 汇报,默认为 31000 ~ 32000);后者作为服务管理的端口,可以被用作一些服务发行机制使用进行转发,在整个 Marathon 集群中是唯一的。
任务执行后,也可以在对应 slave 节点上通过 Docker 命令查看容器运行情况,容器将以 mesos-SLAVE_ID 开头。
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1226b4ec8d7d python:3 "/bin/sh -c 'python3 " 3 days ago Up 3 days 0.0.0.0:10000->8080/tcp mesos-06db0fba-49dc-4d28-ad87-6c2d5a020866-S10.b581149e-2c43-46a2-b652-1a0bc10204b3
原理与架构
首先,再次需要强调 Mesos 自身只是一个资源调度框架,并非一整套完整的应用管理平台,所以只有 Mesos 自己是不能干活的。但是基于 Mesos,可以比较容易地为各种应用管理框架或者中间件平台(作为 Mesos 的应用)提供分布式运行能力;同时多个框架也可以同时运行在一个 Mesos 集群中,提高整体的资源使用效率。
Mesos 对自己定位范围的划分,使得它要完成的任务很明确,其它任务框架也可以很容易的与它进行整合。
架构
下面这张基本架构图来自 Mesos 官方。
图 1.22.3.1 - mesos 的基本架构
可以看出,Mesos 采用了经典的主-从(master-slave)架构,其中主节点(管理节点)可以使用 zookeeper 来做 HA。
Mesos master 服务将运行在主节点上,Mesos slave 服务则需要运行在各个计算任务节点上。
负责完成具体任务的应用框架们,跟 Mesos master 进行交互,来申请资源。
基本单元
Mesos 中有三个基本的组件:管理服务(master)、任务服务(slave)以及应用框架(framework)。
管理服务 - master
跟大部分分布式系统中类似,主节点起到管理作用,将看到全局的信息,负责不同应用框架之间的资源调度和逻辑控制。应用框架需要注册到管理服务上才能被使用。
用户和应用需要通过主节点提供的 API 来获取集群状态和操作集群资源。
任务服务 - slave
负责汇报本从节点上的资源状态(空闲资源、运行状态等等)给主节点,并负责隔离本地资源来执行主节点分配的具体任务。
隔离机制目前包括各种容器机制,包括 LXC、Docker 等。
应用框架 - framework
应用框架是实际干活的,包括两个主要组件:
- 调度器(scheduler):注册到主节点,等待分配资源;
- 执行器(executor):在从节点上执行框架指定的任务(框架也可以使用 Mesos 自带的执行器,包括 shell 脚本执行器和 Docker 执行器)。
应用框架可以分两种:一种是对资源的需求是会扩展的(比如 Hadoop、Spark 等),申请后还可能调整;一种是对资源需求大小是固定的(MPI 等),一次申请即可。
调度
对于一个资源调度框架来说,最核心的就是调度机制,怎么能快速高效地完成对某个应用框架资源的分配,是核心竞争力所在。最理想情况下(大部分时候都无法实现),最好是能猜到应用们的实际需求,实现最大化的资源使用率。
Mesos 为了实现尽量优化的调度,采取了两层(two-layer)的调度算法。
算法基本过程
调度的基本思路很简单,master 先全局调度一大块资源给某个 framework,framework 自己再实现内部的细粒度调度,决定哪个任务用多少资源。两层调度简化了 Mesos master 自身的调度过程,通过将复杂的细粒度调度交由 framework 实现,避免了 Mesos master 成为性能瓶颈。
调度机制支持插件机制来实现不同的策略。默认是 Dominant Resource Fairness(DRF)。
注:DRF 算法细节可以参考论文《Dominant Resource Fairness: Fair Allocation of Multiple Resource Types》。其核心思想是对不同类型资源的多个请求,计算请求的主资源类型,然后根据主资源进行公平分配。
调度过程
调度通过 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 也支持回收机制。
主节点可以定期回收计算节点上的任务所占用的资源,可以动态调整长期任务和短期任务的分布。
HA
从架构上看,最为核心的节点是 master 节点。除了使用 ZooKeeper 来解决单点失效问题之外,Mesos 的 master 节点自身还提供了很高的鲁棒性。
Mesos master 节点在重启后,可以动态通过 slave 和 framework 发来的消息重建内部状态,虽然可能导致一定的时延,但这避免了传统控制节点对数据库的依赖。
当然,为了减少 master 节点的负载过大,在集群中 slave 节点数目较多的时候,要避免把各种通知的周期配置的过短。实践中,可以通过部署多个 Mesos 集群来保持单个集群的规模不要过大。
本文暂时没有评论,来添加一个吧(●'◡'●)