Хабрахабр

Load Balancers для систем оркестрации

К Load Balancers в системах оркестрации (Kubernetes, Nomad и других) предъявляется больше требований, чем просто балансировка нагрузки. Во-первых, Load Balancer должен уметь читать каталог со списком сервисов, на которые необходимо перенаправлять трафик (или, как вариант, давать возможность сервисам регистрироваться на включение их в трафик). Во-вторых, делать это динамически, т.к. системы оркестрации в любой момент могут увеличить или уменьшить количество реплик сервисов, или переместить их на другие адреса в сети. И, в-третьих, делать это без остановки трафика.

Эти Load Balancers имеют возможность работать с внушительным списком средств оркестрации. В сегодняшнем сообщении я опишу работу с двумя Load Balancers — Traefik и HAProxy. Его ограничения: работает только с http/https протоколами, и работает только с системой оркестрации Nomad. В примерах будет описана работа с системой оркестрации Nomad.
В прошлом сообщении я уже приводил пример Load Balancers — Fabio. Вот их неполный список, взятый с сайта разработчика: Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS,… В отличие от Fabio, Load Balancers Troefik работает с впечатляющим количеством различных систем.

Я продолжу пример из предыдущего сообщения, в котором создавалось несколько реплик сервиса django.

Для интеграции с Nomad (собственно с Consul) необходимо создать файл конфигурации: Traefik можно загрузить с сайта разработчика в виде исполняемого файла для наиболее распространенных операционных систем.

[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

После этого на порте 8080 будет доступен UI Traefik, в котором пока не опубликован ни один сервис. Для публикации сервисов существует несколько способов, которые в конечно счете делают одно и тоже — загружают в систему Traefik данные типа ключ/значение. Мы воспользуемся возможностью задавать пары ключ/значение через tags сервисов. Дополним конфигурационный файл сервиса django параметром tags:

job "django-job" 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. В Troefik разработана гибкая и полная система правил для конфигурирования роутов, включая работу с регулярными выражениями. Перечень параметров для правил в документации разработчика.

Соответственно, можно менять эти параметры, деплоить новый вариант сервиса командой nomad job run nomad/django.conf, и все изменения применятся без досадной остановки трафика. После выполнения команды nomad job run nomad/django.conf правила применятся, и на сервис будет направлен трафик с Load Balancer.

Но все же есть такая вероятность, что возникнет необходимость работать и с другими протоколами. Недостатком Troefik является то что он работает с протоколами семейства http/https (на всякий случай замечу что это семейство включает и веб-сокеты). Какое-то время назад у HAProxy были проблемы с «мягкой» перегрузкой, что делало его использование с системами оркестрации сложным (на время рестарта приходилось на сетевом уровне приостанавливать движение пакетов). Поэтому перейдем к следующему более широкому решению на основе HAProxy. Сейчас это уже не проблема.

Здесь не подойдет вариант с установкой внутри контейнера. Для начала необходимо установить haproxy на компьютер. В haproxy только недавно появилась возможность рестартовать процесс в «мягком» режиме, но при этом все равно контейнер докер останавливается, так как фактически запускается второй процесс с haproxy, просто их смена проходит в режиме ожидания — что не работает с докером и его принципом «один-контейнер-один процесс».

В Nomad (собственно в Consul) применяется система шаблонов, которая может генерировать конфигурации: Для работы haproxy необходимо иметь файл конфигурации, в котором прописаны необходимые правила.

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 по адресу /haproxy?stats.

Код примеров доступен в репозитарии

Полезные ссылки:

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

apapacy@gmail.com
24 февраля 2019 года

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть