原文:
annas-archive.org/md5/02afb619d35d623ceeb88a3a89f4324f译者:飞龙
第四章:服务调度和管理框架
本章介绍了几个基于 Mesos 的调度和管理框架或应用程序,这些框架或应用程序对于长期运行服务的轻松部署、发现、负载均衡和故障处理至关重要。这些所谓的元框架负责处理其他框架和应用程序的家务工作,例如服务发现(即跟踪某个特定服务运行的实例)和负载均衡(确保在各个实例之间公平分配工作负载),此外还包括配置管理、自动化****任务调度、应用程序****扩展和故障处理。我们将在这里探讨的框架包括:
-
Marathon:用于在 Mesos 上启动和管理长期运行的应用程序
-
Chronos:这是一个集群调度器
-
Apache Aurora:这是一个用于长期运行服务和定时任务的框架
-
Singularity:这是一个平台即服务(PaaS),用于运行服务
-
Marathoner:这是用于 Marathon 的服务发现工具
-
Consul:执行服务发现和协调
-
HAProxy:用于负载均衡
-
Bamboo:用于自动配置 Mesos 和 Marathon 的 HAProxy
此外,我们还将简要介绍两个非常新的开源框架,即Netflix Fenzo(一个任务调度器)和Yelp 的 PaaSTA(一个运行服务的 PaaS)。
使用 Marathon 在 Mesos 上启动和管理长期运行的应用程序
Marathon 是一个常用的 Mesos 框架,用于长期运行的应用程序。它可以被视为传统系统中 init 或 upstart 的替代品,或者是您系统的 init.d。
Marathon 拥有许多功能,例如控制高可用环境、检查应用程序的健康状态等。它还支持表现层状态转移(REST),如端点,您可以使用它来启动、停止和扩展您的应用程序。它可以根据负载自动扩展和缩减集群,这意味着它应能在某个可用实例宕机时启动新的实例。Marathon 还设计用来运行其他框架,例如Hadoop、Kafka、Storm、Chronos等。Marathon 确保通过它启动的每个应用程序即使在某个从节点宕机的情况下也能继续运行。
Marathon 以高度可用的方式运行,这意味着集群中可以运行多个调度器,但在任何时候,只有一个领导者。当应用程序请求非领导者时,请求将被代理到活跃的领导者。您还可以使用 HAProxy(本章稍后将解释)进行服务发现和负载均衡。
Marathon 还支持基本的认证机制,并使用 SSL 加密连接。
安装 Marathon
访问 mesosphere.github.io/marathon/ 下载最新的 Marathon 版本。编写本书时,最新版本是 0.13.0。
可以按照如下方式下载 Marathon:
$ wget http://downloads.mesosphere.com/marathon/v0.13.0/marathon-0.13.0.tgz
下载后,按如下方式解压文件:
$ tar xf marathon-0.13.0.tgz
解压 Marathon 后,你将看到以下文件:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_01.jpg
Marathon 有一个开发模式,在该模式下你不需要分布式 Mesos 设置。这被称为 Marathon 本地模式。本地模式仅用于实验目的,不建议在任何生产环境中运行。ZooKeeper 和 Marathon 一起使用,用于存储状态。
安装 ZooKeeper 以存储状态
Marathon 要求你运行一个 Apache ZooKeeper 实例,以便它能够保存状态。按照以下步骤安装并使用 ZooKeeper:
-
访问
zookeeper.apache.org下载 ZooKeeper 的最新版本。编写本书时,当前版本是 3.4.7。 -
如下所示下载 ZooKeeper:
$ wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.7/zookeeper-3.4.7.tar.gz -
下载后,按如下方式解压归档文件:
$ tar xf zookeeper-3.4.7.tar.gz -
下一步是配置 ZooKeeper。可以按如下方式完成:
用以下内容编辑
conf/zoo.cfg文件:tickTime=2000 dataDir=/var/zookeeper clientPort=2181 -
然后,运行以下命令来启动 ZooKeeper:
$ bin/zkServer.sh start
启动成功后,你可以看到以下消息:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_02.jpg
在本地模式下启动 Marathon
以下命令将启动 Marathon 本地模式:
$ ./bin/start --master local --zk zk://localhost:2181/marathon
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_03.jpg
一旦 ZooKeeper 启动并运行,你可以通过浏览器访问服务器上的 8080 端口来查看 Marathon UI。
多节点 Marathon 集群设置
要设置此环境,需要配置一个高可用性的 Mesos 集群,详细内容将在第五章中解释,Mesos 集群部署。目前我们假设你已经配置好了高可用性的 Mesos 集群。接下来,我们将看看如何在集群的所有主机上安装 Marathon。
登录到所有 Mesos 主机,并输入以下命令来设置 Marathon。
在 Debian/Ubuntu 系统上,运行以下命令:
# Update the repositories
# Setup
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
$ DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
$ CODENAME=$(lsb_release -cs)
# Add the repository
$ echo "deb http://repos.mesosphere.com/${DISTRO} ${CODENAME} main" | \
sudo tee /etc/apt/sources.list.d/mesosphere.list
$ sudo apt-get
update
# Install Marathon
$ sudo apt-get -y install marathon
在 RedHat/CentOS 系统上,执行以下命令:
$ sudo yum -y install marathon
现在,你可以在浏览器中访问任何一个主机的 8080 端口,并查看 Marathon UI:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_04.jpg
从 UI 启动测试应用程序
在 Mesos 中,应用程序通常是一个长时间运行的服务,可以扩展到多个实例。现在,我们将查看从用户界面启动测试应用程序的步骤:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_05.jpg
-
点击左上角的 + 创建 按钮。
-
ID 可以用来标识任务。我们将其命名为
marathon-test。 -
提供作业所需的 CPU 数量——比如说,
1。 -
内存以 MB 为单位,因此我们将分配
16MB(这也是默认值)。 -
实例数可以为我们的测试应用程序设置为 1。
-
在命令框下的文本框中编写以下 bash 脚本:
while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done
如果一切正确,你会首先看到 marathon-test 测试应用程序,状态为 已部署,最终会变为 运行中。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_06.jpg
扩展应用程序
在创建时,我们给出了 1 作为实例数。我们可以通过点击 UI 上的“扩展应用程序”按钮来修改实例数量。应用程序将按指定的实例数量启动。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_07.jpg
终止应用程序
现在我们可以通过点击应用程序列表中的应用程序名称,然后点击 销毁 按钮来终止我们的 marathon-test 应用程序。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_08.jpg
销毁应用程序是一个不可逆的过程,无法撤销。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_09.jpg
Chronos 作为集群调度器
可以将 Chronos 看作一个基于时间的作业调度器,例如典型 Unix 环境中的 cron。Chronos 是分布式的,完全容错,并且运行在 Apache Mesos 之上。
与 cron 类似,Chronos 默认执行 shell 脚本(结合 Linux 命令),并且支持 Mesos 执行器。
即使 Mesos 工作节点(实际执行作业的机器)上没有安装该系统,Chronos 也可以与像 Hadoop 或 Kafka 这样的系统进行交互。你可以使用 Chronos 在远程机器的后台启动服务或运行脚本。包装脚本可以包含异步回调,提醒 Chronos 作业状态,如是否完成或失败等。大多数情况下,人们使用 Chronos 来运行 Docker 化的应用程序。关于 Docker 化应用程序 的详细解释,请参见 第七章,Mesos 容器化器。
Chronos 附带一个 Web UI,你可以在其中查看作业状态、作业历史统计、作业配置以及重试信息。
安装 Chronos
登录到任何一台机器(比如说其中一台 Mesos 主机),然后输入以下命令来设置 Chronos。
在 Debian/Ubuntu 机器上,运行以下命令:
# Install chronos
$ sudo apt-get -y install chronos
# Start the chronos server
$ sudo service chronos start
在 RedHat/CentOS 机器上,执行以下代码:
# Install chronos
$ sudo yum -y install chronos
# Start the chronos server
$ sudo service chronos start
安装完成后,你可以将浏览器指向机器的 4400 端口来查看 Chronos 的 UI,如下所示:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_10.jpg
调度一个新作业
按照这里提到的步骤调度新作业:
-
点击 + 新建作业 按钮,如前一截图所示。https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_11.jpg
-
现在,填写 名称 和 描述 字段。
-
COMMAND 是将实际调度在执行器上运行的任务。为了简化起见,我们将仅运行
sleep命令。 -
在 OWNER(S) 字段中,我们可以填写名称和电子邮件地址,以便 Chronos 在任务失败时向其发送警报邮件。
-
在 SCHEDULE 下,我们可以设置任务应该运行的调度频率。默认情况下,它是空的并且是无限的。我们可以将其设置为任何数字值。例如,当值设置为 0 时,重复次数仅为一次。
一旦任务创建成功,我们可以通过 UI 查看任务的摘要,如下图所示:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_12.jpg
任务的状态也可以在以下截图中查看。在这种情况下,我们可以看到 chronos-test 任务处于 运行中 状态:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_13.jpg
我们可以前往 Mesos UI(运行在 5050 端口上),实际查看由 Chronos 启动的任务。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_14.jpg
Chronos 加 Marathon
Chronos 和 Marathon 的结合可以作为构建生产级分布式应用程序的基础。你已经知道 Chronos 可以在预定的时间间隔触发任务;cron 和 Marathon 让你的任务能够持续运行,例如在典型的 Linux 环境中的 init 或 upstart。如前所述,两个调度器都提供 REST 端点,允许用户管理任务。你可以使用这个端点来启动、管理和终止运行中的任务。接下来我们将看看这是如何实现的。
Chronos REST API 端点
如前所述,您可以通过 HTTP 使用 REST JSON API 与 Chronos 进行通信。默认情况下,运行 Chronos 的节点会在 8080 端口监听 API 请求。本节将介绍如何使用 REST 端点执行以下任务:
-
列出正在运行的任务
-
手动启动任务
-
添加一个调度任务
-
删除任务
欲了解更多信息,请访问 mesos.github.io/chronos/docs/api.html。
列出正在运行的任务
使用 HTTP GET 方法请求 /scheduler/jobs 将返回当前正在运行的任务列表,格式为 JSON。
这是一个示例:
$ curl -L -X GET localhost:8080/scheduler/jobs
响应中包含以下数据:
-
successCount -
errorCount -
lastSuccess -
lastError -
executor -
parents
手动启动任务
要手动启动任务,请向 /scheduler/job 发送 HTTP PUT 请求,并在命令的末尾添加可选参数。
看一下以下示例:
$ curl -L -X PUT localhost:8080/scheduler/job/job_a?arguments=-debug
添加一个调度任务
你可以向 /scheduler/iso8601 发送 HTTP POST 请求,并附带 JSON 数据来调度任务。发送给 Chronos 的 JSON 数据必须包含以下字段:
-
名称
-
命令
-
schedule
-
任务的重复次数;
-
任务开始时间,采用 ISO 8601 格式;
-
标准 ISO 8601 日期时间格式
-
scheduleTimeZone
-
epsilon
-
拥有者
-
异步
请看以下示例:
$ curl -L -H 'Content-Type: application/json' -X POST -d '{ "schedule": "<some_value>", "name": "jab_a", "epsilon": "….", "command": "echo 'FOO' >> /tmp/job_a_OUT", "owner": "akhil@sigmoid.com", "async": false }' localhost:8080/scheduler/iso8601
删除一个作业
要删除作业,你可以在/scheduler/job/<jobName>上使用HTTP DELETE请求,其中jobName可以从正在运行的作业列表中获取。
这是一个示例:
$ curl -L -X DELETE localhost:8080/scheduler/job/job_a
删除作业的所有任务
要删除某个作业的所有任务,你可以在/scheduler/task/kill/<jobName>上使用HTTP DELETE请求。
请看以下示例:
$ curl -L -X DELETE localhost:8080/scheduler/task/kill/job_a
Marathon REST API 端点
本节将介绍 Marathon 的 REST 端点。可以执行以下任务:
-
列出正在运行的应用程序。
-
添加一个应用程序。
-
更改配置。
-
删除一个应用程序。
列出正在运行的应用程序
你可以通过向/v2/apps端点发送HTTP GET请求,列出在 Marathon 上部署的正在运行的应用程序。该端点还支持一个过滤器,可以帮助你将列出内容限制到特定的应用程序。
以下是该端点所需的参数:
-
cmd:用于过滤包含给定命令的应用程序 -
embed:可以多次指定该参数,用于嵌入与提供的路径匹配的嵌套资源
这是一个示例:
$ curl -L -X GET "localhost:8080/v2/apps?cmd=sleep 60"
你可以查看以下类似的 JSON 格式响应:
{
"apps": [
{
"id": "/product/us-east/service/myapp",
"cmd": "env && sleep 60",
"constraints": [
[
"hostname",
"UNIQUE",
""
]
],
"container": null,
"cpus": 0.1,
"env": {
"LD_LIBRARY_PATH": "/usr/local/lib/myLib"
},
"executor": "",
"instances": 3,
"mem": 5.0,
"ports": [
15092,
14566
],
"tasksRunning": 1,
"tasksStaged": 0,
"uris": [
"https://raw.github.com/Mesosphere/Marathon/master/README.md"
],
"version": "2014-03-01T23:42:20.938Z"
}
]
}
添加一个应用程序
要从 REST 端点创建并启动一个应用程序,你可以使用/v2/apps端点并发送一个HTTP POST请求。该请求需要传递包含应用程序信息的 JSON 数据。以下是此调用所需的参数:
-
id:这是应用程序的名称 -
cmd:这是需要执行的命令 -
args:这是应用程序的可选参数 -
cpus:这是为应用程序分配的 CPU 核心数量 -
mem:这是为应用程序分配的内存大小 -
ports:这是为应用程序预留的端口 -
instances:这是部署应用程序的实例数量
以下示例展示了如何在 Marathon 中启动一个简单的 Python HTTP 服务器作为应用程序:
$ curl -L -H 'Content-Type: application/json' -X POST –d
'{
"args": null,
"backoffFactor": 1.15,
"backoffSeconds": 1,
"maxLaunchDelaySeconds": 3600,
"cmd": "env && python3 -m http.server $PORT0",
"constraints": [
[
"hostname",
"UNIQUE"
]
],
"container": {
"Docker": {
"image": "python:3"
},
"type": "DOCKER",
"volumes": []
},
"cpus": 0.25,
"dependencies": [],
"deployments": [
{
"id": "f44fd4fc-4330-4600-a68b-99c7bd33014a"
}
],
"disk": 0.0,
"env": {},
"executor": "",
"healthChecks": [
{
"command": null,
"gracePeriodSeconds": 3,
"intervalSeconds": 10,
"maxConsecutiveFailures": 3,
"path": "/",
"portIndex": 0,
"protocol": "HTTP",
"timeoutSeconds": 5
}
],
"id": "/my-app",
"instances": 2,
"mem": 50.0,
"ports": [
0
],
"requirePorts": false,
"storeUrls": [],
"upgradeStrategy": {
"minimumHealthCapacity": 0.5,
"maximumOverCapacity": 0.5
},
"uris": [],
"user": null,
"version": "2014-08-18T22:36:41.451Z"
}
' localhost:8080/v2/apps
另外,注意如果给定的应用程序 ID 在 Marathon 中已经存在,将会抛出重复错误,并且应用程序根本不会启动。
更改应用程序的配置
你可以向/v2/apps/<appId>端点发送一个HTTP PUT请求,来更改给定应用程序的配置。appId值可以通过之前列出正在运行的应用程序的方法获取。一旦请求发送,当前运行的任务将会使用新的配置重启。
它接受force参数,布尔值,默认为 false。将其设置为 true 会覆盖当前的部署,如果应用程序的状态受到影响的话。
考虑以下示例:
$ curl -L -X PUT localhost:8080/v2/apps/my_app -d '{
"cmd": "sleep 55",
"constraints": [
[
"hostname",
"UNIQUE",
""
]
],
"cpus": "0.3",
"instances": "2",
"mem": "9",
"ports": [
9000
]
}
'
一旦更新成功,它将返回一个包含以下内容的 JSON 响应:
{
"deploymentId": "6b2135a6-3326-4e44-9333-554eda6c3838",
"version": "2015-12-16T12:37:50.462Z"
}
删除应用程序
你可以使用HTTP DELETE请求在/v2/apps/<appId>端点销毁应用程序及其相关数据。
看一下以下示例:
$ curl -X DELETE localhost:8080/v2/apps/my_app
Apache Aurora 介绍
Apache Aurora 是一个强大的 Mesos 框架,适用于长期运行的服务、定时任务和临时任务。它最初在 Twitter 设计,后来根据 Apache 许可证开源。你可以使用 Aurora 将 Mesos 集群转变为私人云。与 Marathon 不同,Aurora 负责在共享资源池中长时间运行任务。如果池中的任何机器出现故障,Aurora 可以智能地将任务重新调度到其他健康的机器上。
如果你尝试构建一个具有特定调度需求的应用程序,或者如果任务本身就是一个调度器,那么 Aurora 将不适用。
管理长期运行的应用程序是 Aurora 的关键功能之一。除此之外,Aurora 可以为你的任务提供粗粒度(即固定)的资源,以确保任务始终具有指定数量的资源。它还支持多个用户,且配置使用 DSL(领域特定语言)模板化,以避免配置中的冗余。
安装 Aurora
Aurora 任务可以通过 Aurora Web UI 和 Aurora 命令行工具进行交互。要安装 Aurora,需要安装 vagrant。你可以使用以下命令安装 vagrant:
$ sudo apt-get install vagrant
登录到集群中的任何机器,使用以下命令克隆 Aurora 仓库:
$ git clone git://git.apache.org/aurora.git
将工作目录更改为 Aurora,如下所示:
$ cd aurora
然后,输入以下命令在此机器上安装 Aurora:
$ vagrant up
vagrant 命令将使用与 Aurora 分发版一起提供的配置,在虚拟机上安装并启动 Aurora 服务。它将:
-
下载相应的 Linux 虚拟机镜像
-
配置并启动虚拟机
-
在虚拟机上安装 Mesos 和 ZooKeeper 以及构建工具
-
在虚拟机上编译并构建 Aurora 源代码
-
在虚拟机上启动 Aurora 服务
这个过程可能需要几分钟才能完成。如果命令失败并提示机器上没有安装 VirtualBox,可以使用以下命令进行安装:
$ sudo apt-get install virtualbox
如果一切顺利,你将在终端看到以下输出:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_15.jpg
Singularity 介绍
Singularity 最初在 HubSpot 设计,后来根据 Apache 许可证开源。Singularity 作为一个 API 和 Web 应用程序,可以用于启动和调度长期运行的 Mesos 进程、定时任务和任务。可以将 Singularity 及其组件视为一个PaaS(平台即服务)提供给最终用户。初学者可以使用 Singularity 在 Mesos 上部署任务,而无需详细了解 Mesos。
Singularity 利用 Apache Mesos 的容错性、可扩展性和资源分配等功能,并作为 Mesos 框架的任务调度器运行。
安装 Singularity
在安装 Singularity 之前,确保你的机器上已经安装了 Docker。如果还没有安装,你可以通过访问 docs.docker.com 上的官方文档来安装。
第一步是克隆 Singularity 仓库,操作如下:
$ git clone https://github.com/HubSpot/Singularity
现在,将工作目录切换到 Singularity,如下所示:
$ cd Singularity
一旦成功安装了 Docker 和 Docker Compose,你可以使用 Docker Compose 的 pull 和 up 命令来尝试 Singularity。这些命令将为你在容器中设置以下内容:
-
Mesos 主节点和从节点
-
ZooKeeper
-
奇点
-
Baragon 服务和代理
如果你希望在没有 Docker 的情况下安装 Singularity,以下步骤可以帮助你完成安装:
# Compile the source code
$ mvn clean package
完成后,你可以看到 Singularity jars 被创建在 SingularityService/target 目录下。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_16.jpg
我们将使用 SingularityService-0.4.6-SNAPSHOT-shaded.jar 来运行 Singularity。
创建 Singularity 配置文件
Singularity 配置保存在 YAML 文件中。这里将解释一个示例的 YAML 配置文件。
端口 7099 用于运行 SingulartiyService,日志将保存在 /var/log/singularity-access.log 中。请查看以下代码:
server:
type: simple
applicationContextPath: /singularity
connector:
type: http
port: 7099
requestLog:
appenders:
type: file
currentLogFilename: /var/log/singularity-access.log
archivedLogFilenamePattern: /var/log/singularity-access-%d.log.gz
#Mesos configuration, put the content from /etc/Mesos/zk as Mesos master
mesos:
master: zk://100.76.90.36:2181,100.76.126.34:2181,100.72.150.2:2181/Mesos
defaultCpus: 1 # number of core that will be used by the job
defaultMemory: 128 # default memory of the job, being 128MB
frameworkName: Singularity
frameworkId: Singularity
frameworkFailoverTimeout: 1000000
Zookeeper: # quorum should be a host:port separated by comma
quorum: 100.76.90.36:2181,100.76.126.34:2181,100.72.150.2:2181
zkNamespace: singularity
sessionTimeoutMillis: 60000
connectTimeoutMillis: 5000
retryBaseSleepTimeMilliseconds: 1000
retryMaxTries: 3
logging:
loggers:
"com.hubspot.singularity" : TRACE
enableCorsFilter: true
sandboxDefaultsToTaskId: false # enable if using SingularityExecutor
ui:
title: Singularity (local)
baseUrl: http://localhost:7099/singularity
将上述配置保存为 singularity_config.yaml,并使用以下命令启动 Singularity:
java -jar SingularityService/target/SingularityService-*-shaded.jar server singularity_config.yaml
如果一切顺利,你将在 Mesos UI 的框架标签下看到 Singularity 框架,如下图所示:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_17.jpg
你可以将浏览器指向以下 URL 来访问 Singularity 的 UI:http://ServerIPAddress:7099/singularity/。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_18.jpg
使用 Marathoner 的服务发现
现代分布式应用程序需要一种相互通信的方式,这意味着当它们在同一网络上时,一个应用程序应该知道另一个应用程序的存在。这就是服务发现。在本节中,我们将查看在 Marathon 上运行的 Web 服务的服务发现。你可以采用这种方法来处理大多数在 Marathon 上运行的无状态应用程序。
我们将结合流行的 HAProxy TCP/HTTP 负载均衡器和 Marathon 的 REST API 脚本(在之前的主题中已覆盖),重新生成 HAProxy 配置文件,以实现 Marathon 应用程序的服务发现。当任务在某个 Mesos 从节点上启动时,它们会配置为将端口绑定到默认范围 31,000-32,000 内的一个任意端口。
服务发现使得在 Marathon 上运行的应用程序可以通过它们配置的 Marathon 应用程序端口与其他应用程序进行通信。例如,你可以考虑一个运行在端口 80 上的 Python Web 应用程序,它可以通过连接到 localhost:8080 来与其在端口 8080 上运行的 Java 后端进行通信。
HAProxy 可以将它收到的请求路由到实际运行服务实例的端口和主机。如果由于某种原因,它未能连接到给定的主机和端口,它将尝试连接到下一个配置运行该服务的实例。
我们将使用 HAProxy-Marathon-bridge shell 脚本,该脚本是 Marathon 提供的,用于连接到 Marathon 并检索主机名、运行中的应用程序绑定的端口以及配置的应用程序端口。该脚本每 60 秒通过 cron 调度运行一次。该脚本基本上检查它在上次运行中生成的配置与当前配置是否有所不同,如果检测到变化,则重新加载新的配置到 HAProxy 中。请注意,我们不需要重新启动 HAProxy。
以下是两个服务 SVC1 和 SVC2 在集群中运行的图示,它们分别配置了在端口 1111 和 2222 上运行的应用程序。Mesos 分配的任务端口分别是 31100 和 31200。请注意,由 HAProxy 负责在用户配置的应用程序端口和 Mesos 分配的任务端口之间路由请求。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_19.jpg
例如,如果从从节点 2 上的 SVC2 尝试通过 localhost:2222 连接到 SVC1,HAProxy 将把请求路由到配置的 SVC1 实例——即运行在从节点 1 上的实例。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_20.jpg
如果从节点 1 出现故障,则对 localhost:2222 的请求将被路由到从节点 2。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_21.jpg
使用 Consul 进行服务发现
Mesos-consul 用于注册和注销作为 Mesos 任务运行的服务。
例如,如果你有一个名为 myapp 的 Mesos 任务,那么该程序将会在 Consul 中注册该应用程序,并将其 DNS 暴露为 myapp.service.consul。Consul 还通过 leader.Mesos.service.consul DNS 进行 Mesos 主节点发现,该 DNS 指向当前活动的主节点。
这与其他服务发现软件有何不同?
Mesos-dns 是一个类似于 Consul 的项目。在 Mesos-dns 中,它轮询 Mesos 以获取任务信息,而在 Consul 中,信息不是通过内置的 DNS 服务器暴露,而是通过 Consul 服务发现填充这些信息。然后,这些服务通过 DNS 和其 REST 端点由 Consul 暴露。
运行 Consul
如果你的 ZooKeeper 和 Marathon 服务没有在 Consul 中注册,你需要更改环境变量的值。你可以将 Consul 容器化,并通过 Marathon 运行它。
Consul 可以以以下方式运行:
curl -X POST -d@Mesos-consul.json -H "Content-Type: application/json" http://Marathon.service.consul:8080/v2/apps'
上述代码是一个 HTTP POST 请求,向 Consul API 端点发送以下 JSON 数据,位于 Mesos-consul.json 文件中:
{
"args": [
"--zk=zk://Zookeeper.service.consul:2181/Mesos"
],
"container": {
"type": "DOCKER",
"Docker": {
"network": "BRIDGE",
"image": "{{ Mesos_consul_image }}:{{ Mesos_consul_image_tag }}"
}
},
"id": "Mesos-consul",
"instances": 1,
"cpus": 0.1,
"mem": 256
}
以下表格列出了命令行工具 Mesos-consul 支持的选项:
| 选项 | 描述 |
|---|---|
version | 这个命令会打印出 Mesos-consul 的版本。 |
refresh | 这指的是 Mesos 任务刷新之间的时间间隔。 |
Mesos-ip-order | 这是一个以逗号分隔的列表,控制 github.com/CiscoCloud/Mesos-consul 查找任务 IP 地址的顺序。有效选项为 netinfo、Mesos、Docker 和 host(默认值为 netinfo,Mesos,host)。 |
healthcheck | 这个选项用于启用 HTTP 端点的健康检查。当启用此标志时,它会在 127.0.0.1:24476 提供健康状态。 |
healthcheck-ip | 这是健康检查服务接口的 IP(默认值为 127.0.0.1)。 |
healthcheck-port | 这是健康检查服务的端口(默认值为 24476)。 |
consul-auth | 这是用于身份验证的用户名和密码(可选),由冒号分隔。 |
consul-ssl | 这会在与注册表通信时使用 HTTPS。 |
consul-ssl-verify | 在通过 SSL 连接时验证证书。 |
consul-ssl-cert | 提供 SSL 证书的路径,可用于身份验证注册表服务器。 |
consul-ssl-cacert | 这是 CA 证书文件的路径,包含一个或多个 CA 证书,可用于验证注册表服务器证书。 |
consul-token | 这是用于注册表 ACL 的令牌。 |
heartbeats-before-remove | 这是在任务从 Consul 中移除之前,注册失败的次数(默认值为 1)。 |
zk* | 这是 ZooKeeper 中 Mesos 路径的位置,默认值为 zk://127.0.0.1:2181/Mesos。 |
使用 HAProxy 进行负载均衡
HAProxy-Marathon-bridge 脚本随 Marathon 安装一起提供。你也可以使用 Marathon-lb 来实现相同的功能。这两个工具都会通过查看 Marathon 的 REST API 中正在运行的任务,来为 HAProxy 创建一个配置文件和一个轻量级的 TCP/HTTP 代理。
HAProxy-Marathon-bridge 是一个简单的脚本,提供最小的功能集,且对新手用户更易理解。后者,Marathon-lb,支持高级功能,如 SSL 卸载、基于 VHost 的负载均衡和粘性连接。
创建 HAProxy 和 Marathon 之间的桥接
首先,你需要从运行中的 Marathon 实例创建 HAProxy 配置,该实例默认运行在机器的8080端口。你可以通过以下语法使用 HAProxy-Marathon-bridge 脚本来实现这一点:
$ ./bin/haproxy-Marathon-bridge localhost:8080 > /etc/haproxy/haproxy.cfg
请注意,这里我们指定了localhost:8080,因为我们在同一台机器上运行了 Marathon 实例和 HAProxy。
一旦生成了 HAProxy 配置,你可以通过运行以下命令来简单地重新加载 HAProxy,而不会中断现有的连接:
$ haproxy -f haproxy.cfg -p haproxy.pid -sf $(cat haproxy.pid)
你可以使用典型的 cron 作业自动化配置生成和重新加载过程。如果在重新加载过程中由于某种原因,某个节点发生故障,HAProxy 的健康检查将检测到并停止向该节点发送进一步的流量。
你无需创建触发器来重新加载 HAProxy 配置。HAProxy-Marathon-bridge 脚本已经为你完成了这项工作。它包含 HAProxy 和一个每分钟触发的 cron 作业,用来从 Marathon 服务器拉取配置,并在检测到与上一个版本的变化时刷新 HAProxy。
你可以使用以下命令来实现:
$ ./bin/haproxy-Marathon-bridge install_haproxy_system localhost:8080
它将在/etc/haproxy-Marathon-bridge/Marathons文件中为 Marathon 每一行添加 ping 命令,并将脚本安装在/usr/local/bin/haproxy-Marathon-bridge。你可以在/etc/cron.d/haproxy-Marathon-bridge目录下找到安装的 cron 作业,该作业将在根用户下触发。
Bamboo - 自动为 Mesos 加 Marathon 配置 HAProxy
Bamboo 作为 Web 守护进程运行,并自动为部署在 Mesos 和 Marathon 上的 Web 服务配置 HAProxy。
Bamboo 包含以下内容:
-
一个 Web UI,用于为每个 Marathon 应用程序配置 HAProxy 访问控制限制(ACL)规则。
-
一个 REST 端点来实现相同功能
-
基于你的模板的预配置 HAProxy 配置文件,你可以自定义自己的模板来启用 SSL 并设置 HAProxy 统计信息接口,或配置负载均衡策略。
-
如果 Marathon 应用配置了健康检查,则会有一个健康检查端点。
-
无状态守护进程,支持可扩展性和水平复制
-
无额外依赖(因为它是用 Golang 开发的)
-
与 StatsD 集成,监控配置重新加载事件
Bamboo 可以在每个 Mesos 从节点上与 HAProxy 一起部署。由于 Bamboo 主要用于部署在 Mesos 上的 Web 服务,因此服务发现就像连接到你为其分配了 ACL 规则的本地主机或域名一样简单。然而,你也可以将 HAProxy 和 Bamboo 部署在不同的机器上,这意味着你需要对 HAProxy 集群进行负载均衡。
以下截图显示了 Bamboo 和 HAProxy 通过 Marathon 与 Mesos 集群的交互:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_22.jpg
你可以使用以下命令安装 Bamboo:
# Clone the github repository
$ git clone https://github.com/QubitProducts/bamboo
# Change the working directory
$ cd bamboo
# Install, (make sure you have installed go first)
$ go build bamboo.go; ./builder/build.sh
安装完成后,打开浏览器并访问你安装了 Bamboo 的任意一台机器上的端口 8000,你将看到如下截图所示的 Web UI:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_23.jpg
你可以通过点击 Marathon 应用程序右侧的编辑图标来配置 ACLs。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_24.jpg
Bamboo 命令行接受一个 --config 选项,用于指定 JSON 应用配置文件的位置。你可以在 config 目录下找到示例配置文件模板;config/production.example.json 和 config/haproxy_template.cfg 就是其中的两个。现在,来看一下下面的代码:
{
// This is where you configure the Marathon instance
"Marathon": {
// Since we are running web applications, give the host:port to the applications
"Endpoint":"http://Marathon1:8080,http://Marathon2:8080,http://Marathon3:8080",
// Use the Marathon HTTP event streaming feature
"UseEventStream": true
},
"Bamboo": {
// Bamboo's HTTP address can be accessed by Marathon
// Used for Marathon HTTP callback and each Bamboo instance
// must provide a unique Endpoint that is directly addressable by Marathon
// (e.g., every server's IP address)
"Endpoint": "http://localhost:8000",
// Proxy setting information is stored in Zookeeper// This path is created by Bamboo, if it does not already exist
"Zookeeper": {
// Make sure that the same setting is used while running on the same ZK cluster
"Host": "zk01.example.com:2812,zk02.example.com:2812",
"Path": "/Marathon-haproxy/state",
"ReportingDelay": 5
}
}
// Make sure you are using absolute path on production
"HAProxy": {
"TemplatePath": "/var/bamboo/haproxy_template.cfg",
"OutputPath": "/etc/haproxy/haproxy.cfg",
"ReloadCommand": "haproxy -f /etc/haproxy/haproxy.cfg-p /var/run/haproxy.pid -D -sf $(cat /var/run/haproxy.pid)",
// A command that will validate the config before you run reload command.// '{{.}}' will be expanded to a temporary path that contains the config contents
"ReloadValidationCommand": "haproxy -c -f {{.}}",
// A command that will always be run after ReloadCommand, even if reload fails
"ReloadCleanupCommand": "exit 0"
},
// Enable or disable StatsD event tracking
"StatsD": {
"Enabled": false,
// StatsD or Graphite server host
"Host": "localhost:8125",
// StatsD namespace prefix -
// Label each node if you have multiple Bamboo instances
// by bamboo-server.production.n1.
"Prefix": "bamboo-server.production."
}
}
Bamboo 将以下环境变量映射到相应的 Bamboo 配置。你可以在 production.json 文件中使用这些配置:
| 环境变量 | 对应的配置项 |
|---|---|
MARATHON_ENDPOINT | Marathon.Endpoint |
MARATHON_USER | Marathon.User |
MARATHON_PASSWORD | Marathon.Password |
BAMBOO_ENDPOINT | Bamboo.Endpoint |
BAMBOO_ZK_HOST | Bamboo.Zookeeper.Host |
BAMBOO_ZK_PATH | Bamboo.Zookeeper.Path |
HAPROXY_TEMPLATE_PATH | HAProxy.TemplatePath |
HAPROXY_OUTPUT_PATH | HAProxy.OutputPath |
HAPROXY_RELOAD_CMD | HAProxy.ReloadCommand |
BAMBOO_DOCKER_AUTO_HOST | 当 Bamboo 容器启动时,这将把 BAMBOO_ENDPOINT 设置为 $HOST,并且可以是任何值 |
STATSD_ENABLED | StatsD.Enabled |
STATSD_PREFIX | StatsD.Prefix |
STATSD_HOST | StatsD.Host |
Netflix Fenzo 介绍
Netflix 最近开源了他们为 Apache Mesos 框架编写的调度器库,该库使用 Java 编写,支持调度优化和集群自动扩展。在写书时,Fenzo 已经开源,并且可以在官方的 Netflix OSS 套件仓库中找到,网址为:github.com/Netflix/Fenzo
开发像 Fenzo 这样的框架基本上有两个动机。与前面讨论的其他调度器和框架不同,构建 Fenzo 的原因是为了调度优化和根据使用情况自动扩展集群。
当你的集群处理的数据量时常变化时,预配置集群以应对峰值使用看起来很浪费,因为大部分时间资源会处于闲置状态。这正是根据负载自动扩展应用程序的主要原因——即,在集群资源达到峰值时提供更多机器,并在机器闲置时关闭这些机器。
扩展集群是一个较为简单的任务。您可以使用监控工具来观察资源利用率,当它超过阈值时,可以继续增加集群资源。另一方面,在缩减集群时,您需要识别您将要终止的机器上是否有长期运行的任务,以及终止这些机器是否会影响正在运行的任务。
目前,Fenzo 中的自动扩展基于以下两种策略:
-
阈值
-
资源短缺分析
在基于阈值的自动扩展中,用户可以根据主机组指定规则,如 EC2 自动扩展、GCE 自动扩展等。这些可以视为为计算密集型、网络密集型及其他工作负载创建主机组。这些规则使得新的任务可以迅速启动在预配置的空闲主机上。
在资源短缺分析的情况下,它首先计算完成待处理工作负载所需的主机数量。也可以将其视为一种预测性自动扩展系统,可以分析工作负载并启动新的主机以满足待处理的工作负载。这样的系统的一个例子是 Netflix 网站的 Scryer。
以下是一个图示,展示了 Fenzo 如何被 Apache Mesos 框架使用。Fenzo 本身包含一个任务调度器,提供调度核心,但并不直接与 Mesos 交互。该框架与 Mesos 交互,以获取新的资源报价并拉取任务状态更新。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_04_25.jpg
PaaSTA 简介
Yelp 的 PaaSTA(平台即服务)分布式系统具有高可用性,用于构建、部署和运行使用容器(如 Docker 和 Apache Mesos)的服务。PaaSTA 由 Yelp 设计和开发,并且最近已开源。您可以通过以下网址查看开源仓库:github.com/yelp/paasta
这是一个供开发人员指定如何从 Git 仓库构建、部署、路由和监控代码的工具集。Yelp 已使用 PaaSTA 超过一年,以支持其生产级别的服务。如果您有严格的生产环境,例如 Yelp,要求许多小型微服务,并且在推出新代码时应无缝进行且不打扰生产系统,PaaSTA 最为适用。PaaSTA 帮助自动化整个过程。
它包括以下现有的开源组件:
-
Docker:用于容器化代码
-
Apache Mesos:用于执行和调度
-
Marathon:用于管理长期运行的应用程序
-
Chronos:用于调度目的
-
SmartStack:用于服务发现和注册
-
Sensu:用于监控和警报
-
Jenkins:用于持续构建和部署(这是可选的)
将所有这些组件集中在一起的原因之一是可重用性。你可以重用这些组件中的任何一个来解决分布式环境中的不同问题。
不同调度/管理框架的比较分析
本节将简要比较和介绍我们在本章中讨论的不同调度框架及其应用场景。
Marathon 是一个构建在 Mesos 上的 PaaS,确保即使集群中的部分机器出现故障,作业仍然能够永远运行。它可以无缝处理硬件和软件故障,确保应用程序始终在运行。这类框架在生产环境中非常有用,特别是当你的应用程序需要 24/7 全天候运行并始终可用时——例如,托管网站的 Web 服务器。在这种情况下,你可以将其作为 Marathon 应用程序进行部署,后者会处理所有这些方面。
Chronos 可以被视为典型 Linux cron 作业的分布式容错替代品,cron 作业通常用于启动定时任务、定期备份、检查系统健康状况等。Chronos 和 Marathon 都提供了 Web UI 和 REST 端点来管理作业。我们可以围绕这些工具编写包装脚本,自动化应用程序部署和作业调度,而不仅仅依赖 Web UI。
Aurora 和 Marathon 本质上非常相似,它们都是服务调度器。你所需要做的就是告诉 Aurora 或 Marathon 如何部署应用程序,它们会保持应用程序持续运行,不会出现故障。另一方面,Aurora 对于初学者来说有点难以安装和使用。与 Marathon 不同,Aurora 并不正式支持 REST 端点,但很快会推出。在此之前,Aurora 通过暴露 Thrift API 来进行通信,这意味着你需要在服务器上额外安装 Thrift 库。
Apache Aurora 旨在处理大规模的基础设施,如数据中心。一个典型的例子是 Twitter 上运行的集群,这些集群由成千上万的机器组成,成百上千的工程师用来进行开发和生产。
总结
在本章中,我们深入探讨了一些 Mesos 的重要框架,这些框架使得作业调度和负载均衡变得更加容易和高效。我们介绍了如 Marathon 和 Chronos 等框架,它们的 REST 端点,以及其他一些工具,如 HAProxy、Consul、Marathoner、Bamboo、Fenzo 和 PaaSTA。
在下一章中,我们将讨论系统管理员和 DevOps 专业人员如何使用 Ansible、Chef、Puppet、Salt、Terraform 和 CloudFormation 等标准工具来部署 Mesos 集群,并利用 Nagios 和 Satellite 进行监控。
第五章:Mesos 集群部署
本章讲解了如何使用系统管理员和 DevOps 工程师常用的标准部署和配置管理工具,轻松地设置和监控 Mesos 集群。我们将解释如何通过 Ansible、Puppet、SaltStack、Chef、Terraform 或 Cloudformation 设置 Mesos 集群的步骤,并介绍如何使用 Playa Mesos 设置测试环境。我们还会讨论一些标准监控工具,例如 Nagios 和 Satellite,可以用来监控集群。我们还将讨论在部署 Mesos 集群时遇到的一些常见问题以及相应的解决方法。
本章将涵盖以下主题:
-
使用以下方法部署和配置 Mesos 集群:
-
Ansible
-
Puppet
-
SaltStack
-
Chef
-
Terraform
-
Cloudformation
-
-
使用 Playa Mesos 创建测试环境
-
常见部署问题及解决方案
-
使用以下工具监控 Mesos 集群:
-
Nagios
-
Satellite
-
使用 Ansible 部署和配置 Mesos 集群
Ansible 是一种流行的基础设施自动化工具,当前广泛应用于系统管理员中,并且最近被 Red Hat 收购。节点通过安全外壳(SSH)进行管理,只需要 Python 支持。Ansible 已开源了许多剧本,包括我们将在本节中讨论的 ansible-mesos 剧本。
ansible-mesos 剧本可以用于安装和配置 Mesos 集群,并支持自定义的主节点和从节点设置选项。目前,它支持基于 Ubuntu 和 CentOS/Red Hat 操作系统的机器。ansible-mesos 剧本还支持设置特定的从节点执行器,因此可以与原生 Docker 支持一起运行。
安装 Ansible
安装 Ansible 只需要在单台机器上进行。它不需要数据库,也不需要持续运行守护进程。它通过 SSH 来管理集群,并要求机器上安装 Python(版本 2.6 或 2.7)。你甚至可以在笔记本电脑或个人计算机上安装 Ansible,远程管理其他机器。安装了 Ansible 的机器被称为控制机器。在编写本书时,Windows 机器尚不受支持。受控制的机器称为受管节点,需要控制机器的 SSH 访问权限,并且上面也需要安装 Python(版本 2.4 或更高)。
安装控制机器
我们可以在没有 root 权限的情况下运行 Ansible,因为它不需要安装任何额外的软件或数据库服务器。执行以下代码:
# Install python pip
$ sudo easy_install pip
# Install the following python modules for ansible
$ sudo pip install paramiko PyYAML Jinja2 httplib2 six
# Clone the repository
$ git clone git://github.com/ansible/ansible.git --recursive
# Change the directory
$ cd ansible
# Installation
$ source ./hacking/env-setup
如果一切顺利,我们可以在终端中看到以下输出,表示安装成功。之后,我们将能够在终端中使用 Ansible 命令。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_01.jpg
默认情况下,Ansible 使用/etc/ansible/hosts中的清单文件,该文件采用类似 INI 格式,可能如下所示:
mail.xyz.com
[webservers]
foo.xyz.com
bar.xyz.com
[dbservers]
one.xyz.com
two.xyz.com
three.xyz.com
这里,组名用括号表示,可用于对将被管理的系统进行分类。
我们还可以使用命令行选项-i,将其指向不同的文件,而不是/etc/ansible/hosts中找到的文件。
创建 ansible-mesos 设置
Ansible 执行由角色组成的剧本,针对的是如之前在 hosts 文件中描述的,按组组织的一组主机。更多详情,请访问frankhinek.com/create-ansible-playbook-on-github-to-build-mesos-clusters/。
首先,让我们通过以下方式创建一个指向 Mesos 主节点和从节点的 hosts 文件:
$ cat hosts
[mesos_masters]
ec2-….compute-1.amazonaws.com zoo_id=1 ec2-….compute-1.amazonaws.com zoo_id=2
ec2-….compute-1.amazonaws.com zoo_id=3
[mesos_workers]
ec2-….compute-1.amazonaws.com
ec2-….compute-1.amazonaws.com
在这里,我们创建了两个组,分别命名为mesos_masters和mesos_workers,并列出了主节点和从节点的 IP 地址。对于mesos_masters组,我们还需要指定 ZooKeeper ID,因为集群将以高可用性运行。
在接下来的步骤中,我们将看看如何使用 Ansible 在 hosts 文件中列出的机器上部署 Mesos:
-
创建一个
site.yml文件,内容如下:-- # This playbook deploys the entire Mesos cluster infrastructure. # RUN: ansible-playbook --ask-sudo-pass -i hosts site.yml - name: deploy and configure the mesos masters hosts: mesos_masters sudo: True roles: - {role: mesos, mesos_install_mode: "master", tags: ["mesos-master"]} - name: deploy and configure the mesos slaves hosts: mesos_workers sudo: True roles: - {role: mesos, mesos_install_mode: "slave", tags: ["mesos-slave"]} -
现在,我们可以创建一个适用于集群中所有主机的组变量文件,内容如下:
$ mkdir group_vars $ vim all -
接下来,我们将在所有文件中放入以下内容:
--- # Variables here are applicable to all host groups mesos_version: 0.20.0-1.0.ubuntu1404 mesos_local_address: "{{ansible_eth0.ipv4.address}}" mesos_cluster_name: "XYZ" mesos_quorum_count: "2" zookeeper_client_port: "2181" zookeeper_leader_port: "2888" zookeeper_election_port: "3888" zookeeper_url: "zk://{{ groups.mesos_masters | join(':' + zookeeper_client_port + ',') }}:{{ zookeeper_client_port }}/mesos" -
现在,我们可以为 Mesos 集群创建角色。首先,通过以下命令创建一个 roles 目录:
$ mkdir roles; cd roles -
我们现在可以使用
ansible-galaxy命令初始化该角色的目录结构,内容如下:$ ansible-galaxy init mesos -
这将创建以下目录结构:https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_02.jpg
-
现在,修改
mesos/handlers/main.yml文件,内容如下:--- # handlers file for mesos - name: Start mesos-master shell: start mesos-master sudo: yes - name: Stop mesos-master shell: stop mesos-master sudo: yes - name: Start mesos-slave shell: start mesos-slave sudo: yes - name: Stop mesos-slave shell: stop mesos-slave sudo: yes - name: Restart zookeeper shell: restart zookeeper sudo: yes - name: Stop zookeeper shell: stop zookeeper sudo: yes -
接下来,按以下方式修改
mesos/tasks/main.yml文件中的任务:--- # tasks file for mesos # Common tasks for all Mesos nodes - name: Add key for Mesosphere repository apt_key: url=http://keyserver.ubuntu.com/pks/lookup?op=get&fingerprint=on&search=0xE56151BF state=present sudo: yes - name: Determine Linux distribution distributor shell: lsb_release -is | tr '[:upper:]' '[:lower:]' register: release_distributor - name: Determine Linux distribution codename command: lsb_release -cs register: release_codename - name: Add Mesosphere repository to sources list copy: content: "deb http://repos.mesosphere.io/{{release_distributor.stdout}} {{release_codename.stdout}} main" dest: /etc/apt/sources.list.d/mesosphere.list mode: 0644 sudo: yes # Tasks for Master, Slave, and ZooKeeper nodes - name: Install mesos package apt: pkg={{item}} state=present update_cache=yes with_items: - mesos={{ mesos_pkg_version }} sudo: yes when: mesos_install_mode == "master" or mesos_install_mode == "slave" - name: Set ZooKeeper URL # used for leader election amongst masters copy: content: "{{zookeeper_url}}" dest: /etc/mesos/zk mode: 0644 sudo: yes when: mesos_install_mode == "master" or mesos_install_mode == "slave" # Tasks for Master nodes - name: Disable the Mesos Slave service copy: content: "manual" dest: /etc/init/mesos-slave.override mode: 0644 sudo: yes when: mesos_install_mode == "master" - name: Set Mesos Master hostname copy: content: "{{mesos_local_address}}" dest: /etc/mesos-master/hostname mode: 0644 sudo: yes when: mesos_install_mode == "master" - name: Set Mesos Master ip copy: content: "{{mesos_local_address}}" dest: /etc/mesos-master/ip mode: 0644 sudo: yes when: mesos_install_mode == "master" - name: Set Mesos Master Cluster name copy: content: "{{mesos_cluster_name}}" dest: /etc/mesos-master/cluster mode: 0644 sudo: yes when: mesos_install_mode == "master" - name: Set Mesos Master quorum count copy: content: "{{mesos_quorum_count}}" dest: /etc/mesos-master/quorum mode: 0644 sudo: yes when: mesos_install_mode == "master" # Tasks for Slave nodes - name: Disable the Mesos Master service copy: content: "manual" dest: /etc/init/mesos-master.override mode: 0644 sudo: yes when: mesos_install_mode == "slave" - name: Disable the ZooKeeper service copy: content: "manual" dest: /etc/init/zookeeper.override mode: 0644 sudo: yes notify: - Stop zookeeper when: mesos_install_mode == "slave" - name: Set Mesos Slave hostname copy: content: "{{mesos_local_address}}" dest: /etc/mesos-slave/hostname mode: 0644 sudo: yes when: mesos_install_mode == "slave" - name: Set Mesos Slave ip copy: content: "{{mesos_local_address}}" dest: /etc/mesos-slave/ip mode: 0644 sudo: yes when: mesos_install_mode == "slave" - name: Set Mesos Slave ip copy: content: "{{mesos_local_address}}" dest: /etc/mesos-slave/ip mode: 0644 sudo: yes when: mesos_install_mode == "slave" - name: Set Mesos Slave isolation copy: content: "cgroups/cpu,cgroups/mem" dest: /etc/mesos-slave/isolation mode: 0644 sudo: yes notify: - Start mesos-slave when: mesos_install_mode == "slave" # Tasks for ZooKeeper nodes only - name: Create zookeeper config file template: src=zoo.cfg.j2 dest=/etc/zookeeper/conf/zoo.cfg sudo: yes when: mesos_install_mode == "master" - name: Create zookeeper myid file template: src=zoo_id.j2 dest=/etc/zookeeper/conf/myid sudo: yes notify: - Restart zookeeper - Start mesos-master when: mesos_install_mode == "master"这是配置集群中 Mesos 主从机器的标准模板。该文件还指定了安装 ZooKeeper 等组件所需的各种配置。步骤如下:
-
按如下方式创建 ZooKeeper 配置模板:
$ vim mesos/templates/zoo.cfg.j2 -
然后,添加以下内容:
tickTime=2000 dataDir=/var/lib/zookeeper/ clientPort={{ zookeeper_client_port }} initLimit=5 syncLimit=2 {% for host in groups['mesos_masters'] %} server.{{ hostvars[host].zoo_id }}={{ host }}:{{ zookeeper_leader_port }}:{{ zookeeper_election_port }} {% endfor %} -
接下来,输入以下命令:
$ vim mesos/templates/zoo_id.j2 -
最后,添加以下内容:
{{ zoo_id }}
现在,我们可以运行这个剧本,将 Mesos 部署到 hosts 文件中列出的机器上。我们只需要更改 hosts 文件中的 IP 地址,就能在其他机器上部署。
使用 Puppet 部署和配置 Mesos 集群
这一部分将主要介绍如何使用 Puppet 配置管理工具,结合 ZooKeeper 和 Mesos 模块,从以下仓库部署 Mesos 集群:
Puppet 是一款开源的配置管理工具,支持在 Windows、Linux 和 Mac OS 上运行。Puppet Labs 由 Luke Kanies 于 2005 年创立,他也开发了 Puppet。Puppet 是用 Ruby 编写的,并在版本 2.7.0 之前作为 GNU 通用公共许可证(GPL)下的自由软件发布,从那时起采用 Apache License 2.0。通过使用 Puppet,系统管理员可以自动化他们需要定期执行的标准任务。有关 Puppet 的更多信息,请访问以下位置:
代码将按照配置文件和角色模式进行组织,节点数据将通过 Hiera 存储。Hiera 是一个 Puppet 工具,用于执行配置数据的键/值查找。它允许在 Puppet 中对数据进行层次化配置,而这在原生 Puppet 代码中是很难实现的。此外,它作为配置数据和代码的分隔器。
在本模块结束时,你将拥有一个高度可用的 Mesos 集群,包含三个主节点和三个从节点。此外,Marathon 和 Chronos 也将以相同的方式部署。
我们可以结合多个 Puppet 模块来管理 Mesos 和 ZooKeeper。让我们执行以下步骤:
-
首先,创建一个包含以下内容的
Puppetfile:forge 'http://forge.puppetlabs.com' mod 'apt', :git => 'git://github.com/puppetlabs/puppetlabs-apt.git', :ref => '1.7.0' mod 'concat', :git => 'https://github.com/puppetlabs/puppetlabs-concat', :ref => '1.1.2' mod 'datacat', :git => 'https://github.com/richardc/puppet-datacat', :ref => '0.6.1' mod 'java', :git => 'https://github.com/puppetlabs/puppetlabs-java', :ref => '1.2.0' mod 'mesos', :git => 'https://github.com/deric/puppet-mesos', :ref => 'v0.5.2' mod 'stdlib', :git => 'https://github.com/puppetlabs/puppetlabs-stdlib', :ref => '4.5.1' mod 'zookeeper', :git => 'https://github.com/deric/puppet-zookeeper', :ref => 'v0.3.5'现在,我们可以为 Mesos 主节点和从节点编写配置文件和角色模式。在主节点上,还将包括管理 ZooKeeper、Marathon 和 Chronos。
-
为主节点创建以下角色:
class role::mesos::master { include profile::zookeeper include profile::mesos::master # Mesos frameworks include profile::mesos::master::chronos include profile::mesos::master::marathon } -
接下来,为从节点创建以下角色:
class role::mesos::slave { include profile::mesos::slave }现在,我们可以继续创建与之前在角色中列出的 include 语句匹配的可重用配置文件。这些配置文件将包含对 Mesos 和 ZooKeeper 模块的调用以及我们需要管理的任何其他资源。可以将角色视为业务逻辑,而将配置文件视为实际的实现。
-
为 ZooKeeper 创建以下配置文件:
class profile::zookeeper { include ::java class { '::zookeeper': require => Class['java'], } } -
为 Mesos 主节点创建以下配置文件:
class profile::mesos::master { class { '::mesos': repo => 'mesosphere', } class { '::mesos::master': env_var => { 'MESOS_LOG_DIR' => '/var/log/mesos', }, require => Class['profile::zookeeper'], } } -
接下来,为 Mesos 从节点创建以下配置文件:
class profile::mesos::slave { class { '::mesos': repo => 'mesosphere', } class { '::mesos::slave': env_var => { 'MESOS_LOG_DIR' => '/var/log/mesos', }, } }这些是启动 Mesos 集群所需的基本内容。为了管理 Chronos 和 Marathon,还需要包含以下配置文件。
-
按照以下方式创建 Chronos 的配置文件:
class profile::mesos::master::chronos { package { 'chronos': ensure => '2.3.2-0.1.20150207000917.debian77', require => Class['profile::mesos::master'], } service { 'chronos': ensure => running, enable => true, require => Package['chronos'], } } -
现在,通过以下代码创建 Marathon 的配置文件:
class profile::mesos::master::marathon { package { 'marathon': ensure => '0.7.6-1.0', require => Class['profile::mesos::master'], } service { 'marathon': ensure => running, enable => true, require => Package['marathon'], } }到目前为止,角色和配置文件中并没有包含我们将用于设置集群的机器的信息。这些信息将通过 Hiera 提供。主节点的 Hiera 数据大致如下所示:
--- classes: - role::mesos::master mesos::master::options: quorum: '2' mesos::zookeeper: 'zk://master1:2181,master2:2181,master3:2181/mesos' zookeeper::id: 1 zookeeper::servers: ['master1:2888:3888', 'master2:2888:3888', 'master3:2888:3888']由于我们正在设置一个高度可用的集群,因此主节点的名称分别为 master 1、master 2 和 master 3。
-
从节点的 Hiera 数据大致如下所示:
--- classes: - role::mesos::slave mesos::slave::checkpoint: true mesos::zookeeper: 'zk://master1:2181,master2:2181,master3:2181/mesos'
现在,我们可以在每台机器上启动 Puppet 运行,来安装和配置 Mesos、ZooKeeper、Chronos 和 Marathon。
模块的安装与任何 Puppet 模块相同,步骤如下:
$ puppet module install deric-mesos
一旦执行成功,我们可以预期 Mesos 包会被安装,并且 mesos-master 服务会在集群中配置好。
使用 SaltStack 部署和配置 Mesos 集群
SaltStack 平台,或称 Salt,是一个基于 Python 的开源配置管理软件和远程执行引擎。本模块解释了如何使用 SaltStack 在生产环境中安装一个包含 Marathon 和其他一些工具的 Mesos 集群。SaltStack 是 Puppet、Ansible、Chef 等的替代方案。与其他工具类似,它用于自动化在多个服务器上部署和配置软件。SaltStack 架构由一个节点作为 SaltStack 主节点,以及其他作为 minion(从节点)的节点组成。还有两种不同的角色:一个主节点角色用于执行集群操作,一个从节点角色用于运行 Docker 容器。
以下软件包将为主节点角色安装:
-
ZooKeeper
-
Mesos 主节点
-
Marathon
-
Consul
从节点角色将安装以下软件包:
-
Mesos 从节点
-
Docker
-
cAdvisor(用于将指标导出到 Prometheus)
-
Registrator(用于将服务注册到 Consul)
-
Weave(为容器之间提供覆盖网络)
现在,让我们看看这些组件在集群中的样子。下图显示了集群中所有这些组件的连接方式(来源:github.com/Marmelatze/saltstack-mesos-test):
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_03.jpg
SaltStack 安装
我们需要安装 Salt-Master 来协调所有的 Salt-Minions。SaltStack 要求主节点数量为奇数。这些主节点中的一个可以作为 Salt-Master,其余的将成为 minions。让我们按照这里提到的步骤安装 SaltStack:
-
执行以下命令设置主节点和 minion:
$ curl -L https://bootstrap.saltstack.com -o install_salt.sh $ sudo sh install_salt.sh -U -M -P -A localhost #Clone the repository to /srv/salt this is where the configurations are kept. $ sudo git clone https://github.com/Marmelatze/saltstack-mesos-test /srv/salt -
编辑
/etc/salt/master文件并按如下方式更改配置:file_roots: base: - /srv/salt/salt # ... pillar_roots: base: - /srv/salt/pillar现在重启主节点:
$ sudo service salt-master restart -
通过以下代码编辑位于
/etc/salt/minion的 minion 配置文件:# ... mine_interval: 5 mine_functions: network.ip_addrs: interface: eth0 zookeeper: - mine_function: pillar.get - zookeeper -
现在,通过执行以下代码编辑位于
/etc/salt/grains的salt-grains文件:# /etc/salt/grains # Customer-Id this host is assigned to (numeric)- customer_id: 0 # ID of this host. host_id: ID # ID for zookeeper, only needed for masters. zk_id: ID # Available roles are master & slave. Node can use both. roles: - master - slave -
然后,将 ID 替换为从 1 开始的数字值;这个 ID 类似于我们之前使用的 ZooKeeper ID。
现在,通过以下命令重启 minion:
$ sudo service salt-minion restart -
公钥认证用于 minion 与主节点之间的认证。执行以下命令进行认证:
$ sudo salt-key -A -
完成前面的步骤后,我们可以使用以下命令运行 SaltStack:
$ sudo salt '*' state.highstate
如果一切执行成功,则 Mesos 服务将在集群中启动并运行。
使用 Chef 部署和配置 Mesos 集群
Chef 既是一个公司的名字,也是一个配置管理工具的名称,它是用 Ruby 和 Erlang 编写的。Chef 使用纯 Ruby 领域特定语言(DSL)编写系统配置“配方”。本模块将解释如何使用 Chef cookbook 安装和配置 Apache Mesos 的主从节点。Chef 是一个配置管理工具,用于自动化大规模的服务器和软件应用部署。我们假设读者已经熟悉 Chef。以下代码库将作为参考:
github.com/everpeace/cookbook-mesos
本书编写时的 Chef cookbook 版本支持 Ubuntu 和 CentOS 操作系统。CentOS 版本为实验性版本,不建议在生产环境中使用。需要 Ubuntu 14.04 或更高版本才能使用 cgroups 隔离器或 Docker 容器功能。只有 Mesos 0.20.0 及更高版本支持 Docker 容器化。
这个 cookbook 支持两种安装方式——即,从源代码构建 Mesos 和从 Mesosphere 包构建。默认情况下,此 cookbook 是从源代码构建 Mesos 的。可以通过设置以下类型变量在源代码构建和 Mesosphere 之间切换:
node[:mesos][:type]
配方
以下是此 cookbook 用于安装和配置 Mesos 的配方:
-
mesos::default:根据之前讨论的类型变量,这将使用源代码或 Mesosphere 配方安装 Mesos。 -
mesos::build_from_source:这将以通常的方式安装 Mesos——即,从 GitHub 下载 zip 文件,配置,make,并安装。 -
mesos::mesosphere:此变量使用 Mesosphere 的mesos包安装 Mesos。与此同时,我们可以使用以下变量来安装 ZooKeeper 包。node[:mesos][:mesosphere][:with_zookeeper]
-
mesos::master:此配置项用于配置 Mesos 主节点和集群部署的配置文件,并使用mesos-master来启动服务。以下是与这些配置相关的变量:-
node[:mesos][:prefix]/var/mesos/deploy/masters -
node[:mesos][:prefix]/var/mesos/deploy/slaves -
node[:mesos][:prefix]/var/mesos/deploy/mesos-deploy-env.sh -
node[:mesos][:prefix]/var/mesos/deploy/mesos-master-env.sh
-
如果我们选择mesosphere作为构建类型,则默认的 “:” 前缀属性位置将是/usr/local,因为来自 Mesosphere 的软件包将 Mesos 安装在这个目录下。此配方还在以下位置配置了 upstart 文件:
-
/etc/mesos/zk -
/etc/defaults/mesos -
/etc/defaults/mesos-master
配置 mesos-master
mesos-master命令行参数可用于配置node[:mesos][:master]属性。以下是一个示例:
node[:mesos][:master] = {
:port => "5050",
:log_dir => "/var/log/mesos",
:zk => "zk://localhost:2181/mesos",
:cluster => "MesosCluster",
:quorum => "1"
}
mesos-master命令将使用配置中给定的选项进行调用,具体如下:
mesos-master --zk=zk://localhost:2181/mesos --port=5050 --log_dir=/var/log/mesos --cluster=MesosCluster
mesos::slave 命令为 Mesos 从节点提供配置并启动 mesos-slave 实例。我们可以使用以下变量来指向 mesos-slave-env.sh 文件:
node[:mesos][:prefix]/var/mesos/deploy/mesos-slave-env.sh
mesos-slave 的 upstart 配置文件如下:
-
/etc/mesos/zk -
/etc/defaults/mesos -
/etc/defaults/mesos-slave
配置 mesos-slave
mesos-slave 命令行选项可以通过 node[:mesos][:slave] 哈希值进行配置。下面是一个配置示例:
node[:mesos][:slave] = {
:master => "zk://localhost:2181/mesos",
:log_dir => "/var/log/mesos",
:containerizers => "docker,mesos",
:isolation => "cgroups/cpu,cgroups/mem",
:work_dir => "/var/run/work"
}
mesos-slave 命令的调用方式如下:
mesos-slave --master=zk://localhost:2181/mesos --log_dir=/var/log/mesos --containerizers=docker,mesos --isolation=cgroups/cpu,cgroups/mem --work_dir=/var/run/work
现在,让我们来看看如何将这些内容结合在一个 vagrant 文件中并启动一个独立的 Mesos 集群。创建一个包含以下内容的 Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby:
# vagrant plugins required:
# vagrant-berkshelf, vagrant-omnibus, vagrant-hosts
Vagrant.configure("2") do |config|
config.vm.box = "Official Ubuntu 14.04 daily Cloud Image amd64 (Development release, No Guest Additions)"
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
# config.vm.box = "chef/centos-6.5"
# enable plugins
config.berkshelf.enabled = true
config.omnibus.chef_version = :latest
# if you want to use vagrant-cachier,
# please activate below.
config.cache.auto_detect = true
# please customize hostname and private ip configuration if you need it.
config.vm.hostname = "mesos"
private_ip = "192.168.1.10"
config.vm.network :private_network, ip: private_ip
config.vm.provision :hosts do |provisioner|
provisioner.add_host private_ip , [ config.vm.hostname ]
end
# for mesos web UI.
config.vm.network :forwarded_port, guest: 5050, host: 5050
config.vm.provider :virtualbox do |vb|
vb.name = 'cookbook-mesos-sample-source'
# Use VBoxManage to customize the VM. For example, to change memory:
vb.customize ["modifyvm", :id, "--memory", "#{1024*4}"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
config.vm.provision :shell do |s|
s.path = "scripts/populate_sshkey.sh"
s.args = "/home/vagrant vagrant"
end
# mesos-master doesn't create its work_dir.
config.vm.provision :shell, :inline => "mkdir -p /tmp/mesos"
# Mesos master depends on zookeeper emsamble since 0.19.0
# for Ubuntu
config.vm.provision :shell, :inline => "apt-get update && apt-get install -y zookeeper zookeeperd zookeeper-bin"
# For CentOS
# config.vm.provision :shell, :inline => <<-EOH
# rpm -Uvh http://archive.cloudera.com/cdh4/one-click-install/redhat/6/x86_64/cloudera-cdh-4-0.x86_64.rpm
# yum install -y -q curl
# curl -sSfL http://archive.cloudera.com/cdh4/redhat/6/x86_64/cdh/RPM-GPG-KEY-cloudera --output /tmp/cdh.key
# rpm --import /tmp/cdh.key
# yum install -y -q java-1.7.0-openjdk zookeeper zookeeper-server
# service zookeeper-server init
# service zookeeper-server start
# EOH
config.vm.provision :chef_solo do |chef|
# chef.log_level = :debug
chef.add_recipe "mesos"
chef.add_recipe "mesos::master"
chef.add_recipe "mesos::slave"
# You may also specify custom JSON attributes:
chef.json = {
:java => {
'install_flavor' => "openjdk",
'jdk_version' => "7",
},
:maven => {
:version => "3",
"3" => {
:version => "3.0.5"
},
:mavenrc => {
:opts => "-Dmaven.repo.local=$HOME/.m2/repository -Xmx384m -XX:MaxPermSize=192m"
}
},
:mesos => {
:home => "/home/vagrant",
# command line options for mesos-master
:master => {
:zk => "zk://localhost:2181/mesos",
:log_dir => "/var/log/mesos",
:cluster => "MesosCluster",
:quorum => "1"
},
# command line options for mesos-slave
:slave =>{
:master => "zk://localhost:2181/mesos",
:isolation => "posix/cpu,posix/mem",
:log_dir => "/var/log/mesos",
:work_dir => "/var/run/work"
},
# below ip lists are for mesos-[start|stop]-cluster.sh
:master_ips => ["localhost"],
:slave_ips => ["localhost"]
}
}
end
end
现在,键入以下命令以启动一个完全功能的独立 Mesos 集群:
$ vagrant up
使用 Terraform 部署和配置 Mesos 集群
Terraform 是一个基础设施构建、变更和版本控制工具,用于安全高效地处理现有的流行服务以及定制的内部解决方案,属于 HashiCorp 公司并使用 Go 语言编写。在本模块中,我们将首先讨论如何安装 Terraform,然后再讨论如何使用 Terraform 启动一个 Mesos 集群。
安装 Terraform
前往 www.terraform.io/downloads.html,下载适合您平台的版本,并解压,如下所示:
$ wget https://releases.hashicorp.com/terraform/0.6.9/terraform_0.6.9_linux_amd64.zip
$ unzip terraform_0.6.9_linux_amd64.zip
您会注意到,解压后,terraform 压缩包中的文件是一堆二进制文件,类似于以下内容:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_04.jpg
现在,将目录路径添加到 PATH 变量中,这样您就可以从任何目录访问 terraform 命令。
如果一切顺利,当您在终端执行 terraform 命令时,您将看到 terraform 的使用:
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_05.jpg
在 Google Cloud 上使用 Terraform 启动 Mesos 集群
要在 Google Cloud Engine (GCE) 上使用 Terraform 启动 Mesos 集群,您需要一个 JSON 密钥文件进行身份验证。前往 console.developers.google.com,然后通过导航到 Credentials | Service 账户生成一个新的 JSON 密钥。一个文件将被下载,稍后将用于启动虚拟机。
现在,我们可以为 Mesos 集群创建一个 terraform 配置文件。创建一个包含以下内容的 mesos.tf 文件:
module "mesos" {
source = "github.com/ContainerSolutions/terraform-mesos"
account_file = "/path/to/your/downloaded/key.json"
project = "your google project"
region = "europe-west1"
zone = "europe-west1-d"
gce_ssh_user = "user"
gce_ssh_private_key_file = "/path/to/private.key"
name = "mymesoscluster"
masters = "3"
slaves = "5"
network = "10.20.30.0/24"
domain = "example.com"
image = "ubuntu-1404-trusty-v20150316"
mesos_version = "0.22.1"
}
正如我们所看到的,其中一些配置可以用来控制版本,例如:
-
mesos_version:这指定了 Mesos 的版本 -
image:这是 Linux 系统镜像
现在,执行以下命令开始部署:
# Download the modules
$ terraform get
# Create a terraform plan and save it to a file
$ terraform plan -out my.plan -module-depth=1
# Create the cluster
$ terraform apply my.plan
销毁集群
我们可以执行以下命令来销毁集群:
$ terraform destroy
使用 Cloudformation 部署和配置 Mesos 集群
在本模块中,我们将讨论如何使用 Cloudformation 脚本在 Amazon AWS 上启动 Mesos 集群。在开始之前,请确保在希望启动集群的机器上安装并配置了 aws-cli。从以下存储库查看说明来设置 aws-cli:
在设置 aws-cli 后,我们需要的下一步是 cloudformation-zookeeper 模板用于管理由 Exhibitor 管理的 ZooKeeper 集群。
设置 cloudformation-zookeeper
我们首先需要克隆以下存储库,因为它包含了具有参数、描述符和配置值的 JSON 文件:
$ git clone https://github.com/mbabineau/cloudformation-zookeeper
登录 AWS 控制台,并为安全组打开以下端口:
-
SSH 端口:22
-
ZooKeeper 客户端端口:2181
-
Exhibitor HTTP 端口:8181
现在我们可以使用 aws-cli 命令来启动集群:
aws cloudformation create-stack \
--template-body file://cloudformation-zookeeper/zookeeper.json \
--stack-name <stack> \
--capabilities CAPABILITY_IAM \
--parameters \
ParameterKey=KeyName,ParameterValue=<key> \
ParameterKey=ExhibitorS3Bucket,ParameterValue=<bucket> \
ParameterKey=ExhibitorS3Region,ParameterValue=<region> \
ParameterKey=ExhibitorS3Prefix,ParameterValue=<cluster_name> \
ParameterKey=VpcId,ParameterValue=<vpc_id> \
ParameterKey=Subnets,ParameterValue='<subnet_id_1>\,<subnet_id_2>' \
ParameterKey=AdminSecurityGroup,ParameterValue=<sg_id>
使用 cloudformation-mesos
你可以从以下网址克隆项目存储库:
$ git clone https://github.com/mbabineau/cloudformation-mesos
该项目主要包括三个 JSON 格式的模板,定义了参数、配置和描述,如下所示:
-
mesos-master.json:用于启动一组运行 Marathon 的 Mesos 主节点的模板,在自动扩展组中运行。 -
mesos-slave.json:与前述相似,这会在自动扩展组中启动一组 Mesos 从节点。 -
mesos.json:此文件从先前列出的对应模板创建mesos-master和mesos-slave两个堆栈。这是用于启动 Mesos 集群的通用模板。
master.json 中列出了一些可配置属性:
"MasterInstanceCount" : {
"Description" : "Number of master nodes to launch",
"Type" : "Number",
"Default" : "1"
},
"MasterQuorumCount" : {
"Description" : "Number of masters needed for Mesos replicated log registry quorum (should be ceiling(<MasterInstanceCount>/2))",
"Type" : "Number",
"Default" : "1"
},
MasterInstanceCount 和 MasterQuorumCount 控制集群中所需的主节点数量。查看以下代码:
"SlaveInstanceCount" : {
"Description" : "Number of slave nodes to launch",
"Type" : "Number",
"Default" : "1"
},
同样,SlaveInstanceCount 用于控制集群中从节点实例的数量。
Cloudformation 更新自动扩展组,Mesos 通过增加和减少节点来透明地处理扩展。详见:
"SlaveInstanceType" : {
"Description" : "EC2 instance type",
"Type" : "String",
"Default" : "t2.micro",
"AllowedValues" : ["t2.micro", "t2.small", "t2.medium",
"m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge","c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge","r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge","i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge","hs1.8xlarge", "g2.2xlarge"],
"ConstraintDescription" : "must be a valid, HVM-compatible EC2 instance type."
},
我们还可以使用 InstanceType 配置属性来控制 AWS 云中主节点 (MasterInstanceType) 和从节点 (SlaveInstanceType) 的机器大小。
再次,在我们之前创建的安全组中,为 Mesos 通信打开以下端口:
-
Mesos 主节点端口:5050
-
Marathon 端口:8080
在 mesos-master.json 和 mesos-slave.json 文件中配置值后,我们可以使用以下命令将这些文件上传到 S3:
$ aws s3 cp mesos-master.json s3://cloudformationbucket/
$ aws s3 cp mesos-slave.json s3://cloudformationbucket/
现在我们可以使用 aws-cli 命令来启动我们的 Mesos 集群:
aws cloudformation create-stack \
--template-body file://mesos.json \
--stack-name <stack> \
--capabilities CAPABILITY_IAM \
--parameters \
ParameterKey=KeyName,ParameterValue=<key> \
ParameterKey=ExhibitorDiscoveryUrl,ParameterValue=<url> \
ParameterKey=ZkClientSecurityGroup,ParameterValue=<sg_id> \
ParameterKey=VpcId,ParameterValue=<vpc_id> \
ParameterKey=Subnets,ParameterValue='<subnet_id_1>\,<subnet_id_2>' \
ParameterKey=AdminSecurityGroup,ParameterValue=<sg_id> \
ParameterKey=MesosMasterTemplateUrl,ParameterValue=https://s3.amazonaws.com/cloudformationbucket/mesos-master.json \
ParameterKey=MesosSlaveTemplateUrl,ParameterValue=https://s3.amazonaws.com/cloudformationbucket/mesos-slave.json
使用 Playa Mesos 创建测试环境
使用 Playa Mesos 可快速创建 Apache Mesos 测试环境。你可以从以下网址查看官方存储库:
github.com/mesosphere/playa-mesos。
在使用此项目之前,请确保在您的环境中安装并配置了 VirtualBox、Vagrant 和包含预装 Mesos 和 Marathon 的 Ubuntu 镜像。
安装
按照以下说明开始使用 Playa Mesos
-
安装 VirtualBox:您可以访问
www.virtualbox.org/wiki/Downloads下载并安装适合您环境的版本。 -
安装 Vagrant:您可以参考 第四章 中 安装 Aurora 部分所描述的方法来开始使用 Vagrant。
-
Playa:您可以使用以下命令克隆仓库:
$ git clone https://github.com/mesosphere/playa-mesos # Make sure the tests are passed $ cd playa-mesos $ bin/test # Start the environment $ vagrant up
如果一切顺利,我们可以通过将浏览器指向 10.141.141.10:5050 来查看 Mesos master Web UI,并通过 10.141.141.10:8080 查看 Marathon Web UI。
一旦机器启动,我们可以使用 ssh 登录到机器,命令如下:
$ vagrant ssh
我们还可以使用以下命令来停止并终止测试环境:
# Halting the machine
$ vagrant halt
#Destroying the VM
$ vagrant destroy
除此之外,如果您希望稍微调整配置,您可以通过编辑位于 playa-mesos 仓库根目录的 config.json 文件来进行。
我们可以在 config.json 文件中使用以下配置属性:
-
platform:这是虚拟化平台。我们将使用 VirtualBox,虽然 VMware Fusion 和 VMware Workstation 也可以使用。 -
box_name:这是 Vagrant 实例的名称。 -
base_url:这是 Vagrant 镜像存储的基本 URL。 -
ip_address:这是虚拟机的私有网络 IP 地址。 -
mesos_release:此参数是可选的,指定 Mesos 的版本。它应为apt-cache policy mesos返回的完整字符串。例如:0.22.1-1.0.ubuntu1404。 -
vm_ram:这是分配给 Vagrant 虚拟机的内存。 -
vm_cpus:这是分配给 Vagrant 虚拟机的核心数量。
我们可以通过将所有这些配置参数放在一起,创建一个示例 config.json 文件,文件内容如下:
{
"platform": "virtualbox",
"box_name": "playa_mesos_ubuntu_14.04_201601041324",
"base_url": "http://downloads.mesosphere.io/playa-mesos",
"ip_address": "10.141.141.10",
"vm_ram": "2048",
"vm_cpus": "2"
}
如您所见,我们分配了 2040 MB 的内存和两个核心,且机器将运行在 10.141.141.10 的 IP 地址上。
使用 Nagios 监控 Mesos 集群
监控是保持基础设施正常运行的关键部分。Mesos 与现有的监控解决方案集成良好,并且有适用于大多数监控解决方案的插件,例如 Nagios。本模块将指导您如何在集群上安装 Nagios,并启用监控功能,在集群出现故障时通过电子邮件向您发送警报。
安装 Nagios 4
在安装 Nagios 之前,我们需要做的第一件事是为 Nagios 进程添加一个 Nagios 用户,该进程可以运行并发送警报。我们可以通过执行以下命令来创建一个新用户和一个新用户组:
$ sudo useradd nagios
$ sudo groupadd nagcmd
$ sudo usermod -a -G nagcmd nagios
在这里,我们创建了一个用户 Nagios 和一个用户组nagcmd,该组分配给 Nagios 用户,如前面列出的第三个命令所示。
现在,使用以下命令安装依赖包:
$ sudo apt-get install build-essential libgd2-xpm-dev openssl libssl-dev xinetd apache2-utils unzip
安装依赖项并添加用户后,我们可以开始通过执行以下命令下载并安装nagios:
#Download the nagios archive.
$ wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.1.1.tar.gz
# Extract the archive.
$ tar xvf nagios-*.tar.gz
# Change the working directory to nagios
$ cd nagios*
# Configure and build nagios
$ ./configure --with-nagios-group=nagios --with-command-group=nagcmd --with-mail=/usr/sbin/sendmail
$ make all
# Install nagios, init scripts and sample configuration file
$ sudo make install
$ sudo make install-commandmode
$ sudo make install-init
$ sudo make install-config
$ sudo /usr/bin/install -c -m 644 sample-config/httpd.conf /etc/apache2/sites-available/nagios.conf
一旦nagios安装完成,我们可以通过下载并构建来安装nagios插件,执行以下命令:
$ wget http://nagios-plugins.org/download/nagios-plugins-2.1.1.tar.gz
$ tar xvf nagios-plugins-*.tar.gz
$ cd nagios-plugins-*
$ ./configure --with-nagios-user=nagios --with-nagios-group=nagios --with-openssl
$ make
$ sudo make install
插件安装完成后,我们可以安装NRPE(Nagios 远程插件执行器)以从远程机器获取状态更新。可以通过执行以下命令进行安装:
$ wget http://downloads.sourceforge.net/project/nagios/nrpe-2.x/nrpe-2.15/nrpe-2.15.tar.gz
$ tar xf nrpe*.tar.gz
$ cd nrpe*
$ ./configure --enable-command-args --with-nagios-user=nagios --with-nagios-group=nagios --with-ssl=/usr/bin/openssl --with-ssl-lib=/usr/lib/x86_64-linux-gnu
$ make all
$ sudo make install
$ sudo make install-xinetd
$ sudo make install-daemon-config
出于安全原因,请编辑/etc/xinetd.d/nrpe文件,内容如下:
only_from = 127.0.0.1 10.132.224.168
用我们的nagios服务器 IP 地址替换文件中的 IP 地址,以确保只有我们的nagios服务器可以进行远程调用。完成后,保存文件并退出,然后执行以下命令重启xintend服务:
$ sudo service xinetd restart
现在nagios已安装,我们可以通过编辑以下文件来配置接收通知的联系电子邮件地址:
$ sudo vi /usr/local/nagios/etc/objects/contacts.cfg
找到并将以下行替换为您自己的电子邮件地址:
email nagios@localhost ; << ** Change this to your email address **
通过执行以下命令,添加一个用户到nagios,以便我们可以从浏览器登录并查看活动。在这里,我们使用nagiosadmin作为用户名和密码,如下所示:
$ sudo htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin
现在,通过执行以下命令重启nagios服务:
$ sudo service nagios restart
现在,我们可以通过从浏览器访问以下 URL 登录nagios管理面板:
http://MachineIP/nagios
MachineIP是我们安装了nagios的机器的 IP 地址,它会提示您输入认证表单,您可以在其中输入用户名和密码nagiosadmin。
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_06.jpg
认证通过后,您将进入 Nagios 主页。要查看 Nagios 监控的主机,点击左侧的Hosts链接,如下图所示(来源:www.digitalocean.com/community/tutorials/how-to-install-nagios-4-and-monitor-your-servers-on-ubuntu-14-04):
https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_07.jpg
接下来,我们将讨论如何使用 NRPE 监控 Mesos 集群中的节点。
接下来的部分将添加一台机器到 Nagios 进行监控,我们可以重复相同的步骤添加需要的任意多台机器。目前,我们选择监控 Mesos 主节点,如果某个驱动器的磁盘使用量超过给定值,它将触发电子邮件。
现在,在主机上,通过以下命令安装 Nagios 插件和nrpe-server:
$ sudo apt-get install nagios-plugins nagios-nrpe-server
如前所述,为了安全原因,请编辑/etc/nagios/nrpe.cfg文件,并将nagios服务器的 IP 地址放入allowed_hosts属性下进行通信。
现在,使用以下命令编辑 nrpe 配置文件,设置监控磁盘使用情况:
$ sudo vi /etc/nagios/nrpe.cfg
然后,添加以下内容:
server_address=client_private_IP
allowed_hosts=nagios_server_private_IP
command[check_hda1]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /dev/vda
在这里,server_address 是机器的 IP 地址,allowed_hosts 是 nagios 服务器的地址,命令是实际用于拉取磁盘使用情况的命令。我们使用了 nagios 自带的 check_disk 插件,并将参数传递给命令,分别为 -w 20% 和 -c 10%。每当服务器的磁盘使用超过 20% 时,Nagios 会触发电子邮件警报。
编辑文件后,通过以下命令重启nrpe服务器:
$ sudo service nagios-nrpe-server restart
既然我们已经配置了 Mesos 主节点来检查磁盘使用情况,我们还需要将这个 Mesos 主节点添加到 nagios 服务器,以便它可以持续检查磁盘使用情况,并在超过配额时提醒管理员。
在 nagios 服务器上添加一个新的配置文件进行监控,我们可以将文件添加到 /usr/local/nagios/etc/servers/,如下所示:
$ sudo vi /usr/local/nagios/etc/servers/mesos-master.cfg
然后,添加以下内容:
define host {
use linux-server
host_name mesos-master
alias Mesos master server
address 10.132.234.52
max_check_attempts 5
check_period 24x7
notification_interval 30
notification_period 24x7
}
该配置将持续监控 Mesos 主机,检查其是否仍在运行。如果 Mesos 主机宕机,管理员(或邮件列表中指定的其他人员)将收到电子邮件通知。
我们还可以通过添加以下服务来启用网络使用情况检查:
define service {
use generic-service
host_name mesos-master
service_description PING
check_command check_ping!100.0,20%!500.0,60%
}
一旦我们为新主机设置了配置,就需要通过执行以下命令来重启nagios:
$ sudo service nagios reload
我们还可以通过遵循之前列出的步骤,为从属节点创建新的配置文件。
使用 Satellite 监控 Mesos 集群
Satellite 是另一个用于监控 Mesos 的工具,Satellite 项目由 Two Sigma Investments 维护,使用 Clojure 编写。Satellite 主实例监控 Mesos 主节点,并通过 Satellite 从属节点接收来自 Mesos 从属节点的监控信息。对于每个 Mesos 主节点和从属节点,都会有一个 Satellite 主进程和从进程,satellite-slave 进程将向集群中的所有 satellite-master 发送一种类型的消息。
集群的汇总统计信息,如资源利用率、丢失的任务数量以及与主节点相关的事件(例如当前有多少个领导节点处于活动状态等),通常是被拉取的。Satellite 还提供了一个表现状态转移(REST)接口,以与 Mesos 主节点白名单进行交互。白名单是包含主节点将考虑发送任务的主机列表的文本文件。它还提供了一个 REST 接口,用于访问缓存的 Mesos 任务元数据。Satellite 本身从不缓存这些信息,只提供一个接口来检索缓存的信息(如果已缓存)。这是一个可选功能,但如果我们在 Mesos 内部持久化了任务元数据,它将非常有用。
Satellite 添加了两个额外的概念性白名单:
-
托管白名单:这些是自动输入的主机
-
手动白名单:如果某个主机出现在此白名单中,那么它的状态将覆盖前面讨论的受管白名单中的状态。这些是接受
PUT和DELETE请求的 REST 端点。
在间隔时间内,合并操作实际上会将这两者合并到白名单文件中。
卫星安装
卫星需要安装在所有 Mesos 集群中的机器上。我们需要在 Mesos 主机上安装 satellite-master,并在 Mesos 从机上安装 satellite-slave。运行以下代码:
# Install lein on all the machines
$ wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
$ chmod +x lein
$ export PATH=$PATH:/path/to/lein
# Clone the satellite repository
$ git clone https://github.com/twosigma/satellite
# Compile the satellite-master jar
$ cd satellite/satellite-master
$ lein release-jar
上述命令将在目标目录中创建一个 jar 文件,我们可以将其复制到所有 Mesos 主机上。
通过传递配置执行以下命令,将在机器上运行卫星进程:
$ java -jar ./target/satellite.jar ./config/satellite-config.clj
常见的部署问题及解决方案
本模块包含了一些在安装或设置本章中描述的工具和模块时常遇到的常见问题:
-
对于 Ansible python-setup 工具,查看以下截图:https://github.com/OpenDocCN/freelearn-linux-pt4-zh/raw/master/docs/ms-mesos/img/B05186_05_08.jpg
如果你的 Ansible 安装显示上述消息,请执行以下命令来解决该问题:
$ sudo pip install setuptools -
SSH 运行在不同的端口上,
nagios显示连接被拒绝错误。如果你将
ssh服务器运行在不同的端口上,你将遇到以下异常:SERVICE ALERT: localhost;SSH;CRITICAL;HARD;4;Connection refused通过编辑
/etc/nagios/conf.d/services_nagios.cfg文件中的以下行可以解决此问题:# check that ssh services are running define service { hostgroup_name ssh-servers service_description SSH check_command check_ssh_port!6666!server use generic-service notification_interval 0 ; set > 0 if you want to be renotified在这里,我们使用
6666作为ssh端口,而不是22,以避免出现错误信息。 -
Chef 无法解压软件包。
有时,Chef 设置无法检索软件包并给出以下错误堆栈:
==> master1: [2015-12-25T22:28:39+00:00] INFO: Running queued delayed notifications before re-raising exception ==> master1: [2015-12-25T22:28:39+00:00] ERROR: Running exception handlers ==> master1: [2015-12-25T22:28:39+00:00] ERROR: Exception handlers complete ==> master1: [2015-12-25T22:28:39+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out ==> master1: [2015-12-25T22:28:39+00:00] ERROR: packageunzip had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '100' ==> master1: ---- Begin output of apt-get -q -y install unzip=6.0-8ubuntu2 ---- ==> master1: STDOUT: Reading package lists... ==> master1: Building dependency tree... ==> master1: Reading state information... ==> master1: The following packages were automatically installed and are no longer required: ==> master1: erubis ohai ruby-bunny ruby-erubis ruby-highline ruby-i18n ruby-ipaddress ==> master1: ruby-mime-types ruby-mixlib-authentication ruby-mixlib-cli ==> master1: ruby-mixlib-config ruby-mixlib-log ruby-mixlib-shellout ruby-moneta ==> master1: ruby-net-ssh ruby-net-ssh-gateway ruby-net-ssh-multi ruby-polyglot ==> master1: ruby-rest-client ruby-sigar ruby-systemu ruby-treetop ruby-uuidtools ==> master1: ruby-yajl ==> master1: Use 'apt-get autoremove' to remove them. ==> master1: Suggested packages: ==> master1: zip ==> master1: The following NEW packages will be installed: ==> master1: unzip ==> master1: 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. ==> master1: Need to get 192 kB of archives. ==> master1: After this operation, 394 kB of additional disk space will be used. ==> master1: WARNING: The following packages cannot be authenticated! ==> master1: unzip ==> master1: STDERR: E: There are problems and -y was used without --force-yes ==> master1: ---- End output of apt-get -q -y install unzip=6.0-8ubuntu2 ---- ==> master1: Ran apt-get -q -y install unzip=6.0-8ubuntu2 returned 100 ==> master1: [2015-12-25T22:28:40+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1) Chef never successfully completed! Any errors should be visible in the output above. Please fix your recipes so that they properly complete.当你的 apt 密钥过期时,可能会出现此错误。要解决此问题,你需要通过执行以下命令来更新密钥:
$ sudo apt-key update -
ZooKeeper 抛出错误 “没有主节点当前正在领导”。
这是一个已知的 ZooKeeper 错误,源于 ZooKeeper 配置文件的错误配置。我们可以通过正确编辑位于
/etc/zookeeper/conf/zoo.cfg的 ZooKeeper 配置文件来解决此错误。将以下属性添加到文件中列出的服务器 IP 旁边:tickTime=2000 dataDir=/var/zookeeper clientPort=2181
总结
阅读完本章后,你现在应该能够使用任何标准部署工具,在分布式基础设施上启动并配置 Mesos 集群。你还将能够理解 Mesos 支持的各种安全性、多租户性和维护功能,并学习如何将它们实现到生产级别的设置中。
在下一章,我们将更详细地探索 Mesos 框架。我们将讨论框架的各种特性、将现有框架移植到 Mesos 上的过程,并了解如何在 Mesos 上开发自定义框架来解决特定的应用需求。
1167

被折叠的 条评论
为什么被折叠?



