Apache Mesos(7)-Marathon的高级应用
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
前面我们使用Marathon部署了一个简单的命令行程序和一个基于Docker容器的应用,现在我们来探索一下Marathon提供的其它功能。这些功能包括:程序的健康检查,程序组的应用等。
程序的健康检查
对于任何的Marathon应用程序,都可以实现健康检查的功能。对于一个程序的实例,有三种方法来实现:
- HTTP-发送一个第七层的HTTP请求到特定的端口和路径。
- TCP-尝试打开一个到特定端口的TCP socket连接。
- COMMAND-运行任意一个命令来判断健康状态(目前与运行在容器中的任务不兼容)。
另外,您可以指定intervalSeconds,gracePeriodSeconds,timeoutSeconds,maxConsecutiveFailures等参数来配置健康状态监控。
健康检查参数选项可以参考http://mesosphere.github.io/marathon/docs/health-checks.html。
我们来看一个实际的例子。在上一篇时,我们部署了一个基于docker的web服务器,我们继续使用这个配置,在原来的配置基础上加上健康检查的配置,如下:
这个例子指定了使用HTTP协议(代码清单第25行)来查询指定的路径(代码清单第23行)。关于端口的指定,使用了portIndex项(代码清单第24行)而取代重复在程序中的端口定义(代码清单第15、16行),默认情况下此项的值为0,指定的是portMappings数组的第一个值。gracePeriodSeconds(代码清单第26行)指定了在程序刚刚启动多长时间内,忽略健康检查的结果。intervalSeconds(代码清单第27行)指定两次检查的间隔时间。timeoutSeconds(代码清单第28行)指定健康检查的超时时间。maxConsecutiveFailures(代码清单第29行)指定了健康检查连续失败几次后,应该结束此不健康的程序。
通过Marathon框架部署程序,程序相关端口的配置的详细信息请参考http://mesosphere.github.io/marathon/docs/ports.html。
创建应用程序组
理解应用程序组
在现实中,应用程序通常是由多个服务或Docker程序组成的。前面我们已经通过Web或JSON部署了单个的Marathon应用程序,现在我们来看看怎样通过程序组来定义应用程序及其依赖的服务。
应用程序组可以包括应用程序或者其它的程序组。而且,这些程序或程序组可以依赖组中的其它程序或程序组。
通过程序组,可以使用一个JSON文档来描述一个非常复杂的应用,这个应用内部包含各种依赖关系。通过它可以非常容易得定义依赖,部署更新,缩放单个应用程序实例或者整个程序组实例。
实际部署应用程序组
下面我们实际部署一个示例程序来看看程序组的使用。这个程序是一个基于Ruby的web程序(使用Sinatra框架),它允许用户操作Redis数据库中的键/值对。这个程序组运行了web app的三个实例和Redis数据库的一个实例,并且使用marathon-lb进行服务发现,处理服务间的通信。如下图:
在实际部署前,需要配置好marathon-lb的服务发现机制(参考)。在168的机器上执行:
docker run -e PORTS=9090 -d --net=host --name internal-marathon-lb mesosphere/marathon-lb sse -m http://192.168.71.167:8080 -m http://192.168.71.168:8080 -m http://192.168.71.169:8080 --health-check --group internal
这样此节点上部署了一个内部的负载均衡器,它可以用来进行端口映射,将动态部署到slave上未知端口的应用映射到固定节点的固定端口上。
另外需要注意的是,此程序并没有做成Docker镜像。为了使程序在slave节点上成功运行,每个slave节点必须安装了Ruby(版本1.9.3+)和Bundler。从这里就可以看出,Docker使程序及依赖库的部署更加简单,一个镜像就可以包括程序及其依赖,不用系统管理员手动进行应用程序环境的配置。
下面的代码清单将keys-and-values的程序组建立了起来:
使用如下命令进行应用组的部署:
curl -H 'Content-Type: application/json' -d @keys-and-values.json http://192.168.71.167:8080/v2/groups
上面的代码清单,我们看几个关键的地方:
第9-11行指定了程序的下载地址,下载完成后Marathon自动在其Sandbox目录中解压。
第12行是怎样运行该程序的命令。
第13-17行指定了程序运行需要的相关的环境变量。由于我们使用了Marathon-lb的服务发现机制,便可以指定固定节点的固定端口来连接Redis的服务。PORT环境变量是web服务器监听的端口,默认为8080。我们的实验环境master、slave以及Marathon都部署到同一机器上,8080已经被Marathon占用,所以我们指定PORT到一个未占用的端口。
第18-20行指定app程序依赖于db程序。
第33-40行指定了将容器暴露的6379端口映射到该节点主机上的任意端口(hostPort:0)。服务端口便是通过Marathon-lb的服务发现机制暴露出的端口,其它程序和服务可以连接到Marathon-lb所在机器的该端口来使用这个服务。
第50-52行也比较关键,只有指定了”HAPROXY_GROUP”:”internal”标签,才能将此服务映射到主机的动态的端口,绑定到上面指定的服务端口9000上。
服务部署完成后,可以通过slave节点的11111端口来访问web页面。
Marathon的端口映射的更多信息可以参考官方文档。
部署Docker应用程序组
上面的例子部署了一个由命令行的程序和Docker容器组成的程序组。我们再来部署一个全部都是由Docker容器组成的程序组。我们先来添加一个外部的负载均衡器,在167的机器上执行:
docker run -e PORTS=9090 -d --privileged --net=host --name external-marathon-lb mesosphere/marathon-lb sse -m http://192.168.71.167:8080 -m http://192.168.71.168:8080 -m http://192.168.71.169:8080 --health-check --group external
内部负载均衡器还用上面那个例子的(在机器168上),部署的json代码清单如下:
上面的代码我们不再详细解释,要注意的一点是在第30行,启用了外部负载均衡器的虚拟主机配置。这样便可以通过在hosts表中加入一行记录192.168.71.167 test-worldpress.example.com
,便可以通过域名访问虚拟主机,并且Marathon-lb通过HAProxy对web-app的三个实例进行了负载均衡。
Marathon框架还有一些其它功能,例如:可以指定约束条件让程序部署到特定的节点上,使用授权和访问控制,以及使用Volumes进行持久化(该功能处于beta阶段),可以参考官方文档。