编排系统的负载均衡器

编排系统(Kubernetes,Nomad和其他系统)中的负载均衡器不仅具有负载均衡功能,还具有更多要求。 首先,负载均衡器应能够读取目录,其中包含应将流量重定向到的服务列表(或作为一种选择,使服务能够注册以将其包括在流量中)。 其次,动态地进行,因为 编排系统可以随时增加或减少服务副本的数量,或将它们移动到网络上的其他地址。 第三,在不停止流量的情况下做到这一点。

在今天的帖子中,我将介绍如何使用两个负载均衡器-Traefik和HAProxy。 这些负载平衡器能够使用一系列令人印象深刻的编排工具。 这些示例将说明如何使用Nomad编排系统。

一篇文章中,我已经举了一个负载均衡器的示例-Fabio。 它的局限性:仅适用于http / https协议,并且仅适用于Consul。 与Fabio不同,Load Balancers Traefik可与大量不同的系统配合使用。 以下是从开发人员站点中获取的部分列表:Docker,Swarm模式,Kubernetes,Marathon,Consul,Etcd,Rancher,Amazon ECS,...

我将继续上一篇文章中的示例,其中创建了django服务的多个副本。

可以从开发人员的站点下载Traefik,将其作为大多数常见操作系统的可执行文件。 要与Nomad(实际上是Consul)集成,您需要创建一个配置文件:

[entryPoints] [entryPoints.http] address = ":5001" [web] address = ":8080" [consulCatalog] endpoint = "127.0.0.1:8500" domain = "consul.localhost" exposedByDefault = false prefix = "traefik" 

然后使用给定的配置文件运行命令:

 traefik -c nomad/traefik.toml 

之后,UI Traefik将在端口8080上可用,该端口尚未发布任何服务。 有几种发布服务的方法,它们最终会做同样的事情-它们将键/值数据加载到Traefik系统中。 我们将借此机会通过服务标签设置键/值对。 让我们使用tags参数扩展django服务配置文件:

 job "django-job" { datacenters = ["dc1"] type = "service" group "django-group" { count = 3 restart { attempts = 2 interval = "30m" delay = "15s" mode = "fail" } ephemeral_disk { size = 300 } task "django-job" { driver = "docker" config { image = "apapacy/tut-django:1.0.1" port_map { lb = 8000 } } resources { network { mbits = 10 port "lb" {} } } service { name = "django" tags = [ "traefik.enable=true", "traefik.frontend.entryPoints=http", "traefik.frontend.rule=Host:localhost;PathStrip:/test", "traefik.tags=exposed" ] port = "lb" check { name = "alive" type = "http" path = "/" interval = "10s" timeout = "2s" } } } } } 

在此示例中,该服务将在localhost主机上发布并安装在/ test路由上。 Traefik开发了一套灵活而完整的规则系统,用于配置路由,包括使用正则表达式。 开发人员文档中规则的参数列表。

运行nomad job run nomad/django.conf应用规则,并将来自负载均衡器的流量定向到该服务。 因此,您可以更改这些参数,使用nomad job run nomad/django.conf部署新的服务选项,并且将应用所有更改,而不会烦人地阻止流量。

Traefik的缺点是它可以与http / https家族的协议一起使用(以防万一,我注意到该家族还包括Web套接字)。 但是仍然有可能需要与其他协议一起使用。 因此,让我们继续研究基于HAProxy的下一个更广泛的解决方案。 一段时间以前,HAProxy在软加载方面遇到了问题,这使其很难与业务流程系统一起使用(在重新启动期间,有必要在网络级别停止数据包的移动)。 现在,这不再是问题。

首先,您需要在计算机上安装haproxy。 在此,无法在容器内安装选项。 在haproxy中,直到最近才有可能以“软”模式重新启动该进程,但是docker容器仍然停止,因为第二个进程实际上以haproxy开始,所以它只是在待机模式下更改-这不适用于docker及其原理“一个容器是一个过程。”

为了使haproxy起作用,您必须具有一个包含必要规则的配置文件。 Nomad(实际上在Consul中)使用可以生成配置的模板系统:

 global debug defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend http_front bind *:5001 stats uri /haproxy?stats default_backend http_back backend http_back balance roundrobin{{range service "django"}} server {{.Node}} {{.Address}}:{{.Port}} check{{end}} 

在这种情况下, range关键字充当迭代器。 对于三个“ django”服务,将生成以下配置文件:

 global debug defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 frontend http_front bind *:5001 stats uri /haproxy?stats default_backend http_back backend http_back balance roundrobin server 228.195.86.224 127.0.0.1:21469 check server 228.195.86.224 127.0.0.1:25872 check server 228.195.86.224 127.0.0.1:25865 check 

https://github.com/hashicorp/consul-template库用于根据模板动态启动生成过程。 您可以从开发人员的资源中下载所有常见操作系统的可执行文件,并使用以下命令代表未授权用户启动该过程:

 consul-template -template="haproxy/haproxy.cfg.tmpl:haproxy/haproxy.cfg:./haproxy/haproxy.reload.sh" 

-template参数包含用冒号分隔的参数1)模板的名称,2)生成的配置文件的名称3)在生成文件后执行的命令。 如果更改模板中包含的变量(例如,更改django服务的副本数),则将自动生成文件。

启动将生成第一个配置的模板引擎后,可以运行haproxy:

 haproxy -D -f haproxy/haproxy.cfg -p `pwd`/haproxy.pid 

我们明确指定了pid文件,以便能够向“软” haproxy重载发送信号:

 haproxy -D -f ./haproxy/haproxy.cfg -p `pwd`/haproxy.pid -sf $(cat `pwd`/haproxy.pid) 

在此示例中,服务在端口5001上发布。在同一端口上,您可以在地址/haproxy?stats查看haproxy本身的/haproxy?stats

更新02/24/2019 10:43 PM

根据@usego的评论,对docker容器中haproxy的操作进行了进一步改进,特别是根据文档github.com/neo4j/docker-library-docs/tree/master/haproxy#reloading-config中的片段

重新加载配置

如果您对配置使用绑定安装并编辑了haproxy.cfg文件,则可以通过将SIGHUP发送到容器来使用HAProxy的优雅重载功能:

$ docker kill -s HUP my-running-haproxy

映像中的入口点脚本检查是否正在运行命令haproxy,并将其替换为HAProxy上游的haproxy-systemd-wrapper,它负责信号处理以进行正常的重新加载。 在幕后,它使用了haproxy的-sf选项,因此“有两个小窗口,每个小窗口只有几毫秒,在高负载期间可能会注意到一些连接失败”(请参阅​​停止和重新启动HAProxy)。


使用这种方法,实际上是重新加载了配置,但是由于当前进程的中断。 这意味着该服务虽然微不足道,但仍会出现一段不可访问的时间,并且某些客户可能会看到错误消息。 但这有时不是主要的选择标准。 因此,我将另外提供用于在docker中启动haproxy的docker-compose.yml配置:

 version: '3' services: haproxy_lb: image: haproxy volumes: - ./haproxy:/usr/local/etc/haproxy network_mode: host 


使haproxy配置过载的命令也会更改:

 consul-template -template="haproxy/haproxy.cfg.tmpl:haproxy/haproxy.cfg:docker kill -s HUP $(docker-compose ps -q haproxy_lb)" 


此实现的优点包括无需安装代理即可工作的能力。

存储库中提供了示例代码。

有用的链接:

1.www.haproxy.com/blog/haproxy-and-consul-with-dns-for-service-discovery
2.m.mattmclaugh.com/traefik-and-consul-catalog-example-2c33fc1480c0
3.www.hashicorp.com/blog/load-balancing-strategies-for-consul

apapacy@gmail.com
2019年2月24日

Source: https://habr.com/ru/post/zh-CN441534/


All Articles