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

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
应用型负载均衡 ALB,每月750个小时 15LCU
简介:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
默认情况下,mesos marathon会把app发布到随机节点的随机端口上,当mesos slaves和app越来越多的时候,想查找某组app就变得困难。
mesos提供了两个工具:mesos-dns和marathon-lb,他们俩是mesosphere 官网提供的两种服务发现和负载均衡工具,其中:
mesos-dns是一个服务发现工具,marathon-lb不仅是服务发现工具,还是负载均衡工具。
 
鉴于Mesos-DNS有如下诸多缺陷:
1)DNS无法识别服务端口,除非使用SRV查询(SRV记录它是DNS服务器的数据库中支持的一种资源记录的类型,它记录了哪台计算机提供了哪个服务这么一个简单的信息);大多数应用程序都无法使用SRV记录“开箱即用”。
2)DNS不具有快速故障转移能力,没有快速容错功能。
3) DNS记录有一个TTL(生存时间: time  to live),同时Mesos-DNS使用轮询来创建DNS记录; 这可能会导致过时的记录。
4)DNS记录不提供任何服务的健康数据。
5)一些应用程序和库不正确地处理多个A记录(handle multiple A records);在某些情况下,查询可能被缓存,并根据需要不正确地重新加载。
 
所以现在一般不推荐使用Mesos-DNS作为服务发现工具,而是推荐使用marathon-lb,marathon-lb是可以起到与Mesos-DNS同样作用。
Marathon-lb既是一个服务发现工具,也是负载均衡工具,它集成了haproxy,自动获取各个app的信息,为每一组app生成haproxy配置,通过servicePort或者web虚拟主机提供服务。
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基于HAProxy,给基于TCP和HTTP协议的应用提供代理和负载均衡功能,此外还提供诸如SSL支持,HTTP压缩,健康检查,Lua脚本等。Marathon-lb订阅Marathon的事件总线,实时更新HAProxy的配置,并重载应用。

配置过程如下:
1)首先分别在slave-1、slave-2、slave-3节点机器上拉取marathon-lb镜像

1
2
3
4
5
6
[root@slave-1 ~] # docker pull mesosphere/marathon-lb
[root@slave-1 ~] # docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
docker.io /tomcat                    latest              08f8166740f8        6 days ago          366.7 MB
docker.io /nginx                     latest              46102226f2fd        2 weeks ago         109.4 MB
docker.io /mesosphere/marathon-lb    latest              08e0c402b5c2        3 weeks ago         229.3 MB

2)编写marathon-lb的json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[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://182.48.115.233:8080" , "--group" "external" ]
}

特别注意下:

1
2
3
4
1)network采用的是 "HOST"
2)args后面http配置的ip是marathon的ip;也可以将多个master的ip都配置上
    "args" : [ "sse" "-m" , "http://master1_ip:8080" "-m" , "http://master2_ip:8080" "-m" , "http://master3_ip:8080" , "--group" "external" ]
3)注意group后面的external参数

3)部署marathon-lb应用
第一种方法:在marathon机器上通过curl的方式调用

1
[root@master-1 ~] # curl -i -H 'Content-Type: application/json' 182.48.115.233:8080/v2/apps -d@marathon-lb.json

第二种方式:在marathon访问界面里点击"Create Application",在"JSON Mode"模式下,将上面marathon-lb.json文件内容粘贴进去

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[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
2
3
4
5
6
7
8
9
10
11
12
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上,访问域名时就会自动发布到后端的容器应用上。

部署docker的nginx容器应用,方式也有两种:
第一种方法:在marathon机器上通过curl的方式调用

1
[root@master-1 ~] # curl -i -H 'Content-Type: application/json' 182.48.115.233:8080/v2/apps -d@docker_nginx.json

第二种方式:在marathon访问界面里点击"Create Application",在"JSON Mode"模式下,将上面marathon-lb.json文件内容粘贴进去

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

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

为了试验效果,分别将下面绑定了marathon-lb的四个ngixn容器的访问内容修改下,简单做法是:

1
2
在182.48.115.237本机编写index.html文件,使用 "docker cp" 将文件覆盖到映射端口分别为31277、31022、31667的nginx容器的80端口默认站点目录 /usr/share/nginx/html 下的index.html。
同理,在182.48.115.239本机也编写index.html文件,然后将其覆盖到映射端口为31380的nginx容器的80端口默认站点目录 /usr/share/nginx/html 下的index.html。

四个nginx容器访问页面为:

5)登陆marathon-lb的容器里面,查看生成的haproxy.cfg文件

如上可知,marathon-lb容器创建在slave3节点机器上(182.48.115.239),登陆该容器,查看haproxy.cfg文件,可以发现已经生成了负载配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[root@slave-3 ~] # docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                   NAMES
5acf0e5390dc        docker.io /nginx                     "nginx -g 'daemon off"    About an hour ago   Up About an hour    0.0.0.0:31380->80 /tcp    mesos-92c601e1-3522-49f3-b030-9e0456aa19b9-S2.4ffe15aa-d840-443b-af6d-963a1680b792
39a89fe14869        docker.io /mesosphere/marathon-lb    "tini -g -- /marathon"    About an hour ago   Up About an hour                            mesos-92c601e1-3522-49f3-b030-9e0456aa19b9-S2.3bdc6abc-0eaa-47a6-b562-cfe436168b78
 
[root@slave-3 ~] # docker exec -ti 39a89fe14869 /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 182_48_115_237_31022 182.48.115.237:31022 check inter 60s fall 4
   server 182_48_115_237_31277 182.48.115.237:31277 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 182_48_115_237_31667 182.48.115.237:31667 check inter 60s fall 4
   server 182_48_115_239_31380 182.48.115.239:31380 check inter 60s fall 4

 这时候访问marathon-lb容器所在机的80端口(即访问http://182.48.115.239),则请求就会负载到后端的nginx机器上(即上面那4个ngixn容器所在机器)。如下,不断刷新,就会负载到后端不同的页面上。

 

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

6)查看haproxy的监控页面

即可以分别方面下面url以查看健康状态(182.48.115.239是marathon-lb所在机器的ip)

1
2
3
4
5
http: //182 .48.115.239:9090 /haproxy ?stats
http: //182 .48.115.239:9090 /haproxy ?stats;csv
http: //182 .48.115.239:9090 /_haproxy_health_check
http: //182 .48.115.239:9090 /_haproxy_getconfig
http: //182 .48.115.239:9090 /_haproxy_getpids

总结几点

1
2
3
4
5
6
7
8
9
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的时候加上认证。
本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/6845980.html,如需转载请自行联系原作者

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
1月前
|
人工智能 API 数据安全/隐私保护
使用 Docker 一键免费部署 63.8k 的私人 ChatGPT 网页应用
NextChat 是一个可以在 GitHub 上一键免费部署的私人 ChatGPT 网页应用,支持 GPT3、GPT4 和 Gemini Pro 模型。该项目在 GitHub 上获得了 63.8k 的 star 数。部署简单,只需拉取 Docker 镜像并运行容器,设置 API Key 后即可使用。此外,NextChat 还提供了预设角色的面具功能,方便用户快速创建对话。
184 22
使用 Docker 一键免费部署 63.8k 的私人 ChatGPT 网页应用
|
1月前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
939 12
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
28天前
|
Java 应用服务中间件 Docker
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
32 2
|
1月前
|
Java Linux Docker
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
43 3
|
1月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
1月前
|
运维 开发者 Docker
Docker Compose:简化容器化应用的部署与管理
Docker Compose:简化容器化应用的部署与管理
|
1月前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
68 1
|
1月前
|
持续交付 开发者 Docker
掌握Docker容器化技术,加速软件开发与部署
掌握Docker容器化技术,加速软件开发与部署
53 0
|
1月前
|
前端开发 开发者 Docker
深入探索Docker Compose:简化多容器应用的部署
深入探索Docker Compose:简化多容器应用的部署
90 0