摘要: 将容器应用部署到集群时,其服务地址,即IP端口, 是由集群系统动态分配的。那么,当我们需要访问这个服务时,如何确定它的地址呢?这时,就需要服务发现(Service Discovery)了。本文将以Nginx的部署为例,介绍服务发现的原理与实践。

一. 单机部署Nginx

Nginx作为网页服务器,功能与Apache一致。使用Docker, 可以快速部署Nginx。

1. 下载Nginx镜像

sudo docker pull nginx:1.10

2. 运行Nginx容器

sudo docker run -d \
-p 8080:80 \
nginx:1.10

其中,-d选项表示Nginx容器在后台运行,-p选项表示主机的8080端口映射为容器的80端口。

3. 访问Nginx服务

使用浏览器服务Nginx

http://192.168.59.1:8080

或者使用curl命令访问Nginx, 其返回结果为html文件。

curl 192.168.59.1:8080

Nginx的服务地址是192.168.59.1:8080,其中,192.168.59.1是运行Nginx容器的主机的IP,而8080是Nginx提供服务的端口。

可知,将容器应用部署到单个主机上时,服务的IP即为运行容器的主机IP,而服务的端口可以通过-p选项手动指定,这时服务地址相当于是静态分配的,因此不存在服务发现的问题。然而,当我们将容器应用部署到多个节点的集群时呢?

二. Mesos/Marathon集群中部署Nginx

首先,可以按照基于Docker搭建多节点Mesos/Marathon介绍的方法,快速搭建3个节点的Mesos/Marathon集群。部署Nginx时,可以不使用服务发现,也可以使用Marathon LB提供服务发现。通过对比两种方式,可以更好地理解服务发现。

1. 不使用服务发现

Nginx定义(nginx1.json):

{
"id": "nginx1",
"cpus": 0.2,
"mem": 20.0,
"instances": 1,
"healthChecks": [{
"path": "/"
}],
"container": {
"type": "DOCKER",
"docker": {
"image": "nginx:1.10",
"network": "BRIDGE",
"portMappings": [{ "containerPort": 80, "hostPort": 0, "protocol": "tcp" }]
}
}
}

其中,instances为1,表示仅部署单个Nginx容器; hostPort为0,表示Nginx容器绑定的主机端口由Marathon随机分配。

部署Nginx:

curl -Ss \
-X POST \
-H "Content-Type: application/json" \
--data "@nginx1.json" \
http://127.0.0.1:8080/v2/apps | python2.7 -mjson.tool

这时,Nginx容器可能运行node2(192.168.59.2)上,也可能运行在node3(192.168.59.3)上,因此Nginx服务的IP是无法事先确定的。而Nginx容器绑定的主机端口由Marathon随机分配,也不确定。

当然,服务端口可以通过hostPort指定,但是这样做并不合适,因为有可能会发生端口冲突。当集群中运行了非常多不同的服务时,静态分配端口是不现实的,也限制了集群的灵活性与扩展性

在Slave节点上使用docker ps命令可以获取Nginx服务的IP与端口。

node2(192.168.59.2)

sudo docker ps | grep nginx
b863d407b880 nginx:1.10 "nginx -g 'daemon off" 15 minutes ago Up 15 minutes 443/tcp, 0.0.0.0:31575->80/tcp mesos-d34d0b5b-c3b1-4020-9bb2-bb8582252bf3-S0.d2de6d05-9751-4fbe-af10-d7e35e9e6c7b

node3(192.168.59.3)

sudo docker ps | grep nginx

可知Nginx服务的IP与端口分别为192.168.59.231575,即Nginx的服务地址为:http://192.168.59.2:31575

每次重新部署Nginx时,其IP和端口会发生变化,这就意味着每次都要手动去查询服务地址,这很不方便,且无法将部署任务自动化。在容器集群中,通常需要运行非常多不同的应用,这就意味着服务发现是容器集群系统的必备功能。

2. 使用Marathon LB提供服务发现

Marathon LB是Marathon的服务发现系统。Marathon LB通过使用Haproxy实现了代理服务器的功能。

通过使用Marathon LB可以配置服务的固定端口,而服务的IP就是运行Marathon LB的节点IP。Marathon LB会监听Marathon的调度事件,获取容器实际运行的IP与端口,然后更新Haproxy的配置文件。因此,当重新部署Nginx时,我们仍然可以通过固定的IP与端口访问该服务。

Nginx定义(nginx2.json):

{
"id": "nginx2",
"labels": {
"HAPROXY_GROUP": "external"
},
"cpus": 0.2,
"mem": 20.0,
"instances": 1,
"healthChecks": [{
"path": "/"
}],
"container": {
"type": "DOCKER",
"docker": {
"image": "nginx:1.10",
"network": "BRIDGE",
"portMappings": [{ "containerPort": 80, "hostPort": 0, "servicePort": 10000, "protocol": "tcp" }]
}
}
}

其中,nginx2.json只有HAPROXY_GROUPservicePort两处修改。HAPROXY_GROUP为external,表示Nginx将使用分组为external的Marathon LB做服务发现。servicePort为10000,表示Nginx将使用Marathon LB节点的10000端口提供服务。

部署Nginx:

curl -Ss \
-X POST \
-H "Content-Type: application/json" \
--data "@nginx2.json" \
http://127.0.0.1:8080/v2/apps | python2.7 -mjson.tool

这时,Nginx服务的IP为运行Marathon LB的节点IP,即192.168.59.1,而Nginx服务的端口为servicePort指定的端口,即10000。因此,Nginx的服务地址为:http://192.168.59.1:10000。而Nginx容器的实际地址为http://192.168.59.2:31270,Marathon LB使用Haproxy作为代理服务器转发的服务请求。Marathon LB会监听Marathon的调度事件,获取容器实际运行的IP与端口,然后更新Haproxy的配置文件。下面即为Marathon LB自动生成的Haproxy配置文件:

frontend nginx2_10000
bind *:10000
mode http
use_backend nginx2_10000
 
backend nginx2_10000
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_59_2_31270 192.168.59.2:31270 check inter 60s fall 4

可知Haproxy中,niginx服务的前端(frontend)地址为: *:10000,而后端(backend)地址为: 192.168.59.2:31270。Haproxy负责将服务请求转发到Nginx容器。

当我们重新部署Nginx时,Nginx容器的IP和端口会发生变化,Marathon LB会更新Haproxy的配置文件,因此我们仍然可以通过http://192.168.59.1:10000访问服务。

因此,Marathon LB的任务就是发现服务的地址(IP和端口),然后用户就不用每次手动查询了。bamboonixy实现了同样的功能。

三. 参考

  1. Understanding Modern Service Discovery with Docker
  2. 基于Docker技术构建PaaS云平台
  3. Youzan 服务发现概述
版权声明:
转载时请注明作者KiwenLau以及本文地址:
https://kiwenlau.com/2016/09/04/what-is-service-discovery/

marathon-lb-什么是服务发现?(转)的更多相关文章

  1. .NET Core微服务之路:基于gRPC服务发现与服务治理的方案

    重温最少化集群搭建,我相信很多朋友都已经搭建出来,基于Watch机制也实现了出来,相信也有很多朋友有了自己的实现思路,但是,很多朋友有个疑问,我API和服务分离好了,怎么通过服务中心进行发现呢,这个过 ...

  2. 服务发现与负载均衡 dubbo zk原理

    服务发现与负载均衡 拓展阅读 : dubbo 原理概念图 2016-03-03 杜亦舒 性能与架构 性能与架构 性能与架构 微信号 yogoup 功能介绍 网站性能提升与架构设计 内容整理自文章“实施 ...

  3. etcd学习(3)-grpc使用etcd做服务发现

    grpc通过etcd实现服务发现 前言 服务注册 服务发现 负载均衡 集中式LB(Proxy Model) 进程内LB(Balancing-aware Client) 独立 LB 进程(Externa ...

  4. grpc服务发现与负载均衡

    前言 在后台服务开发中,高可用性是构建中核心且重要的一环.服务发现(Service discovery)和负载均衡(Load Balance)一直都是我关注的话题.今天来谈一下我在实际中是如何理解及落 ...

  5. marathon的高可用服务自动发现和负载均衡

    上一篇我们说谈了docker+zookeeper+mesos+marathon集群,本篇我们来谈谈marathon的集群和自动发现服务. marathon的服务自动发现和负载均衡有两种,1是mesos ...

  6. 【云计算】mesos+marathon 服务发现、负载均衡、监控告警方案

    Mesos-dns 和 Marathon-lb 是mesosphere 官网提供的两种服务发现和负载均衡工具.官方的文档主要针对DCOS,针对其它系统的相关中文文档不多,下面是我在Centos7上的安 ...

  7. 寻找丢失的微服务-HAProxy热加载问题的发现与分析 原创: 单既喜 一点大数据技术团队 4月8日 在一点资讯的容器计算平台中,我们通过HAProxy进行Marathon服务发现。本文记录HAProxy服务热加载后某微服务50%概率失效的问题。设计3组对比实验,验证了陈旧配置的HAProxy在Reload时没有退出进而导致微服务丢失,并给出了解决方案. Keywords:HAProxy热加

    寻找丢失的微服务-HAProxy热加载问题的发现与分析 原创: 单既喜 一点大数据技术团队 4月8日 在一点资讯的容器计算平台中,我们通过HAProxy进行Marathon服务发现.本文记录HAPro ...

  8. linkerd——针对java的为微服务提供可靠性的proxy,服务发现重试LB等

    Buoyant是一家云服务公司,宣布了Linkerd(发音为“linker-DEE”)的一周年纪念日,这是一个基于微服务的原生云应用程序的开源“服务网格”项目.诚如公告所述: 在20世纪90年代,TC ...

  9. Chris Richardson微服务翻译:微服务架构中的服务发现

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...

随机推荐

  1. xampp更改网站存放目录

    改完后重启xampp 如何更改监听端口8080

  2. swift开发之--UISearchBar的使用/UISearchController的使用

    记录下UISearchBar的基本用法,补充:ios 8.0以后,原来的UISearchDisplayController被官方废弃,建议使用UISearchController,下面就简单的记录下这 ...

  3. Android-Gallery GridView ImageSwitcher 使用

    http://liangruijun.blog.51cto.com/3061169/647355/ http://blog.csdn.net/wantianwen/article/details/23 ...

  4. Javascript中的感叹号和函数function

    js函数前加分号和感叹号是什么意思?有什么用?:http://www.cnblogs.com/mq0036/p/4605255.html function与感叹号:https://swordair.c ...

  5. ch5-处理数据,抽取-整理-推导

    场景:教练kelly有4个选手James\Sarah\Julie\Mikey,他们每跑600米,教练就会计时并把时间记录在计算机的一个文件中,总共4个文件:James.txt\Sarah.txt\Ju ...

  6. STM32的操作过程,寄存器配置与调试过程(转载)

    很多学习stm32的,为什么学习stm32他也不知道,我们所知道的就是各个论坛讨论stm32的很多,而我们很多人之所以学习stm32是很多的淘宝卖家做了大量的图片文字宣传,于是我们经不住诱惑就买了板子 ...

  7. 报错程序包org.springframework.test.context不存在

    在pom.xml文件中找到 加入了依赖,但是maven update 或者Reimport后 启动还是报错 最后使出绝招: 在maven仓库的位置 找到对应的文件夹 更奇怪了 发现明明有jar包啊! ...

  8. Axis2开发实例

    1.下载①axis2-1.7.4-bin.zip.②axis2-1.7.4-war.zip.③axis2-eclipse-service-plugin-1.7.4.zip.④axis2-eclipse ...

  9. js jquery获取当前元素的兄弟级 上一个 下一个元素 jquery如何获取第一个或最后一个子元素

    var chils= s.childNodes;  //得到s的全部子节点 var par=s.parentNode;   //得到s的父节点 var ns=s.nextSbiling;   //获得 ...

  10. [置顶] 数据库优化实践【MS SQL优化开篇】

    数据库定义: 数据库是依照某种数据模型组织起来并存在二级存储器中的数据集合,此集合具有尽可能不重复,以最优方式为特定组织提供多种应用服务,其数据结构独立于应用程序,对数据的CRUD操作进行统一管理和控 ...