基于Docker的负载均衡和服务发现

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Docker已经成为时下热门的容器技术,各大公司,中小创业者,都选择采用Docker技术架构其下一代的系统和应用。 随着系统规模扩大,单一Docker容器不能应对压力,需要横向扩展到多个容器,我们需要考虑负载均衡的问题;单一职责的Docker容器之间需要相互通信,而容器在每一次重启之后,它的IP都可

应用的容器化和微服务化带来的问题

  • 在缺省网络模型中,容器每次重启后,IP会发生变动,在一个大的分布式系统保证IP地址不变是比较复杂的事情
  • IP频繁发生变动,动态应用部署无法预知容器的IP地址,client端如何发现server端的访问端点?

解决方案(根据客户端是否有感知进行分类)

  • 客户端的发现。client 订阅注册中心,有一个固定的注册中心地址,client订阅某个服务的注册中心,注册中心根据服务的运行状态推送某个服务的访问端点列表给client端。 该方案的实现举例有dubbo,DNS的解析等。
  • 服务端的发现。服务端提供某个服务固定的访问端点,客户端直接访问该端点即可达到与服务端通信的目的,该访问端口对接后端具有动态IP的容器,作为请求的入口,负责请求转发到后端的容器。该方案的实现举例就是各种对后端负载均衡的实现,包括LVS/Nginx/HAProxy等。我们可以认为如下公式基本成立
    "服务端的发现" = "负载均衡器" + "路由配置自动更新"

对比客户端的发现,服务端发现对客户端无感知,由于很多已有的应用或者系统并不是按照类似Dubbo这种服务化的框架实现的,这些应用或者系统的客户端对服务发现都是无感知的,因此服务端的发现就表现出了独特的优势。客户端的服务发现方法中,DNS是一个例外,几乎所有的客户端都支持DNS。下面介绍客户端DNS和服务端的负载均衡器做服务发现的几个方案。

服务发现方案

  • DNS解析到多个IP

    • 优点:Docker 版本大于1.10即原生支持容器集群内部DNS的服务发现。
    • 缺点:由于DNS TTL生效时间的存在,解析的结果不能做到实时,即使TTL设置为0,某些应用或者方法库会缓存DNS解析的结果,导致会解析到已经失效的地址上
  • 内核空间 LVS/IPVS

    • 优点:IPVS的方案是docker在未来会正式发布的1.12版本中采用的方案,主要是做到了4层的负载均衡,请求的转发实现在内核中,不需要二次拷贝请求和响应的内容,不需要解析和处理7层HTTP协议,效率高
    • 缺点:缺少7层负载均衡的支持,一个服务的负载均衡会占用主机的一个端口,服务与服务之间暴露的端口如果相同会产生冲突
  • 用户空间 Nginx

    • 优点:同时支持4层和7层负载均衡的代理,多进程模型方便利用多核性能,具有cache功能,亦可作为静态文件web服务器,7层可以根据区分HOST字段来复用同一个80端口,解决端口冲突的问题。7层负载会解析HTTP协议,支持多层路由,包括根据域名不同进行路由,根据路径不同进行路由,内部重定向等多种HTTP协议层的功能。
    • 缺点:负载均衡调度算法较少,对后端进行健康检查的策略较少
  • 用户空间 HAProxy

    • 优点:同时支持用户空间4层和7层负载均衡的代理,是一个纯粹的软负载均衡器,支持Round-Robin,static-rr,least-conn,source-IP等多种调度算法,对后端进行健康检查的策略完备,包括TCP端口检查,HTTP请求检查,可执行程序检查等带外检查。7层可以根据区分HOST字段来复用同一个80端口,解决端口冲突的问题。7层负载会解析HTTP协议,支持多层路由,包括根据域名不同进行路由,根据路径不同进行路由,内部重定向等多种HTTP协议层的功能。
    • 缺点:不能作为静态文件服务器,不支持cache缓存功能

aliyun容器服务的负载均衡解决方案

经过前面优缺点的分析和结合aliyun自身产品的优势,提供了以下解决方案。

  • docker自带的DNS 服务发现,只要docker版本大于1.10(目前阿里云支持的docker最新版本为1.11),就支持DNS的服务发现。其特点是为1)每个容器提供独立的DNS解析;2)可以通过容器名与别名(aliases)方式在整个网络作用域内解析到某个容器的IP;3)通过链接别名的方式(link aliases)在容器的作用域内设置DNS解析,好处是不同容器的相同别名不会冲突。4)对外部的DNS解析请求进行代理。如下图所示
  • 4层,提供阿里云的云产品SLB的负载均衡方案,底层是基于LVS做了改造和增强,SLB经受了长期线上实战的考验,稳定性和正确性可以得到保证。同时,容器服务在此基础上能做到监控容器部署的情况,随着服务的启停,动态绑定SLB后端的端口(稍后解释原理)。
  • 7层,提供基于haproxy的负载均衡方案,支持灵活的配置。容器服务在此基础上能做到监控容器部署的情况,随着服务的健康状况,动态调整后端的负载(稍后解释原理)。
  • 虽然我们4层主推SLB来做负载均衡,同时7层主推haproxy来做负载均衡,但是实际上SLB支持7层的负载均衡,底层基于Tengine,而HAProxy也支持用户空间4层的负载均衡,用户可以根据自己的情况,灵活选择/组合方案。
  • SLB做到动态绑定的原理:swarm监听容器的状态,如果容器正常运行,则把容器加入到SLB的后端,如果容器发现异常,则把容器从SLB的后端摘下来。
    SLB_discovery
  • HAProxy实现动态服务发现的原理:HAProxy容器内除了有HAProxy软件,还有脚本程序监听容器的状态,根据容器的健康状况重新生成负载均衡信息,然后重新加载(reload) HAProxy,使得新的负载均衡信息生效。
    haproxy_routing_discovery
  • 实现不停服rolling_update原理:平滑升级的关键在于每一时刻均有至少一个容器还能正常提供服务。1)需要部署多个容器,将容器分为A,B两批更新。2)更新容器时,先将A批容器的路由从SLB或者HAProxy上面摘下来。3) 更新A批容器 4)A批容器健康检查正常后,重新加入路由 5)摘下B批容器的路由 6)更新B批容器。
  • 实现灰度发布原理:不通版本的服务可以共享同一路由信息,通过调整SLB或者HAProxy权重的方式来做到灰度发布。

根据场景提供给用户的服务形态

  • 简单路由服务:基于HAProxy,我们加了一层wrapper,做到动态发现处于运行状态的容器,加入到负载均衡中,我们称之为简单路由服务(routing service),其公网IP通过一个SLB对外进行暴露。主要解决如下需求:

    • 7层服务端点对公网暴露,即承接公网访问集群内使用7层协议的服务的流量。
    • 7层服务端点对内网暴露,即容器集群内的负载均衡和服务发现:如下图所示,集群内的服务发现利用了Docker自带的DNS resolver配合了HAProxy的负载均衡和健康检查。图中的LB即为简单路由服务下的HAProxy容器,1)首先通过Docker自带的DNS resolver将域名restserver.local解析到HAProxy容器的IP,此处会优先选择当前节点的HAProxy容器进行负载均衡;2)RestClient请求域名restserver.local时,请求先走到代理容器LB;3)LB根据从Discovery Service获取到的负载均衡信息代理到提供相应服务的容器后端RestServer Contaienr
      inner_service_discovery
    • 不支持4层的路由
  • 自定义路由服务:作为一个可选的容器,实现跟简单路由服务类似,解决如下需求:

    • 通过环境变量和标签提供强大且灵活的配置支持,同时支持用户基于该容器进行扩展(通过Dockerfile FROM的方式)。
    • 支持用户空间的4层协议转发
  • SLB路由服务:将SLB绑定到某个服务上面,后端随服务的启停动态配置。主要解决如下需求

    • 对外暴露的服务,使用4层协议,通过自定义SLB做4层的转发
    • 容器间的4层或者7层通信,流量特别大时,推荐使用自定义SLB(内网)服务。

场景和对应的路由服务总结

sn_and_ew_communication

layers S-N (ingress 入口通信) E-W (peer to peer 容器间通信)
layer 4 SLB路由服务(公网) 自定义路由服务/SLB路由服务(内网,防止回路问题)
layer 7 简单路由服务 简单路由服务/自定义路由服务

如上述图表所示,我们将容器集群外进入容器集群内的入口通信称为南北通信,将集群内容器和容器之间的流量成为东西通信。我们根据不同的通信形式和协议层提供不同的服务来满足用户的需求,例如对应南北通信,如果是使用7层协议的服务,我们推荐用户使用集群的SLB进行流量转发,最终的流量会转发到每个主机的HAProxy容器上面,然后在分发到相应的处理请求的服务上。

  • 南北通信

    • 指的是整个容器集群入口的通信。南北通信的特点往往是通信量比较大,因此我们首先用SLB将流量分散到各个主机节点。
  • 东西通信

    • 指的是集群内部,容器和容器间的通信方式
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
存储 负载均衡 调度
Docker 多主机部署:构建容器集群的最佳实践,助力高可用性与负载均衡
Docker 多主机部署:构建容器集群的最佳实践,助力高可用性与负载均衡
832 0
|
2月前
|
负载均衡 网络协议 调度
Docker Swarm服务发现与负载均衡
【10月更文挑战第8天】
71 1
|
5月前
|
负载均衡 Kubernetes 算法
K8s服务发现与负载均衡的技术探索
【7月更文挑战第15天】K8s通过Service资源对象和kube-proxy组件实现了高效、灵活的服务发现和负载均衡机制。通过合理选择Service类型、优化kube-proxy配置以及使用Ingress进行高级路由,可以确保应用在K8s集群中高效、可靠地运行。随着云原生技术的不断发展,K8s的服务发现和负载均衡机制也将不断完善和优化,为更多场景提供强大的支持。
|
5月前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
7月前
|
负载均衡 网络协议 算法
【Docker 专栏】Docker 容器内服务发现与负载均衡
【5月更文挑战第8天】本文探讨了Docker容器中的服务发现与负载均衡。服务发现通过环境变量、DNS或集中式系统(如Consul、Zookeeper)来定位服务实例。负载均衡则采用轮询、随机等算法,可通过软件负载均衡器、云服务或容器编排工具(如Kubernetes)实现。服务发现与负载均衡结合使用,确保请求有效分发和系统稳定性。面对动态性、网络延迟及大规模部署的挑战,需采取相应措施优化。选择合适技术并持续优化,能提升Docker容器应用的性能和可靠性。
268 5
【Docker 专栏】Docker 容器内服务发现与负载均衡
|
7月前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。
|
7月前
|
Linux Nacos 数据库
Linux 通过 Docker 部署 Nacos 2.2.3 服务发现与配置中心
Linux 通过 Docker 部署 Nacos 2.2.3 服务发现与配置中心
|
7月前
|
负载均衡 应用服务中间件 nginx
百度搜索:蓝易云【Docker安装Nginx,并实现负载均衡教程。】
通过按照上述步骤,你就可以使用Docker安装Nginx并实现负载均衡。请确保在创建Nginx配置文件时定义了正确的负载均衡策略,并根据需要进行适当的配置和调整。
151 0
|
7月前
|
负载均衡 应用服务中间件 nginx
Docker配置1台Nginx+3台Tomcat做负载均衡
Docker配置1台Nginx+3台Tomcat做负载均衡
255 0
|
应用服务中间件 nginx 数据中心
docker服务发现
docker服务发现
127 1