Использование HAProxy для включения HA в сервисах ADS

Обзор

HAProxy — сервис ADS, используемый для обеспечения высокой доступности (High Availability, HA), балансировки нагрузок и маршрутизации HTTP/TCP-трафика между серверами.

Данный сервис основан на проекте HAProxy и позволяет эффективно использовать несколько экземпляров серверов в составе кластера (например, несколько компонентов Kafka REST Proxy) за счет распределения входящих HTTP-запросов.

В ADS режим высокой доступности поддерживается для сервисов:

ВАЖНО

Для реализации HA на сетевом уровне можно развернуть несколько экземпляров HAProxy Server.

Конфигурация HAProxy в ADCM

После установки сервиса HAProxy в кластере ADS ADCM автоматически генерирует общую конфигурацию.

Основным конфигурационным файлом является /etc/ads-haproxy/haproxy.cfg. Этот файл генерируется из Jinja-шаблона в ADCM и его не рекомендуется редактировать вручную на хостах.

Для изменения конфигурации HAProxy:

  1. Откройте шаблон haproxy_cfg_template (доступен после активации переключателя Advanced) на странице конфигурирования компонента HAProxy Server (Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration).

  2. Внесите необходимые изменения в шаблон, примените их при помощи кнопки Apply, подтвердите изменения в конфигурации, нажав Save.

  3. После внесения изменений выполните обновление конфигурации сервиса при помощи действия Reload.

    ПРИМЕЧАНИЕ

    Некоторые конфигурационные параметры HAProxy могут быть изменены в интерфейсе ADCM без использования шаблона на странице конфигурирования компонента HAProxy Server (Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration). После изменения значений параметров также требуется обновление конфигурации сервиса.

При запуске сервиса или после обновления конфигурации сервиса итоговый файл /etc/ads-haproxy/haproxy.cfg будет сгенерирован из следующего шаблона:

#jinja2: lstrip_blocks:"True", trim_blocks:"True", keep_trailing_newline: True
# {{ ansible_managed }}
{% set stats_username = haproxy_server_config.haproxy_cfg.listener_stats.haproxy_server_listener_user %}
{% set stats_password = haproxy_server_config.haproxy_cfg.listener_stats.haproxy_server_listener_password %}
{% if ads_ssl_enabled %}
    {% set merged_pem_certificate = haproxy_server_config.haproxy_cfg.haproxy_ssl_frontend %}
    {% set haproxy_ssl_frontend = "ssl crt " ~ merged_pem_certificate | default('/etc/ssl/merged.pem', true) %}
{% endif %}


#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global (1)
    log /dev/log    local0
    chroot      /var/lib/haproxy/
    maxconn     1024
    user        haproxy
    group       haproxy
    daemon
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults (2)
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
#---------------------------------------------------------------------
# HAProxy statistics
#---------------------------------------------------------------------
listen stats (3)
    bind *:{{ haproxy_server_config.haproxy_cfg.listener_stats.haproxy_server_listener_port }} {% if ads_ssl_enabled %} {{ haproxy_ssl_frontend }}{% endif %}

    stats enable
    stats uri /stats
    stats hide-version
    stats auth {{ stats_username }}:{{ stats_password }}
1 Глобальные параметры HAProxy (логирование, директория chroot, SSL и т.д.).
2 Параметры режима HTTP по умолчанию и настройки тайм-аутов.
3 Включает эндпойнт статистики и мониторинга HAProxy (по умолчанию: http://<haproxy_host>:7001/).
Пример итогового конфигурационного файла
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log /dev/log    local0
    chroot      /var/lib/haproxy/
    maxconn     1024
    user        haproxy
    group       haproxy
    daemon
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
#---------------------------------------------------------------------
# HAProxy statistics
#---------------------------------------------------------------------
listen stats
    bind *:7001
    stats enable
    stats uri /stats
    stats hide-version
    stats auth haproxy:haproxy

Подробное описание настроек HAProxy доступно в справочной документации HAProxy.

Высокая доступность Schema-Registry

После установки сервиса HAProxy в кластере ADS ADCM автоматически генерирует конфигурацию для маршрутизации входящих запросов ко всем доступным экземплярам сервиса Schema-Registry дополнительно к общей конфигурации HAProxy.

ВАЖНО

При подключении к сервису в режиме HA клиент Schema-Registry должен подключаться к компоненту HAProxy Server, а не напрямую к серверу. Актуальная ссылка для подключения (Load Balancer (HAProxy) links) доступна в ADCM (Clusters → <ads_cluster_name> → Services → Schema-Registry → Info).

Конфигурационным файлом для настройки подключения к Kafka REST Proxy является /etc/ads-haproxy/conf.d/schema-registry.cfg. Этот файл генерируется из Jinja-шаблона в ADCM и его не рекомендуется редактировать вручную на хостах.

Для изменения конфигурации HAProxy:

  1. Откройте шаблон Schema-Registry HAProxy config template (доступен после активации переключателя Advanced) в группе Listener Schema Registry на странице конфигурирования компонента HAProxy Server (Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration) .

  2. Внесите необходимые изменения в шаблон, примените их при помощи кнопки Apply, подтвердите изменения в конфигурации, нажав Save.

  3. После внесения изменений выполните обновление конфигурации сервиса при помощи действия Reload.

    ПРИМЕЧАНИЕ

    Некоторые конфигурационные параметры HAProxy для настройки подключений к Schema-Registry могут быть изменены в интерфейсе ADCM без использования шаблона на странице конфигурирования компонента HAProxy Server (Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration) в группе Listener Schema Registry. После изменения значений параметров также требуется обновление конфигурации сервиса.

При запуске сервиса или после обновления конфигурации сервиса итоговый файл /etc/ads-haproxy/conf.d/schema-registry.cfg будет сгенерирован из следующего шаблона:

#jinja2: lstrip_blocks:"True", trim_blocks:"True", keep_trailing_newline: True
# {{ ansible_managed }}
{% if ads_ssl_enabled %}
    {% set merged_pem_certificate = haproxy_server_config.haproxy_cfg.haproxy_ssl_frontend %}
    {% set haproxy_ssl_frontend = "ssl crt " ~ merged_pem_certificate | default('/etc/ssl/merged.pem', true) %}
    {% set haproxy_ssl_backend = "ssl verify required ca-file @system-ca" %}
{% endif %}
{% set sr_port = services.schema_registry.config.Main.schema_registry_listener_port%}
{% set sr_group = groups['schema_registry'] %}

# Schema Registry frontend (1)
frontend schema_registry_frontend
    default_backend schema_registry_backend
    http-response add-header X-Backend %s
    bind *:{{ haproxy_server_config.haproxy_cfg.listener_schema_registry.schema_registry_front_port }} {% if ads_ssl_enabled %} {{ haproxy_ssl_frontend }}{% endif %}

# Schema Registry backend (2)
backend schema_registry_backend
    balance {{ haproxy_server_config.haproxy_cfg.listener_schema_registry.haproxy_server_backend_balance }}
    option {{ haproxy_server_config.haproxy_cfg.listener_schema_registry.haproxy_server_backend_option }}
{% if ads_basic_auth_enabled %}
    http-check send hdr Authorization "Basic {{ haproxy_check_auth_b64 }}"
{% endif %}
{% if ads_ssl_enabled %}
    http-send-name-header Host
{% endif %}
    {# # `ipv4@{{ host }}` - Force IPv4 address resolution. Without an explicit IP protocol prefix,
    ALT Linux may resolve FQDN via IPv6 by default. #}
{% for host in sr_group %}
    {% set __host = ("ipv4@" if haproxy_server_config.haproxy_cfg.backend_network.force_ipv4 else "") ~ host %}
    {% set _ssl_settings = '' %}
    {% if ads_ssl_enabled %}
        {% set _ssl_settings = haproxy_ssl_backend ~ ' sni str(' ~ host ~ ')' %}
    {% endif %}
    {#  Server name must stay the host FQDN: http-send-name-header sends it as the Host header,
        and the backend rejects a Host absent from its certificate (400 Invalid SNI). #}
    server {{ host }} {{ __host }}:{{ sr_port }} check inter 10s rise 2 fall 3 {{ _ssl_settings }}
{% endfor %}
1 IP-адреса и порты, к которым клиенты Schema-Registry могут подключаться.
2 Список серверов Schema-Registry, на которые балансировщик нагрузки будет направлять запросы. В цикле {% for host in …​ %} формируется список серверов Schema-Registry, доступных в кластере ADS. balance roundrobin равномерно распределяет запросы между всеми доступными хостами.
Пример итогового конфигурационного файла
# Schema Registry frontend
frontend schema_registry_frontend
    default_backend schema_registry_backend
    http-response add-header X-Backend %s
    bind *:8085
# Schema Registry backend
backend schema_registry_backend
    balance roundrobin
    option httpchk GET /subjects
    server sov-ads-3.ru-central1.internal ipv4@sov-ads-3.ru-central1.internal:8081 check inter 10s rise 2 fall 3
    server sov-ads-2.ru-central1.internal ipv4@sov-ads-2.ru-central1.internal:8081 check inter 10s rise 2 fall 3
    server sov-ads-1.ru-central1.internal ipv4@sov-ads-1.ru-central1.internal:8081 check inter 10s rise 2 fall 3

После установки сервиса HAProxy в кластере ADS для сервиса Schema-Registry автоматически определяются параметры конфигурационного файла /etc/schema-registry/schema-registry.properties, описанные ниже.

Параметр Описание Значение по умолчанию

leader.eligibility

Определяет, может ли конкретный узел (сервер) быть избран лидером (основным) в кластере. Для всех узлов (компонентов Schema-Registry) должно быть установлено значение true

true

schema.registry.group.id

Идентификатор группы потребителей, который использует Schema-Registry для чтения из топика _schemas. Должен быть одинаковым для всех узлов (компонентов Schema-Registry) в кластере

schema-registry

Высокая доступность Kafka REST Proxy

После установки сервиса HAProxy в кластере ADS ADCM автоматически генерирует конфигурацию для маршрутизации входящих запросов ко всем доступным экземплярам сервиса Kafka REST Proxy дополнительно к общей конфигурации HAProxy.

ВАЖНО

При подключении к сервису в режиме HA клиент Kafka REST Proxy должен подключаться к компоненту HAProxy Server, а не напрямую к серверу. Актуальная ссылка для подключения (Load Balancer (HAProxy) links) доступна в ADCM (Clusters → <ads_cluster_name> → Services → Kafka REST Proxy → Info).

Конфигурационным файлом для настройки подключения к Kafka REST Proxy является /etc/ads-haproxy/conf.d/kafka-rest.cfg. Этот файл генерируется из Jinja-шаблона в ADCM и его не рекомендуется редактировать вручную на хостах.

Для изменения конфигурации HAProxy:

  1. Откройте шаблон Kafka REST HAProxy config template (доступен после активации переключателя Advanced) в группе Listener Kafka REST на странице конфигурирования компонента HAProxy Server (Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration) .

  2. Внесите необходимые изменения в шаблон, примените их при помощи кнопки Apply, подтвердите изменения в конфигурации, нажав Save.

  3. После внесения изменений выполните обновление конфигурации сервиса при помощи действия Reload.

    ПРИМЕЧАНИЕ

    Некоторые конфигурационные параметры HAProxy для настройки подключений к Kafka REST Proxy могут быть изменены в интерфейсе ADCM без использования шаблона на странице конфигурирования компонента HAProxy Server(Clusters → <ads_cluster_name> → Services → HAProxy → Components → HAProxy Server → Primary configuration) в группе Listener Kafka REST. После изменения значений параметров также требуется обновление конфигурации сервиса.

При запуске сервиса или после обновления конфигурации сервиса итоговый файл /etc/ads-haproxy/conf.d/kafka-rest.cfg будет сгенерирован из следующего шаблона:

#jinja2: lstrip_blocks:"True", trim_blocks:"True", keep_trailing_newline: True
# {{ ansible_managed }}
{% if ads_ssl_enabled %}
    {% set merged_pem_certificate = haproxy_server_config.haproxy_cfg.haproxy_ssl_frontend %}
    {% set haproxy_ssl_frontend = "ssl crt " ~ merged_pem_certificate | default('/etc/ssl/merged.pem', true) %}
    {% set haproxy_ssl_backend = "ssl verify required ca-file @system-ca" %}
{% endif %}
{% set kafka_rest_port = services.kafka_rest.config.Main.rest_listener_port%}
{% set kafka_rest_group = groups['kafka_rest'] %}

# Kafka REST frontend (1)
frontend kafka_rest_frontend
    default_backend kafka_rest_backend
    http-response add-header X-Backend %s
    bind *:{{ haproxy_server_config.haproxy_cfg.listener_kafka_rest.kafka_rest_front_port }} {% if ads_ssl_enabled %} {{ haproxy_ssl_frontend }}{% endif %}

# Kafka REST backend (2)
backend kafka_rest_backend
    balance {{ haproxy_server_config.haproxy_cfg.listener_kafka_rest.haproxy_server_backend_balance }}
    option {{ haproxy_server_config.haproxy_cfg.listener_kafka_rest.haproxy_server_backend_option }}
{% if ads_basic_auth_enabled %}
    http-check send hdr Authorization "Basic {{ haproxy_check_auth_b64 }}"
{% endif %}
{% if ads_ssl_enabled %}
    http-send-name-header Host
{% endif %}
    {# # `ipv4@{{ host }}` - Force IPv4 address resolution. Without an explicit IP protocol prefix,
    ALT Linux may resolve FQDN via IPv6 by default. #}
{% for host in kafka_rest_group %}
    {% set __host = ("ipv4@" if haproxy_server_config.haproxy_cfg.backend_network.force_ipv4 else "") ~ host %}
    {% set _ssl_settings = '' %}
    {% if ads_ssl_enabled %}
        {% set _ssl_settings = haproxy_ssl_backend ~ ' sni str(' ~ host ~ ')' %}
    {% endif %}
    {# # Server name must stay the host FQDN: http-send-name-header sends it as the Host header,
        and the backend rejects a Host absent from its certificate (400 Invalid SNI). #}
    server {{ host }} {{ __host }}:{{ kafka_rest_port }} check inter 10s rise 2 fall 3 {{ _ssl_settings }}
{% endfor %}
1 IP-адреса и порты, к которым клиенты Kafka REST Proxy могут подключаться.
2 Список серверов Kafka REST Proxy, на которые балансировщик нагрузки будет направлять запросы. В цикле {% for host in …​ %} формируется список серверов Kafka REST Proxy, доступных в кластере ADS. balance roundrobin равномерно распределяет запросы между всеми доступными хостами.
Пример итогового конфигурационного файла
# Kafka REST frontend
frontend kafka_rest_frontend
    default_backend kafka_rest_backend
    http-response add-header X-Backend %s
    bind *:8086
# Kafka REST backend
backend kafka_rest_backend
    balance roundrobin
    option httpchk GET /topics
    server sov-ads-3.ru-central1.internal ipv4@sov-ads-3.ru-central1.internal:8082 check inter 10s rise 2 fall 3
    server sov-ads-2.ru-central1.internal ipv4@sov-ads-2.ru-central1.internal:8082 check inter 10s rise 2 fall 3
    server sov-ads-1.ru-central1.internal ipv4@sov-ads-1.ru-central1.internal:8082 check inter 10s rise 2 fall 3

После установки сервиса HAProxy в кластере ADS для сервиса Kafka REST Proxy автоматически устанавливаются параметры конфигурационного файла /etc/kafka-rest/kafka-rest.properties, описанные ниже.

Параметр Описание Значение по умолчанию

id

Уникальный идентификатор экземпляра Kafka REST Proxy в кластере, при включении режима HA устанавливается в формате kafka-rest-server-<n>

 — 

advertised.listeners

Имена слушателей HAProxy Server в формате <haproxy_fqdn>:<port>. Используются при подключении к сервису Kafka REST Proxy в режиме HA и для генерации корректных URL в ответах API

 — 

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней