前面的章节介绍了Mesos+Zookeeper+Marathon的Docker管理平台,接下来介绍如何在该平台下构建负载均衡。

默认情况下,mesos marathon会把app发布到随机节点的随机端口上,当mesos slaves和app越来越多的时候,想查找某组app就变得困难。
mesos提供了两个工具:mesos-dns和marathon-lb,他们俩是mesosphere 官网提供的两种服务发现和负载均衡工具,其中:
mesos-dns是一个服务发现工具,marathon-lb不仅是服务发现工具,还是负载均衡工具。

marathon-lb介绍

鉴于Mesos-DNS有如下诸多缺陷:

  1. DNS不能识别服务端口,除非使用DIG的SRV进行直接查询。大多数应用不能立即使用SRV记录
  2. DNS没有快速容错
  3. DNS记录有一个TTL(生存时间),并且Mesos-DNS使用池创建DNS记录,这样SRV记录会稍有滞后
  4. DNS不能提供任何服务健康状态数据
  5. 一些应用和库不能正确的处理多个SRV记录。很多情况下查询或许是缓存过的,以及不能按照实际需要被正确的重新装载

所以现在一般不推荐使用Mesos-DNS作为服务发现工具,而是推荐使用marathon-lb,marathon-lb是可以起到与Mesos-DNS同样作用。

Marathon-lb是个基于HAProxy的快速代理和负载均衡。他能为基于TCP和HTTP协议的应用提供代理和负载均衡,此外还支持SSL、健康检查、HTTP压缩、Lua脚本等特性。

Marathon-lb通过Marathon的EventBus可以自动获取Marathon上每个应用的信息,并且能够为每组应用生成HAProxy配置。不同于通过域名机制来发现服务的Mesos-DNS,Marathon-lb是通过servicePort服务端口来发现服务外,另外,还可以通过VHOST来访问服务。

  1. 要使用marathonn-lb,每组app必须设置HAPROXY_GROUP标签。
  2. Marathon-lb运行时绑定在各组app定义的服务端口(servicePort,如果app不定义servicePort,marathon会随机分配端口号)上,可以通过marathon-lb所在节点的相关服务端口访问各组app。比如说:marathon-lb部署在slave2,test-app 部署在slave1,test-app 的servicePort是10004,那么可以在slave2的10004端口访问到test-app提供的服务。
  3. 由于servicePort非80、443端口(80、443端口已被marathon-lb中的 haproxy独占),对于web服务来说不太方便,可以使用 haproxy虚拟主机解决这个问题:在提供web服务的app配置里增加HAPROXY_{n}_VHOST(WEB虚拟主机)标签,marathon-lb会自动把这组app的WEB集群服务发布在marathon-lb所在节点的80和443端口上,用户设置DNS后通过虚拟主机名来访问。

配置Marathon-lb

首先分别在slave-1、slave-2、slave-3节点机器上拉去marathon-lb镜像:

[root@slave-1 ~]# docker pull mesosphere/marathon-lb
[root@slave-1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/nginx latest 2f7f7bce8929 12 days ago 107.5 MB
docker.io/tomcat latest a2fbbcebd67e 2 weeks ago 333.9 MB
docker.io/mesosphere/marathon-lb latest 8fffa444b894 2 weeks ago 181.3 MB

编写marathon-lb的json文件:

[root@master-1 ~]# vim marathon-lb.json
{
"id": "marathon-lb",
"instances": 1,
"constraints": [["hostname", "UNIQUE"]],
"container": {"type": "DOCKER",
"docker": {
"image": "docker.io/mesosphere/marathon-lb",
"privileged": true,
"network": "HOST"
}
},
"args":["sse","-m","http://192.168.93.133:8080","-m","http://192.168.93.134:8080","-m","http://192.168.93.135:8080","--group","external"]
}

也可以通过marathon是访问界面里点击“Create Application”,在“JSON Mode”模式下,将上面marathon-lb.json文件粘贴进去:

接着编写应用的json,然后构建应用。这里以创建docker的nginx容器应用为例:

[root@master-1 ~]# vim docker_nginx.json
{
"id":"nginx",
"labels": {
"HAPROXY_GROUP":"external",
"HAPROXY_0_VHOST":"nginx.marathon.mesos"
},
"cpus":0.2,
"mem":20.0,
"instances": 2,
"healthChecks": [{ "path": "/" }],
"container": {
"type":"DOCKER",
"docker": {
"image": "docker.io/nginx",
"network": "BRIDGE",
"portMappings":[{"containerPort":80,"hostPort":0,"servicePort":80,"protocol":"tcp"}]
}
}
}

注意几点:

  1. 一定要加上HAPROXY_GROUP标签,它填写的是marathon-lb创建时定义的组名(如上)
  2. HAPROXY_0_VHOST是标签名,对于web服务可以加上VHOST标签,让marathon-lb设置WEB虚拟主机;这个标签名字可以随便定义,目的是为了便于区别应用容器。一般可以用业务域名来描述标签。
  3. "instances"表示应用的实例数,一般默认是1,如果写成n,说明创建n个应用。
  4. containerPort为80,是指容器内的端口。
  5. hostPort是当前主机映射到contenterPort的端口,如果hostPort为0的话,则说明是随机的。
  6. serverPort是marathon-lb需要配置的haproxy代理暴露的端口,这里设置为80,说明访问marathon-lb机器的80端口就可为访问这个应用容器的80端口。

需要记住:
  对于web服务,servicePort设置为0即可,marathon-lb会自动把web服务集群发布到80、443上;
  所以上面docker_nginx_json文件里的"servicePort"后面的端口可以写成0,这样后端若是有443端口开启,marathon-lb会自动分发到上面。
  最后把域名解析到marathon-lb所在的机器ip上,访问域名时就会自动发布到后端的容器应用上。

同样我们也可以在marathon管理控制界面创建nginx容器:

应用容器创建好之后,如下,可以看到容器创建后的“Labels”标签信息,这个在应用容器繁多的情况下很有用,便于识别:

还可以在创建一组绑定marathon-lb的nginx应用容器(只需要将docker_nginx.json文件里的id改变一下,比如改成“nginx2”,然后创建这个应用)

为了试验效果,分别将下面绑定了marathon-lb的四个nginx容器的访问内容修改一下:

[root@slave-2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d0117ff35d5 docker.io/nginx "nginx -g 'daemon off" 5 minutes ago Up 4 minutes 0.0.0.0:31112->80/tcp mesos-7e126eca-5cc9-4dab-97a7-ee25132ae82e-S1.4899d7cc-0062-4502-afaf-3a435deefb6c
[root@slave-2 ~]# cat index.html
this is nginx - port:31112
[root@slave-2 ~]# docker cp index.html 2d0117ff35d5:/usr/share/nginx/html

其余的同理。

访问四个Nginx容器的页面:

登录marathon-lb的容器里面,查看生成的haproxy.cfg文件:

[root@slave-3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e7967120ce4 docker.io/mesosphere/marathon-lb "tini -g -- /marathon" 7 seconds ago Up 6 seconds mesos-7e126eca-5cc9-4dab-97a7-ee25132ae82e-S2.bd0b3c6d-ff9f-470e-b617-e3f4ecd49cbb
[root@slave-3 ~]# docker exec -it 1e7967120ce4 /bin/bash
root@slave-3:/marathon-lb# cat haproxy.cfg
......
......
frontend nginx_80
bind *:80
mode http
use_backend nginx_80 frontend nginx2_80
bind *:80
mode http
use_backend nginx2_80 backend nginx_80
balance roundrobin
mode http
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk GET /
timeout check 20s
server 192_168_93_136_31399 192.168.93.136:31399 check inter 60s fall 4
server 192_168_93_137_31112 192.168.93.137:31112 check inter 60s fall 4 backend nginx2_80
balance roundrobin
mode http
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk GET /
timeout check 20s
server 192_168_93_136_31464 192.168.93.136:31464 check inter 60s fall 4
server 192_168_93_136_31703 192.168.93.136:31703 check inter 60s fall 4

这时候我们访问marathon-lb容器所在机器的80端口,则请求就会负载到后端的nginx机器上,不断刷新就会负载到后端不同的页面上:

可以在三个slave节点上做keepalived心跳测试,绑定一个VIP,三个节点做成一主两从,keepalived.conf里监控80端口的marathon-lb进程。当marathon-lb在哪个节点上,VIP就漂移到那个节点上,业务域名解析到VIP上,这样也就完成了一个高可用方案。

查看haproxy的监控页面:

总结几点:

  1. docker应用容器创建时的servicePort端口设置,这个关系到使用haproxy负载后,最终的访问端口。
  2. 可以创建不同的marathon-lb容器(可以定义不同的group),然后依据这些marathon-lb创建不同业务的应用容器,以实现负载均衡。
  3. marathon-lb容器默认会在三个slave节点中的某一个节点上创建,当所在节点出现故障或重启marathon-lb容器时,才会漂移到其他节点上,这样即实现了高可用(相当于"一主两从"),将业务玉域名解析到marathon-lb所在的节点ip上。
  4. 如果之前创建的应用容器绑定了marathon-lb,后续这个应用容器删除了,那么要记得重启marathon-lb,否则LB访问会出现故障。因为haproxy.cfg文件里还保留这个已删的应用容器的负载配置,重启marathon-lb后,haproxy.cfg文件才会更新。
  5. 为了安全考虑,最好不要将Marathon暴漏到公网上,要不定时监控Docker运行情况。此外,Mesos和Marathon启动的时候最好加认证,具体操作是:Marathon启动的时候加上--http_credentials即可,然后Mesos启动时候加上--authenticate --credentials参数,让Mesos slave 连接到Master的时候加上认证。

docker集群——Mesos集群下的负载均衡marathon-lb的更多相关文章

  1. 轻松搭建docker应用的mesos集群

    7条命令在docker中部署Mesos集群 所有使用的Docker容器构建文件是有也.您可以在本地构建每个容器或只使用位于Docker Hub预构建的容器.下面的命令会自动下载所需的预建的容器为您服务 ...

  2. EMQ集群搭建实现高可用和负载均衡(百万级设备连接)

    一.EMQ集群搭建实现高可用和负载均衡 架构服务器规划 服务器IP 部署业务 作用 192.168.81.13 EMQTTD EMQ集群 192.168.81.22 EMQTTD EMQ集群 192. ...

  3. Mesos+Zookeeper+Marathon的Docker管理平台部署记录(2)- 负载均衡marathon-lb

    之前介绍了Mesos+Zookeeper+Marathon的Docker管理平台部署记录(1)的操作,多余的废话不说了,下面接着说下在该集群环境下的负载均衡marathon-lb的部署过程: 默认情况 ...

  4. Nginx + Tomcat Windows下的负载均衡配置

     Nginx + Tomcat Windows下的负载均衡配置 一.为什么需要对Tomcat服务器做负载均衡?    Tomcat服务器作为一个Web服务器,其并发数在300-500之间,如果超过50 ...

  5. 19个心得 明明白白说Linux下的负载均衡

    [51CTO.com独家特稿]前言:作为一名Linux/unix系统工程师,这几年一直在涉及到对外项目,经手过许多小中型网站的架构,F5.LVS及Nginx接触的都比较多,我想一种比较通俗易懂的语气跟 ...

  6. 001/Nginx高可用模式下的负载均衡与动静分离(笔记)

    Nginx高可用模式下的负载均衡与动静分离 Nginx(engine x)是一个高性能的HTTP和反向代理服务器,具有内存少,并发能力强特点. 1.处理静态文件.索引文件以及自动索引:打开文件描述符缓 ...

  7. Nginx+Tomcat在Windows下做负载均衡

    一. 为什么需要对Tomcat服务器做负载均衡 Tomcat服务器作为一个Web服务器,其并发数在300-500之间,如果有超过500的并发数便会出现Tomcat不能响应新的请求的情况,严重影响网站的 ...

  8. 集群下Dubbo负载均衡配置

    在集群负载均衡时,Dubbo提供了4种均衡策略,默认为Random(随机调用) 负载均衡策略: 1).Random LoadBalance(随机,按照权重的设置随机概率) 2).RoundRobin  ...

  9. MySQL集群(三)mysql-proxy搭建负载均衡与读写分离

    前言 前面学习了主从复制和主主复制,接下来给大家分享一下怎么去使用mysql-proxy这个插件去配置MySQL集群中的负载均衡以及读写分离. 注意:这里比较坑的就是mysql-proxy一直没有更新 ...

随机推荐

  1. 驱动模块和装模块的概念——Junit单元测试案例

    驱动模块是用来模拟被测试模块的上一级模块,相当于被测模块的主程序.它接收数据,将相关数据传送给被测模块,启用被测模块,并打印出相应的结果. 桩模块(Stub)是指模拟被测试的模块所调用的模块,而不是软 ...

  2. selenium 3.0鼠标事件 (java代码)

    注意:ActionChains下相关方法在当前的firefox不工作,建议使用谷歌浏览器. public static void main(String[] args) throws Interrup ...

  3. Java中的new关键字和引用传参

    先看看Java中如何使用new关键字创建一个对象的. [java] view plain copy public class Student { public String name; public  ...

  4. elasticsearch中client.transport.sniff的使用方法和注意事项

    https://blog.csdn.net/J_bean/article/details/79507559

  5. SecureCRT的安装、介绍、简单操作

    网上看到一篇名为<SecureCRT的使用方法和技巧(详细使用教程)>的secureCRT教程,可能软件版本与我不一样我安装的是8.1. 原文来源:http://www.jb51.net/ ...

  6. 树形DP求树的最小支配集,最小点覆盖,最大独立集

    一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...

  7. linux根目录下文件夹概览详解

    / 根目录 /bin 存放必要的命令 /boot 存放内核以及启动所需的文件等 /dev 存放设备文件 /etc 存放系统的配置文件 /home 用户文件的主目录,用户数据存放在其主目录中 /lib ...

  8. URAL 1682 Crazy Professor (并查集)

    [题目链接] http://acm.timus.ru/problem.aspx?space=1&num=1682 [题目大意] 给出k,从1开始不断地加一并把这个数写在黑板上,如果写上的数字和 ...

  9. 【推导】Codeforces Round #402 (Div. 2) A. Pupils Redistribution

    一次交换,会让Group A里面的某个数字的数量-1,另一个数字的数量+1:对Group B恰好相反. 于是答案就是xigma(i=1~5,numA[i]-numB[i]>0)(numA[i]- ...

  10. 【二分】【动态规划】Codeforces Round #393 (Div. 1) B. Travel Card

    水dp,加个二分就行,自己看代码. B. Travel Card time limit per test 2 seconds memory limit per test 256 megabytes i ...