Маршрутизация и балансировка трафика
Маршрутизация и балансировка трафика выполняются с помощью протокола BGP и сервиса HAProxy. В качестве клиента выступает пользователь или сервис, инициирующий запрос к сервису Платформы. Пользовательский трафик обрабатывается Public HAProxy, а межсервисное взаимодействие — Private HAProxy.
Маршрутизация и балансировка трафика выполняются в следующем порядке:
- На уровне BGP выполняется:
- На уровне HAProxy:
- Для Public HAProxy выполняется:
- Для Private HAProxy выполняется:
- DNS-разрешение имени.
- Маршрутизация и путь до HAProxy:
- Если сервис на том же управляющем узле.
- Если сервис вне управляющего узла.
- Напрямую к подам Kubernetes (без HAProxy, если применимо).
- Обработка запросов через HAProxy.
Механизм BGP-анонсов формирует основу для организации подключений пользователей и сервисов.
BGP — динамический протокол маршрутизации, который выполняет балансировку HAProxy по IP-адресу.
Принцип работы BGP-анонсов приведен на рисунке 1.
Если в инсталляции есть RS-узел, он участвует в распространении анонсов (рисунок 2).
Перечень участников BGP-сети на стороне Платформы зависит от готовности управляющих узлов принимать соединения. На Платформе реализованы проверки доступности зависимых HAProxy-сервисов. В зависимости от результата приложение ExaBGP либо публикует, либо отзывает (не публикует) назначенные ему анонсы.
Для ExaBGP проверка доступности HAProxy выполняется через health-порты:
-
Для Private HAProxy используется порт
9005:# less /etc/private_haproxy/haproxy.cfg...frontend healthcheckmode httpbind 10.30.3.8:9005monitor-uri /healthcheck...# cat /etc/exabgp/private_haproxy.conf...interval = 5command = curl -sf http://10.30.3.8:9005/healthcheck...# netstat -nltp | grep 9005tcp 0 0 10.30.3.8:9005 0.0.0.0:* LISTEN 2400826/haproxy -
Для Public HAProxy используется порт
9000:# less /etc/public_haproxy/haproxy.cfg...frontend healthcheckmode httpbind 10.30.3.8:9000monitor-uri /healthcheck...# cat /etc/exabgp/public_haproxy.conf...interval = 1command = curl -sf http://10.30.3.8:9000/healthcheck...# netstat -nltp | grep :9000tcp 0 0 10.30.3.8:9000 0.0.0.0:* LISTEN 2400015/haproxy
Проверка Private HAProxy выполняется раз в 5 секунд, а Public HAProxy — каждую секунду.
Если в ExaBGP перестанут проходить успешные health-проверки, то анонс с этого сервера в BGP перестанет публиковаться, и пользовательский трафик на этот узел идти не будет. Нагрузка распределится на остальные управляющие узлы.
В Kubernetes проверка доступности построена на механизме Calico. Сервис calico-kube-controllers взаимодействует с API Kubernetes при сбоях или изменении конфигурации сети и обновляет BGP-конфигурацию на подах демона calico-node. Демон расположен на каждом узле Kubernetes и выполняет роль BGP-спикера.
Если на одном из узлов кластера Kubernetes произойдет сбой, поды Kubernetes будут перемещены на доступные узлы, и анонсы будут скорректированы с исключением узла, вышедшего из строя.
# calicoctl get nodes -o wide
Пример результата:
NAME ASN IPV4cpn001 (65433) 10.30.3.6/24cpn002 (65433) 10.30.3.7/24cpn003 (65433) 10.30.3.8/24
Все анонсы публикуются через сеть Management. Для этого необходимо обеспечить двусторонний доступ к BGP-соседу по порту 179.
На каждый из управляющих узлов выделяется по два IP-адреса в сети Management, чтобы обеспечить работу двух BGP-спикеров:
- Основной адрес используется для взаимодействия внутренних сервисов продукта. Через него работает Kubernetes, кластеризуются базы данных, выполняется обмен данными между сервисами. Также он используется для BGP-анонсов Calico.
- Дополнительный IP-адрес используется для ExaBGP.
# ip a | grep 10.30.3inet 10.30.3.8/24 brd 10.30.3.255 scope global eth0 # Основной IP-адресinet 10.30.3.113/24 brd 10.30.3.255 scope global secondary eth0:1 # Дополнительный IP-адрес
ExaBGP и Calico анонсируют один автономный номер (AS), но наборы маршрутов различаются. Для BGP-сессии по порту 179 требуются разные IP-адреса, иначе возникает конфликт при прослушивании одного порта.
RS (Route Reflector) — узел для поддержания BGP-анонсов. Позволяет администратору Платформы управлять BGP-соединениями. Имеет отдельный автономный номер (AS).
Наличие узла опционально, поскольку его функцию может выполнять часть корпоративной сети. В таком случае диагностика и управление настройками BGP находятся в зоне ответственности сетевых инженеров заказчика.
При настройке ExaBGP и Calico RS-узел является ближайшим соседом. Он получает маршруты от ExaBGP и Calico и передает их на маршрутизатор BGP.
На RS-узле работает приложение GoBGP.
# netstat -ntlp | grep :179tcp 0 0 10.30.3.19:179 0.0.0.0:* LISTEN 28264/gobgpd# systemctl status gobgpd● gobgpd.service - GoBGP Routing DaemonLoaded: loaded (/usr/lib/systemd/system/gobgpd.service; enabled; vendor preset: disabled)Active: active (running) since ...Main PID: 28264 (gobgpd)...# gobgp neighborPeer AS Up/Down State |#Received Accepted10.30.3.6 65433 4d 04:06:51 Establ | 8 810.30.3.8 65433 4d 04:03:55 Establ | 8 810.30.3.113 65433 4d 04:16:18 Establ | 6 610.30.3.112 65433 02:49:38 Establ | 6 610.30.3.111 65433 17:27:31 Establ | 6 610.30.3.7 65433 02:48:32 Establ | 8 810.30.3.22 65431 4d 04:16:20 Establ | 60 60
GoBGP позволяет получать подробную статистику по каждому BGP-соседу (пиру):
# gobgp neighbor 10.30.3.111
Пример результата:
BGP neighbor is 10.30.3.111, remote AS 65433, route-reflector-clientBGP version 4, remote router ID 10.30.3.111BGP state = ESTABLISHED, up for 17:32:41BGP OutQ = 0, Flops = 0Local address is 10.30.3.19, local ASN: 65435Hold time is 5, keepalive interval is 1 secondsConfigured hold time is 90, keepalive interval is 30 secondsNeighbor capabilities:multiprotocol:ipv4-unicast: advertised and receivedroute-refresh: advertised4-octet-as: advertised and receivedRoute statistics:Advertised: 46Received: 6Accepted: 6
Все исходящие анонсы поступают на маршрутизатор BGP. От них он получает необходимые маршруты.
Если в инсталляции нет RS-узла, анонсы поступают на маршрутизатор BGP напрямую от ExaBGP и Calico. Если в инсталляции есть RS-узел, он получает маршруты от ExaBGP и Calico, и анонсы приходят от его имени.
Пример вывода на маршрутизаторе:
$ sudo vtysh -c "show ip bgp" | grep 65433*> 10.16.8.192/26 10.30.3.8 0 65433 i*> 10.30.4.3/32 10.30.3.6 100 0 65433 i*> 10.30.4.4/32 10.30.3.7 100 0 65433 i*> 10.30.4.5/32 10.30.3.8 100 0 65433 i*> 10.30.6.3/32 10.30.5.12 100 0 65433 i*> 10.30.6.4/32 10.30.5.13 100 0 65433 i*> 10.30.6.5/32 10.30.5.14 100 0 65433 i*> 10.220.0.0/26 10.30.3.6 0 65433 i*> 10.220.0.64/26 10.30.3.6 0 65433 i*> 10.220.0.128/26 10.30.3.6 0 65433 i*> 10.220.0.192/26 10.30.3.6 0 65433 i*> 10.220.1.64/26 10.30.3.6 0 65433 i*> 10.220.1.128/26 10.30.3.6 0 65433 i*> 10.220.1.192/26 10.30.3.6 0 65433 i
По выводу команды видно распределение промежуточных узлов (next hop) для различных анонсов:
- Для анонсов в сетях Public и Private промежуточные узлы распределяются по управляющим узлам. В штатном режиме распределение пользовательского трафика должно быть равномерным.
- Для анонсов, связанных с подами Kubernetes, в качестве промежуточного узла указывается один из управляющих узлов. Трафик к подсети идет через него. При недоступности выбранного промежуточного узла используется другой адрес. Хотя весь пользовательский трафик идет через один управляющий узел, учитывая его малый объем, такая архитектура является приемлемой.
Полученные по BGP маршруты сосед может распространить на другие маршрутизаторы. На рисунке 1 выделены два маршрутизатора:
- Users — один или несколько маршрутизаторов, которые обеспечивают связь от сетей конечных пользователей до сети Public API Transport (Portal) с последующим доступом до адресов Public API Loopbacks.
- Management — один или несколько маршрутизаторов, которые обеспечивают связь между сервисными подсетями Management с последующим доступом до адресов Private API Loopbacks и других сервисных сетей.
Технически маршрутизаторы BGP, Users и Management могут быть реализованы на одном устройстве. Но из‑за различия чувствительности данных в сети рекомендуется использовать отдельные маршрутизаторы для физической сегментации трафика.
На каждый маршрутизатор передаются все маршруты, но использоваться будут не все. Например, пользователи не имеют прямого доступа к сети Private API Loopbacks. Поэтому доступ ограничивают средствами межсетевого экрана и списками разрешенных соединений (адреса и правила задаются в Паспорте инсталляции).
HAProxy — сервис балансировки сетевых соединений. На Платформе две группы таких сервисов:
- Public HAProxy — обеспечивает прием соединений от конечных пользователей. Доступен из корпоративной сети. Например, когда пользователь переходит на Портал самообслуживания, он подключается к Public HAProxy.
- Private HAProxy — обеспечивает прием соединений от внутренних сервисов. Доступен из сети Management. Private HAProxy недоступен для пользователей, но системный администратор может использовать его для диагностики Платформы.
Принцип работы Public HAProxy приведен на рисунке 3.
При обращении к веб-интерфейсу Платформы DNS-сервер преобразует FQDN в IP-адрес.
Клиент получает три адреса из сети Public API Loopbacks:
$ nslookup lk.private.infra.devmail.ru
Пример результата:
Server: 127.0.0.53Address: 127.0.0.53#53Non-authoritative answer:Name: lk.private.infra.devmail.ruAddress: 10.30.6.4Name: lk.private.infra.devmail.ruAddress: 10.30.6.5Name: lk.private.infra.devmail.ruAddress: 10.30.6.3
При каждом запросе клиент с равной вероятностью использует один из трех IP-адресов.
Трафик проходит по цепочке маршрутизаторов и попадает на маршрутизатор, который непосредственно связан с сетью Public API Transport. На этом маршрутизаторе должны быть настроены маршруты до IP-адресов сети Public API Loopbacks через сетевые интерфейсы управляющего узла в сети Public API Transport:
$ route -n...10.30.6.3 10.30.5.12 255.255.255.255 UGH10.30.6.4 10.30.5.13 255.255.255.255 UGH10.30.6.5 10.30.5.14 255.255.255.255 UGH...
В приведенном примере маршрутизатор доставляет пакеты по следующим правилам:
- Если DNS вернул адрес
10.30.6.3, пакет направляется на10.30.5.12(первый управляющий узел). - Если DNS вернул адрес
10.30.6.4, пакет направляется на10.30.5.13(второй управляющий узел). - Если DNS вернул адрес
10.30.6.5, пакет направляется на10.30.5.14(третий управляющий узел).
Так обеспечивается балансировка: клиент с равной вероятностью использует один из IP-адресов сети Public API Loopbacks, а выбранный адрес определяет целевой управляющий узел.
На узле назначения клиент устанавливает соединение с одним из адресов Public API Loopbacks и нужным портом. Сервисы в Public HAProxy принимают соединения на всех адресах сети Public API Loopbacks и затем, по правилам маршрутизации, устанавливают отдельное исходящее соединение с целевым сервисом.
Конфигурация Public HAProxy хранится в файле /etc/public_haproxy/haproxy.cfg и состоит из двух основных типов секций:
- Фронтенд (
frontend): определяет, где и как принимать соединения (адреса/порты), какие ACL применить и в какой бэкенд направлять трафик. - Бэкенд (
backend): определяет, как подключаться к целевому сервису (адрес и набор параметров).
Часть бэкендов расположена в директории /etc/public_haproxy/conf.d/:
# ls /etc/public_haproxy/conf.d/public_keystone_admin.cfg public_bff-admin.cfg ...public_keystone_public.cfg public_mcs-admin-ui.cfg ...
Правила, по которым запрос направляется в эти бэкенды, находятся в секции mcs-https-incoming backends файла /etc/public_haproxy/haproxy.cfg. Пример:
# less /etc/public_haproxy/haproxy.cfg...# mcs-https-incoming backends >>>use_backend admin-solar-helium if { hdr(host) -i admin.private.infra.devmail.ru } { path_beg /front_endpoints/solar-helium/ }...use_backend audit-admin-vkcloud if { hdr_end(host) -i lk.private.infra.devmail.ru } { path_beg /audit/admin }...
Бэкенды HAProxy можно разделить на следующие группы:
-
Направленные в systemd-сервис. Целевое приложение запущено как systemd-сервис и принимает подключения на порту по IP-адресу в сети Management одного из управляющих узлов. В бэкенде указан список всех управляющих узлов, поэтому HAProxy выбирает один из них и распределяет трафик между ними. По такой схеме работает Nova API.
Пример бэкенда для Nova API:
# less /etc/public_haproxy/haproxy.cfg...backend nova_compute_api_clusterhttp-request replace-uri \/infra\/compute(.*) /\1http-request set-header X-Forwarded-Proto https if { ssl_fc }timeout server 600stimeout http-request 10scapture request header x-req-id len 16capture request header Host len 32capture request header Referer len 128capture request header X-MCS-Request-Id len 64fullconn 2000server cpn001 10.30.3.6:8774 weight 1 check inter 10s fastinter 2s downinter 3s rise 3 fall 3 minconn 100 maxconn 500server cpn002 10.30.3.7:8774 weight 1 check inter 10s fastinter 2s downinter 3s rise 3 fall 3 minconn 100 maxconn 500server cpn003 10.30.3.8:8774 weight 1 check inter 10s fastinter 2s downinter 3s rise 3 fall 3 minconn 100 maxconn 500 -
Направление в Kubernetes-сервис. Для сервиса нельзя зафиксировать один IP, так как адреса сервисов динамические. Поэтому HAProxy определяет имя сервиса через CoreDNS и подключается по FQDN.
В HAProxy для этого настроен сервис, указывающий на CoreDNS. С точки зрения HAProxy это обычный DNS-сервер. Пример:
...resolvers kubedns-kubenameserver dns1 10.16.8.228:53resolve_retries 10timeout resolve 3stimeout retry 3shold other 20shold refused 20shold nx 20shold timeout 20shold valid 30shold obsolete 30s...Здесь
10.16.8.228:53— адрес ClusterIP сервисаkube-dns(CoreDNS) в Kubernetes:# kubectl -n kube-system get service | grep 10.16.8.228kube-dns ClusterIP 10.16.8.228 <none> 53/UDP,53/TCP,9153/TCP 4d6hСервис работает как DNS с логикой разрешения имен Kubernetes: имя сервиса, пространство имен, суффикс кластера и прочее.
В бэкенде задаются FQDN в формате Kubernetes и порт. Пример:
backend solar-staticmode httpoption forwardfor header X-Real-IPoption http-server-closecapture request header x-req-id len 16capture request header Host len 32capture request header Referer len 32capture request header X-MCS-Request-Id len 64timeout client 2mtimeout server 2mtimeout http-request 10shttp-request replace-path \/solar-static\/(.*) /\1server-template solar-static-app1_ 1-2 solar-static-app-headless.mcs-front-vkcloud.svc.kube:8524 check inter 2s fastinter 1s downinter 1s resolvers kubedns-kube init-addr last,none
Принцип работы Private HAProxy приведен на рисунке 4.
По аналогии с пользовательским сценарием при обмене запросами между сервисами сначала выполняется DNS-разрешение внутреннего имени. По умолчанию используется internal.private.infra.devmail.ru.
В конфигурации сервисов это имя обычно указывают как адрес для подключения к Private HAProxy.
DNS возвращает три IP-адреса из сети Private API Loopbacks. Маршруты к ним были доставлены BGP-анонсами.
# nslookup internal.private.infra.devmail.ru
Пример результата:
Server: 127.0.0.53Address: 127.0.0.53#53Non-authoritative answer:Name: internal.private.infra.devmail.ruAddress: 10.30.4.4Name: internal.private.infra.devmail.ruAddress: 10.30.4.3Name: internal.private.infra.devmail.ruAddress: 10.30.4.5
Балансировка за счет ответа DNS относится к сервисам вне управляющих узлов. Подробнее о балансировке на управляющем узле — в разделе Сервис на том же управляющем узле.
В конфигурациях разных сервисов встречаются и другие FQDN:
- Формат
memcached-0.query.dc1.compute— формат Consul. - Формат прямого IP (например,
10.30.10.15) — адрес сервера без FQDN.
Такие обращения выполняются в обход HAProxy.
Поскольку все IP-адреса в сети Private API Loopbacks уже представлены на управляющем узле, на этом этапе трафик не покидает узел и подключается к одному из локальных IP-адресов и необходимому порту:
# ip a | grep 10.30.4inet 10.30.4.5/32 scope global loinet 10.30.4.4/32 scope global loinet 10.30.4.3/32 scope global lo# netstat -na | grep 10.30.4...tcp 0 0 10.30.4.3:6443 10.30.4.3:55076 ESTABLISHED 2400826/haproxytcp 0 0 10.30.4.5:3279 10.30.4.5:54792 ESTABLISHED 2400826/haproxy...
В отличие от Public HAProxy, соединение устанавливается с Private HAProxy на локальном узле, независимо от IP-адреса, возвращенного DNS.
Если на узле недоступен процесс Private HAProxy, виртуальные адреса Private API Loopbacks удаляются с интерфейса lo. После этого трафик идет на соседний управляющий узел, поэтому сервисы продолжают работать:
# systemctl stop private_haproxy# ip a | grep 10.30.4# traceroute 10.30.4.5traceroute to 10.30.4.5 (10.30.4.5), 30 hops max, 60 byte packets1 * * *2 internal.private.infra.devmail.ru (10.30.4.5) 0.732 ms 0.697 ms 0.910 ms
Если сервис обращается к Private HAProxy, но сам он не находится на управляющем узле, он получает IP-адрес из сети Private API Loopbacks и устанавливает соединение с этим адресом. Для узла вне подсети назначения трафик передается через шлюз по умолчанию:
# traceroute 10.30.4.3traceroute to 10.30.4.3 (10.30.4.3), 30 hops max, 60 byte packets1 _gateway (10.30.3.22) 0.744 ms 0.689 ms *2 * * internal.private.infra.devmail.ru (10.30.4.3) 1.595 ms
Маршрутизатор использует маршруты, полученные ранее через BGP-анонсы. Логика выбора узла совпадает с описанной для Public HAProxy:
- Если DNS вернул
10.30.4.3, маршрутизатор доставляет пакет на10.30.3.6(первый управляющий узел). - Если DNS вернул
10.30.4.4, маршрутизатор доставляет пакет на10.30.3.7(второй управляющий узел). - Если DNS вернул
10.30.4.5, маршрутизатор доставляет пакет на10.30.3.8(третий управляющий узел).
Выбранный IP-адрес определяет, на какой управляющий узел попадет запрос. Так достигается равномерная балансировка нагрузки.
Сервисы за пределами управляющего узла могут подключаться напрямую к подсети сервисов или подсети подов Kubernetes на управляющих узлах. В этом случае HAProxy не участвует: для некоторых сервисов (например, RabbitMQ и Memcached) внешняя балансировка не подходит по архитектуре.
Пример адресов, которые могут быть указаны в конфигурации сервисов на внешнем узле:
...transport_url = rabbit://openstack:XXX@nova-rabbitmq.query.dc1.compute:5672...memcached_servers = memcached-0.query.dc1.compute:11211,memcached-1.query.dc1.compute:11211,memcached-2.query.dc1.compute:11211...
После DNS-разрешения эти адреса указывают на IP-адреса из подсетей Kubernetes.
Указанные IP-адреса отображаются в кластере Kubernetes как адреса подов:
# kubectl get pods -A -o wide | grep -e memcached -e rabbitmqmemcached-vkcloud memcached-memcached-0-796695747b-ndh5r 1/1 Running 0 4d17h 10.220.1.196 cpn001 <none> <none>memcached-vkcloud memcached-memcached-1-89b8fb699-gsx5f 1/1 Running 0 22h 10.220.0.61 cpn002 <none> <none>memcached-vkcloud memcached-memcached-2-796d4486-v6btz 1/1 Running 0 4d17h 10.220.0.64 cpn003 <none> <none>rabbitmq rabbitmq-nova-0 1/1 Running 0 4d17h 10.220.1.198 cpn001 <none> <none>rabbitmq rabbitmq-nova-1 1/1 Running 0 22h 10.220.0.3 cpn002 <none> <none>rabbitmq rabbitmq-nova-2 1/1 Running 0 22h 10.220.0.66 cpn003 <none> <none>
Чтобы сервис вне управляющего узла мог подключиться к таким сервисам, в BGP анонсируются подсети сервисов и подов Kubernetes.
Трафик следует по цепочке, аналогичной маршруту к HAProxy, но без участия HAProxy — соединение устанавливается непосредственно с подсетью подов Kubernetes:
[Nova Compute] -> [DNS-разрешение memcached-1 в 10.220.0.61] -> [10.30.3.50] -> [Маршрутизатор Management] ->-> [Отработка маршрута до IP управляющего узла] -> [10.30.3.6] -> [Маршрутизация внутри управляющего узла] ->-> [10.220.0.0/26] -> [10.220.0.61:11211]
На этом пути балансировка нагрузки между управляющими узлами не выполняется. Сначала трафик поступает на один из них, после входа в подсеть подов пакет доставляется нужному узлу средствами Kubernetes.
Обработка запросов через Private HAProxy во многом аналогична Public HAProxy (подробнее — в разделе Обработка запросов через HAProxy).
Сервисы в Private HAProxy также принимают соединения на все адреса сети Private API Loopbacks.
Конфигурация Private HAProxy хранится в файле /etc/private_haproxy/haproxy.cfg и состоит из секций frontend и backend.
Для HTTP-запросов в Private HAProxy основным механизмом являются ep-соединения.
В VK Private Cloud на DNS-сервере настраивается A-запись вида *.ep.private.infra.devmail.ru → 10.30.4.3, 10.30.4.4, 10.30.4.5. Wildcard дублирует IP-адреса сети Private API Loopbacks с префиксом ep. Любая подстрока вместо * направляет трафик на Private HAProxy:
# nslookup policy-service-s2s.ep.private.infra.devmail.ruServer: 127.0.0.53Address: 127.0.0.53#53Non-authoritative answer:policy-service-s2s.ep.private.infra.devmail.ru canonical name = internal.private.infra.devmail.ru.Name: internal.private.infra.devmail.ruAddress: 10.30.4.5Name: internal.private.infra.devmail.ruAddress: 10.30.4.3Name: internal.private.infra.devmail.ruAddress: 10.30.4.4
Подстроку, которую сервис указывает вместо *, HAProxy использует как ключевое слово в имени бэкенда. Пример настройки:
...frontend service_https_clusterbind 10.30.4.3:443 ssl crt /etc/private_haproxy/ssl/bind 10.30.4.4:443 ssl crt /etc/private_haproxy/ssl/bind 10.30.4.5:443 ssl crt /etc/private_haproxy/ssl/option httplogoption httpcloseacl hdr_xrealip_set req.hdr(X-Real-IP) -m foundhttp-request set-header X-Real-IP %[src] unless hdr_xrealip_settimeout http-request 5scapture request header x-req-id len 16capture request header Host len 32capture request header Referer len 32capture request header X-MCS-Request-Id len 64# Исключения из ep-механизмаuse_backend services-manager-proxy-admin if { path_beg /services-manager-proxy } { hdr_end(host) -i admin.private.infra.devmail.ru }#backend by cname routinguse_backend %[req.hdr(host),lower,field(1,'.')]-ep if { hdr_sub(host) -i .ep.private.infra.devmail.ru }frontend service_http_clusterbind 10.30.4.3:80bind 10.30.4.4:80bind 10.30.4.5:80option httplogoption http-server-closecookie WEBSVR inserttimeout server 660stimeout http-request 10scapture request header x-req-id len 16capture request header Host len 32capture request header Referer len 32capture request header X-MCS-Request-Id len 64# Исключения из ep-механизмаuse_backend katana-collector if { hdr_end(host) -i int-katana.private.infra.devmail.ru }use_backend private_iam_service_public if { path_beg /iam-service/public }#backend by cname routinguse_backend %[req.hdr(host),lower,field(1,'.')]-ep if { hdr_sub(host) -i .ep.private.infra.devmail.ru }...
Для имени вида auth-service-s2s.ep.private.infra.devmail.ru HAProxy выбирает бэкенд auth-service-s2s-ep и проксирует трафик по его правилам:
# cat /etc/private_haproxy/conf.d/private_auth_service_s2s.cfgbackend auth-service-s2s-epmode httpoption forwardfor header X-Real-IPoption http-server-closecapture request header x-req-id len 16capture request header Host len 32capture request header Referer len 32capture request header X-MCS-Request-Id len 64timeout client 2mtimeout server 2mtimeout http-request 10sserver-template auth-service-s2s-api1_ 1-2 auth-service-s2s-api-headless.mcs-back-vkcloud.svc.kube:80 check inter 2s fastinter 1s downinter 1s resolvers kubedns-kube init-addr last,none
Так сокращается объем секций frontend в конфигурации Private HAProxy. Подключение нового сервиса сводится к добавлению или изменению файла бэкенда. Файлы конфигурации таких бэкендов хранятся в директории /etc/private_haproxy/conf.d/.
Остальная настройка Private HAProxy аналогична настройке Public HAProxy: те же шаблоны для целей за пределами балансировщика (сервис systemd или объект Kubernetes), правила ACL и разрешение имен через DNS кластера (CoreDNS).