最近在研究使用Mesos,对marathon-lb和mesos-dns等诸多工具,只是停留在知道和会用的阶段,特别是对于基于marathon-lb的HAProxy的应用分组和使用更是一头雾水。现在资料也少,看了官网上的这篇文章觉得讲得还算是全面。兄弟英文水平差,先用Google翻译了一下,然后再梳理整理,同时,加上了一些自己的理解的说明。因为每个人的经历和经验都不同,以下这些东西对于有些人可能很难对于有些人可能很简单,所以不当之处还请大家多多见谅。欢迎讨论和拍砖。
这是服务发现和负载平衡的两部分系列文章的第二篇。
在上一篇文章中,我们讨论了marathon-lb的基本知识。在这篇文章中,我们将探讨一些更高级的功能。
marathon-lb的工作原理是自动生成用于HAProxy的配置,然后根据需要重装HAProxy的。marathon-lb是通过marathon REST api,根据可用的application数据来生成HAProxy的配置。它也可以订阅Marathon Event Bus进行实时更新。当一个应用程序启动,停止,重新定位,或健康状况有任何的变化,marathon-lb会自动重新生成HAProxy的配置并重新加载HAProxy的。
marathon-lb具有用于指定任意HAProxy的配置参数的模板功能。模板可以进行全局设置(适用于所有应用程序),或者每个应用程序的基础上使用标签进行设置。我们来演示如何指定自己的全局模板的例子。以下是我们将使用模板:
global
daemon
log /dev/log local0
log /dev/log local1 notice
maxconn 4096
tune.ssl.default-dh-param 2048
defaults
log global
retries 3
maxconn 3000
timeout connect 5s
timeout client 30s
timeout server 30s
option redispatch
listen stats
bind 0.0.0.0:9090
balance
mode http
stats enable
monitor-uri /_haproxy_health_check
在上面的例子中,我们已经将以下这些设置的默认值进行了修改:maxconn,timeout client,和timeout server。接下来,创建一个名为HAPROXY_HEAD的文件,将以上配置信息写入这个文件中,最后将其放在一个名为templates目录下。然后,把整个目录打tar或zip文件。下面是你可以用来做一个方便的脚本。
获取你创建的文件(templates.tgz如果你使用的脚本),并让这个文件可以通过HTTP进行访问。如果你想使用示例,请使用此URI:https://downloads.mesosphere.com/marathon/marathon-lb/templates.tgz
接下来,将模版url信息保存至options.json,我们将通过这个文件来增加marathon-lb配置:
{
"marathon-lb":{
"template-url":"https://downloads.mesosphere.com/marathon/marathon-lb/templates.tgz"
}
}
建立一个新的marathon-lb:
$ dcos package install --options=options.json marathon-lb
我们定制的marathon-lb HAProxy的实例基于该新模板运行。完整的模板列表可以在这里找到。
下一步是什么?如何指定每个应用程序模板?下面是使用我们的忠实nginx的一个例子:
{
"id": "nginx-external",
"container": {
"type": "DOCKER",
"docker": {
"image": "nginx:1.7.7",
"network": "BRIDGE",
"portMappings": [
{ "hostPort": 0, "containerPort": 80, "servicePort": 10000 }
],
"forcePullImage":true
}
},
"instances": 1,
"cpus": 0.1,
"mem": 65,
"healthChecks": [{
"protocol": "HTTP",
"path": "/",
"portIndex": 0,
"timeoutSeconds": 10,
"gracePeriodSeconds": 10,
"intervalSeconds": 2,
"maxConsecutiveFailures": 10
}],
"labels":{
"HAPROXY_GROUP":"external",
"HAPROXY_0_BACKEND_HTTP_OPTIONS":" option forwardfor\n no option http-keep-alive\n http-request set-header X-Forwarded-Port %[dst_port]\n http-request add-header X-Forwarded-Proto https if { ssl_fc }\n"
}
}
在上面的例子中,我们修改了默认模板,禁用 HTTP keep-alive。虽然这是一个人为的例子,可能有你需要重写每个应用程序的某些默认情况。
其他选项可能要指定包括sticky option, redirecting to HTTPS, 或 specifying a vhost。
"labels":{
"HAPROXY_0_STICKY":true,
"HAPROXY_0_REDIRECT_TO_HTTPS":true,
"HAPROXY_0_VHOST":"nginx.mesosphere.com"
}
SSL支持
marathon-lb支持SSL,并且可以指定每个前端多个SSL证书。通过–ssl-certs命令行参数,就可以将额外的SSL证书包含进来。你可以通过设置HAPROXY_SSL_CERT环境变量,指定注入自己的SSL证书到marathon-lb的配置中。
如果不指定SSL证书,marathon-lb在启动时将产生自签名的证书。如果你使用多个SSL证书,你可以通过指定选择每个应用服务端口的SSL证书HAPROXY_{n}_SSL_CERT参数,它对应于指定的SSL证书的文件路径。例如:
"labels":{
"HAPROXY_0_VHOST":"nginx.mesosphere.com",
"HAPROXY_0_SSL_CERT":"/etc/ssl/certs/nginx.mesosphere.com"
}
该SSL证书必须预先加载到marathon-lb加载它们容器(您可以通过构建marathon-lb的自己的镜像,而不是使用中间层提供的镜像做到这一点)。如果没有提供一个SSL证书,自签名的证书将在启动时产生的。
使用HAProxy的指标
HAProxy的统计报告可以用于监测健康状况,性能,甚至进行调度决策。HAProxy的数据包括各种规格的计数器和1秒的速率
在本文中,我们将使用HAProxy的数据实现一个有趣的应用程序:一个演示马拉松应用程序自动缩放的实现。
原理很简单:对于给定的应用程序,我们可以测量其每秒的请求对于一个给定的资源方面的性能。如果该应用是无状态的水平缩放,我们就可以在每秒平均N个间隔的频率下,按比例的缩放应用实例的数目。自动缩放脚本轮询HAProxy的统计,基于传入的请求自动缩放应用实例。
该脚本不会做任何事情聪明,它只是简单的获取当前的RPS(每秒请求数),并用每个应用程序实例目标RPS除以这个数字。该级分的结果是所需的应用实例的数目(或更确切地说,该级分的上限是必需的实例)。
为了演示自动缩放,我们将用3个独立的marathon应用程序:
- marathon-lb-autoscale - 可通过marathon REST api监控HAProxy和缩放应用的脚本。
- nginx - 我们的演示应用程序
- siege - 生成HTTP请求的工具
注:Siege是一个压力测试和评测工具,设计用于WEB开发这评估应用在压力下的承受能力:可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行。
让我们首先运行marathon-lb-autoscale。该应用程序的JSON定义可以在这里找到。保存文件,并启动它的marathon:
$ wget https://gist.githubusercontent.com/brndnmtthws/2ca7e10b985b2ce9f8ee/raw/66cbcbe171afc95f8ef49b70034f2842bfdb0aca/marathon-lb-autoscale.json
$ dcos marathon app add marathon-lb-autoscale.json
让我们来看看定义文件:
"args":[
"--marathon", "http://leader.mesos:8080",
"--haproxy", "http://marathon-lb.marathon.mesos:9090",
"--target-rps", "100",
"--apps", "nginx_10000"
],
注意:如果没有外部(external)marathon-lb在运行的情况下,可以通过命令启动它dcos package install marathon-lb。
上面,我们传递两个重要参数:–target-rps告诉marathon-lb-autoscale我们的RPS目标是什么,–apps的值是一个逗号分隔的多值列表,列表中的每个值是用“_”连接的marathon app 名和服务监听端口的字符串。如果配置成每个应用程序可以向LB暴露多个服务端口,marathon-lb-autoscale将扩展应用程序,以满足所需的实例数的最大公约数。
接下来,我们将启动我们的nginx测试实例。该应用程序的JSON定义文件可以在这里找到。保存文件,并启动:
$ wget https://gist.githubusercontent.com/brndnmtthws/84d0ab8ac057aaacba05/raw/d028fa9477d30b723b140065748e43f8fd974a84/nginx.json
$ dcos marathon app add nginx.json
最后,让我们进行压力测试,用于生成HTTP请求。该应用程序的JSON定义文件可以在这里找到。保存文件,并启动
$ wget https://gist.githubusercontent.com/brndnmtthws/fe3fb0c13c19a96c362e/raw/32280a39e1a8a6fe2286d746b0c07329fedcb722/siege.json
$ dcos marathon app add siege.json
现在,如果您检查HAProxy的状态页面,你应该看到气球命中nginx实例:
在“Session rate”部分中,你可以看到我们目前得到每秒约54请求。
下一步,缩放压力测试应用程序,使我们产生了一堆的HTTP请求:
$ dcos marathon app update /siege instances=15
现在,等待几分钟,去喝杯咖啡,茶,松饼,牛排或任何你可能做的休闲事情。过几分钟你就会发现nginx的应用程序已经被自动扩展到可以支撑当前服务流量的数目。
接下来,尝试修改marathon-lb-autoscale参数(这是实验记录在这里)。试着改变区间,样本数和其他值,直到达到预期的效果。默认值是相当保守的,这可能会或可能不符合您的期望。它建议您目标RPS安全系数是50%。例如,如果您测量您的应用程序SLA是:在1个CPU和1GiB内存的情况下能满足1500 RPS,那么你可能希望将目标RPS设置为1000。
注:
1)我的理解是RPS安全系数,是marathon-lb根据系统运行参数生成的预判值,想要保证服务在这个情况下稳定运行,就要将SLA的值进行等比例的下调。
2)SLA是关于网络服务供应商和客户间的一份合同,其中定义了服务类型、服务质量和客户付款等术语。SLA概念已被大量企业所采纳,作为公司 IT 部门的内部服务。大型企业的 IT 部门都规范了一套服务等级协议,以衡量、确认他们的客户(企业其他部门的用户)服务,有时也与外部网络供应商提供的服务进行比较。
就这样!在到达终点的祝贺。
参考资料:
[1]: https://mesosphere.com/blog/2015/12/13/service-discovery-and-load-balancing-with-dcos-and-marathon-lb-part-2/
[2]: http://baike.baidu.com/link?url=flgM8lI4eJ6p0AP4frcu84-eSmj-gBppeQqpoE6XeUizKv-FE00l0qHaT5xScOo3owQoc7JBs_eCKQzbR5Olfq