Marathon-lb用途
在使用Marathon+Mesos 的容器集群中,我们会构建很多个容器,这些容器在不同的slave上分配了不同的随机端口,这些Docker容器在HA模式下运行,如果任何slave节点故障导致容器实例意外退出,它将自动重新创建到健康的节点上。 所以我们不必担心高可用性问题,Marathon会自动帮我们处理这些问题。
但是,当我们要使用这些容器处理我们的业务数据时,问题就来了。如我们有多个nginx提供web服务,我们如何分配流量? 如果slave节点发生硬件故障,或者容器实例崩溃,那么新创建的容器IP和端口随时可能发生变化。 我们需要确保我们的负载均衡器能够在最短时间内检测这些变化,并相应地路由流量。 要解决这个问题,我们就要使用Marathon-lb。 Marathon-lb是通过监测Marathon应用程序状态来管理HAProxy的工具。而 HAProxy是一款快速,高效,经过测试的高可用性负载平衡器,具有许多高级功能,如健康检查,SSL,会话持久性等。
Marathon-lb设计思想
Marathon-lb通过调用自身的marathon_lb.py 脚本,连接到Marathon API以检索所有正在运行的应用程序,根据检索的信息生成HAProxy配置并重新加载HAProxy。 每当应用程序状态有任何变化时,Marathon-lb就会使用最新的IP和端口号更新haproxy配置文件,并重新加载haproxy。 默认情况下,Marathon-lb会绑定到每个应用的服务端口,并将传入的请求发送到应用实例。
Marathon-lb依赖于嵌入在haproxy中的最新lua支持来生成配置文件。 我们需要下载并安装具有Lua支持的Haproxy,需要使用haproxy 1.6.0以上版本。
Marathon-lb可以直接从官方下载docker镜像,简单配置之后就可以和其它容器一起放在Mesos集群中以容器的方式运行,也可以使用传统的方法在某一两台主机上安装,设置vip,配置为高可用的模式,这两种方式各有优缺点,可以根据自己的业务要求进行合理规划。下面就这两种方式为大家一一介绍。
使用单独主机配置Marathon-lb
在本地主机IP为192.168.20.47的主机上部署Marathon-lb。
安装Haproxy
1、Haproxy需要lua5.3及以上版本,CentOS7.2默认的lua版本是5.1.4,所以首先安装lua5.3.4,这里使用编译安装,需要确保系统中已经安装gcc和readline-devel:
1
2
3
4
5
6
7
8
<code>[root@marathon-lb ~]</code><code># wget http://www.lua.org/ftp/lua-5.3.4.tar.gz</code>
<code>[root@marathon-lb ~]</code><code># tar xf lua-5.3.4.tar.gz </code>
<code>[root@marathon-lb ~]</code><code># cd lua-5.3.4 </code>
<code>[root@marathon-lb lua-5.3.4]</code><code># make linux test</code>
<code>[root@marathon-lb lua-5.3.4]</code><code># cd src</code>
<code>[root@marathon-lb src]</code><code># cp lua luac /usr/bin/ </code>
<code>[root@marathon-lb ~]</code><code># lua -v</code>
<code>Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio</code>
2、安装Haproxy
先安装必要的模块:
<code>[root@marathon-lb ~]</code><code># yum install socat openssl-devel pcre-devel zlib-devel libcurl-devel -y</code>
下载最新的源码包安装:
<code>[root@marathon-lb ~]</code><code># wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.8.tar.gz </code>
<code>[root@marathon-lb ~]</code><code># tar xf haproxy-1.7.8.tar.gz </code>
<code>[root@marathon-lb ~]</code><code># cd haproxy-1.7.8</code>
<code>[root@marathon-lb haproxy-1.7.8]</code><code># make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1 USE_LUA=1</code>
<code>[root@marathon-lb haproxy-1.7.8]</code><code># make install PREFIX=/usr/local/haproxy</code>
<code>[root@marathon-lb haproxy-1.7.8]</code><code># haproxy -v</code>
<code>HA-Proxy version 1.7.8 2017</code><code>/07/07</code>
<code>Copyright 2000-2017 Willy Tarreau <[email protected]></code>
3、编写启动脚本,此处可参考系统自带的启动脚本,设置配置文件路径。测试使用reload命令是否正常。
<code>/etc/init</code><code>.d</code><code>/haproxy</code> <code>start</code>
<code>/etc/init</code><code>.d</code><code>/haproxy</code> <code>reload</code>
安装Marathon-lb
1、从github上下载安装Marathon-lb
<code>[root@marathon-lb ~]</code><code># git clone https://github.com/mesosphere/marathon-lb.git </code>
<code>[root@marathon-lb ~]</code><code># mv marathon-lb /</code>
<code>[root@marathon-lb ~]</code><code># cd /marathon-lb</code>
2、创建ca证书和pem文件(防止启动时报错,这里只做内部使用,可根据自己的实际需求申请证书)
<code>cd</code> <code>/etc/ssl/</code>
<code>openssl genrsa -out ca.key 1024</code>
<code>openssl req -new -key ca.key -out ca.csr </code>
<code>openssl x509 -req -days 365 -</code><code>in</code> <code>ca.csr -signkey ca.key -out ca.crt </code>
<code>cat</code> <code>ca.crt ca.key > cert.pem</code>
3、创建haproxy的global配置文件,启动haproxy
<code>haproxy -f </code><code>/etc/haproxy/haproxy</code><code>.cfg</code>
4、在marathon上发布含有HAPROXY_GROUP类型的标签的app,这里发布一个haproxy组信息为“external”标签的tomcat容器:
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<code>{ </code>
<code>"id"</code><code>:</code><code>"tomcat"</code><code>, </code>
<code>"labels"</code><code>: {</code>
<code> </code><code>"HAPROXY_GROUP"</code><code>:</code><code>"external"</code><code>,</code>
<code> </code><code>"HAPROXY_0_VHOST"</code><code>:</code><code>"tomcat-test.com"</code>
<code> </code><code>},</code>
<code> </code>
<code>"cpus"</code><code>:1, </code>
<code>"mem"</code><code>:128, </code>
<code>"instances"</code><code>: 1, </code>
<code>"constraints"</code><code>: [[</code><code>"hostname"</code><code>, </code><code>"UNIQUE"</code><code>,</code><code>""</code><code>]], </code>
<code>"container"</code><code>: { </code>
<code>"type"</code><code>:</code><code>"DOCKER"</code><code>, </code>
<code>"docker"</code><code>: { </code>
<code>"image"</code><code>: </code><code>"tomcat"</code><code>, </code>
<code>"network"</code><code>: </code><code>"BRIDGE"</code><code>, </code>
<code>"portMappings"</code><code>: [ </code>
<code>{</code><code>"containerPort"</code><code>: 8080, </code><code>"hostPort"</code><code>: 0,</code><code>"servicePort"</code><code>: 0, </code><code>"protocol"</code><code>: </code><code>"tcp"</code> <code>} </code>
<code>] </code>
<code> </code><code>} </code>
<code> </code><code>} </code>
<code> </code><code>}</code>
5、配置Marathon-lb通过Marathon API获取容器应用状态,使用marathon-lb.py脚本更新haproxy配置信息并自动重新加载haproxy,这里需要指定marathon集群主机信息:
<code>[root@marathon-lb marathon-lb]</code><code># ./marathon_lb.py -m http://192.168.20.41:8080 \</code>
<code>-m http:</code><code>//192</code><code>.168.20.42:8080 -m http:</code><code>//192</code><code>.168.20.43:8080 sse --group external \</code>
<code>--health-check</code>
此时,会在/etc/haproxy目录下生成一个haproxy.cfg的文件。并会自动执行happroxy的reload操作。
6、每次执行marathon-lb.py的文件才会去更新haproxy配置,可以写一个marathon-lb的启动脚本使marathon-lb持续运行,这里只是示例,脚本比较粗糙,大家可以自行优化:
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<code>#!/bin/bash</code>
<code># marathon-lb management script</code>
<code># tryingstuff.blog.51cto.com</code>
<code>PIDFILE=</code><code>/var/run/haproxy</code><code>.pid</code>
<code>SINGNFILE=</code><code>/tmp/marathon-lb</code><code>.sign</code>
<code>MLB_HOME=</code><code>/marathon-lb/</code>
<code>start() {</code>
<code>PRO_CUNT=`</code><code>ps</code> <code>-ef|</code><code>grep</code> <code>marathon_lb|</code><code>grep</code> <code>-</code><code>v</code> <code>'grep'</code><code>|</code><code>wc</code> <code>-l`</code>
<code>if</code> <code>[ $PRO_CUNT -gt 1 ]</code>
<code> </code><code>then</code>
<code> </code><code>echo</code> <code>"marathon-lb already running!"</code>
<code> </code><code>exit</code> <code>1</code>
<code>else</code>
<code> </code><code>echo</code> <code>"marathon-lb start! "</code> <code>> $SINGNFILE</code>
<code>fi</code>
<code>while</code> <code>[ -f $SINGNFILE ]</code>
<code> </code><code>do</code>
<code> </code><code>cd</code> <code>$MLB_HOME && .</code><code>/marathon_lb</code><code>.py -m http:</code><code>//192</code><code>.168.20.41:8080 -m http:</code><code>//192</code><code>.168.20.42:8080 -m http:</code><code>//192</code><code>.168.20.43:8080 sse --group external --health-check &> </code><code>/dev/null</code>
<code> </code><code>done</code>
<code>}</code>
<code>stop() {</code>
<code>rm</code> <code>-f $SINGNFILE</code>
<code>echo</code> <code>"marathon-lb stopped!"</code>
<code>case</code> <code>"$1"</code> <code>in</code>
<code> </code><code>start)</code>
<code> </code><code>start</code>
<code> </code><code>;;</code>
<code> </code><code>stop)</code>
<code> </code><code>stop</code>
<code> </code><code>*)</code>
<code> </code><code>echo</code> <code>$</code><code>"Usage: $0 {start|stop}"</code>
<code>esac</code>
给脚本添加执行权限并命名为marathon-lb,启动marathon-lb:
<code>nohub marathon-lb start &</code>
关闭marathon-lb:
<code>marathon-lb stop</code>
7、访问tomcat容器:
在本地hosts 文件中添加 marathon-lb IP(此处为192.168.20.47)和域名的对应记录(tomcat-test.com),访问tomcat-test.com:
<a href="https://s2.51cto.com/wyfs02/M00/9E/93/wKiom1mSo7iAa20zAAGS-H0PbwU647.jpg" target="_blank"></a>
以容器方式配置Marathon-lb
理解了主机配置的方式,相对于以容器方式配置Marathon-lb那就太简单了,只需下载镜像,启动容器两步即可, 生产中推荐使用这种方式。
1、从官方下载Marathon-lb容器镜像
<code>docker pull docker.io</code><code>/mesosphere/marathon-lb</code>
2、指定mesos的master主机和Haproxy 组,启动Marathon-lb容器:
<code>docker run -d --privileged -e PORTS=9090 --net=host \</code>
<code>docker.io</code><code>/mesosphere/marathon-lb</code> <code>sse \</code>
<code>-m http:</code><code>//192</code><code>.168.20.41:8080 -m http:</code><code>//192</code><code>.168.20.42:8080 \</code>
<code>-m http:</code><code>//192</code><code>.168.20.43:8080 --group external</code>
这里所指定网络模式为host.
3、发布APP要指定标签类型,否则不会被marathon-lb获取到状态信息:
<code>{</code>
<code> </code><code>"id"</code><code>:</code><code>"nginx"</code><code>,</code>
<code> </code><code>"labels"</code><code>: {</code>
<code> </code><code>"HAPROXY_0_VHOST"</code><code>:</code><code>"nginx1.com"</code>
<code> </code><code>"cpus"</code><code>:0.2,</code>
<code> </code><code>"mem"</code><code>:20.0,</code>
<code> </code><code>"instances"</code><code>: 1,</code>
<code> </code><code>"constraints"</code><code>: [[</code><code>"hostname"</code><code>, </code><code>"UNIQUE"</code><code>,</code><code>""</code><code>]],</code>
<code> </code><code>"container"</code><code>: {</code>
<code> </code><code>"type"</code><code>:</code><code>"DOCKER"</code><code>,</code>
<code> </code><code>"docker"</code><code>: {</code>
<code> </code><code>"image"</code><code>: </code><code>"nginx"</code><code>,</code>
<code> </code><code>"network"</code><code>: </code><code>"BRIDGE"</code><code>,</code>
<code> </code><code>"portMappings"</code><code>: [</code>
<code> </code><code>{</code><code>"containerPort"</code><code>: 80, </code><code>"hostPort"</code><code>: 0,</code><code>"servicePort"</code><code>: 0, </code><code>"protocol"</code><code>: </code><code>"tcp"</code> <code>}</code>
<code> </code><code>]</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
如果要实现多个APP负载均衡,可以直接在marathon上对当前的app进行扩容,点击“scale application”节点会自动添加到haproxy中。
4、我们可以通过访问marathon-lb容器所在的主机IP来访问nginx(指定了VHOST需要做解析或在本地添加hosts记录),使用如下格式访问9090端口来查看当前haproxy的状态:
可以创建多个marathon-lb容器作为高可用。
参考资料:
本文转自 酥心糖 51CTO博客,原文链接:http://blog.51cto.com/tryingstuff/1955757