Высокая доступность Airflow Server с помощью HAProxy

Начиная с ADO 3.0, компонент Airflow Server использует Airflow API Server для HTTP запросов. API Server предоставляет Airflow Web UI, REST API и Task Execution API, которые используются воркерами.

Для повышения доступности (High Availability, HA) сервиса можно добавить в кластер несколько компонетов Airflow Server. В такой конфигурации приложения Airflow (воркеры, UI, запросы REST API) должны использовать одну точку доступа вместо подключения к отдельным экземплярам Airflow Server. Компонент Airflow Haproxy предоставляет такую точку доступа и направляет запросы к доступным экземплярам Airflow Server.

Для этой цели сервис Airflow включает компонент Airflow Haproxy. Он автоматически генерирует конфигурацию HAProxy на основе топологии кластера и выбранного режима маршрутизации трафика.

Компонент Airflow Haproxy

Компонент Airflow Haproxy работает как обратный прокси между приложениями, использующими Airflow, и экземплярами сервера. Он предоставляет одну HTTP/HTTPS-точку доступа для Airflow Web UI, REST API и запросов от воркеров.

Компонент выполняет проверки доступности и исключает недоступные серверы из маршрутизации запросов. Если текущий сервер становится недоступен, HAProxy может переключить запросы на другой доступный сервер.

Поддерживаются два режима маршрутизации трафика:

  • Аварийное переключение — запросы отправляются на один сервер. Если он становится недоступен, HAProxy переключает запросы на другой доступный сервер. Этот режим включен по умолчанию.

  • Балансировка нагрузки — запросы распределяются между доступными экземплярами Airflow Server.

Для работы Airflow в режиме HA, запросы должны отправляться к точке доступа Airflow Haproxy, а не напрямую к Airflow Server.

Компонент Airflow Haproxy можно установить на одном или нескольких хостах. При развертывании нескольких экземпляров Airflow Haproxy их можно использовать совместно с внешними механизмами HA на сетевом уровне, чтобы исключить хост HAProxy как единую точку отказа.

ПРИМЕЧАНИЕ

Компоненты Airflow Haproxy и Airflow Server должны быть установлены на разных хостах.

Конфигурация Airflow Haproxy

ADCM автоматически генерирует конфигурацию HAProxy при добавлении нескольких экземпляров Airflow Server в кластер. Сгенерированная конфигурация содержит адреса доступных экземпляров Airflow Server и выбранный алгоритм маршрутизации трафика.

Параметры конфигурации Airflow Haproxy доступны в конфигурации сервиса Airflow в ADCM.

Чтобы изменить конфигурацию Airflow Haproxy через ADCM:

  1. На странице Clusters выберите нужный кластер.

  2. Перейдите на вкладку Services и нажмите Airflow.

  3. Перейдите на вкладку Components и выберите Airflow Haproxy.

  4. Выберите необходимый параметр и внесите изменения.

  5. Подтвердите изменения, нажав Save.

  6. В раскрывающемся меню Actions выберите Restart, убедитесь, что для параметра Apply configs from ADCM установлено значение true, и нажмите Run.

Основная конфигурация HAProxy генерируется из Jinja-шаблона haproxy-airflowcfg:

{% set tls_haproxy_pem = '' %}
{%- if airflow_ssl_enable -%}
    {% set service_ssl = services.airflow.haproxy.config.config_properties_ssl | default('', true) | trim %}
    {% set cluster_ssl = cluster.config.ssl_default_config.tls_haproxy_pem | default('', true) | trim %}
    {% if service_ssl %}
        {% set tls_haproxy_pem = 'ssl crt ' ~ service_ssl %}
    {% elif cluster_ssl %}
        {% set tls_haproxy_pem = 'ssl crt ' ~ cluster_ssl %}
    {% endif %}
{% endif %}
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global (1)
    log /dev/log sample 1:10  local0
    log 127.0.0.1:514  local0
    log-tag airflow-haproxy

    chroot      /var/lib/ado-haproxy/airflow
    maxconn     1024
    user        haproxy
    group       haproxy
    daemon

    ssl-server-verify none

#---------------------------------------------------------------------
# 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

listen stats (3)
    bind *:7001 {{ tls_haproxy_pem }}
    stats enable
    stats uri /

frontend airflow_http_in (4)
    bind *:{{ roles_airflow_vars_component_ports['server']['web'] }} {{ tls_haproxy_pem }}
    default_backend airflow_http_servers

backend airflow_http_servers (5)
    balance first

{% for host in haproxy_conf_hosts %}
    {{ host }}
{% endfor %}
1 Глобальные параметры HAProxy, включая параметры логирования, корневая директория chroot, ограничения количества соединений и проверку SSL.
2 Параметры HTTP-режима по умолчанию, параметры логирования, количество повторных попыток и настройки тайм-аутов.
3 Включает эндпоинт статистики HAProxy. Он доступен по адресу http://<haproxy_host>:7001/ или, если включен SSL, по адресу https://<haproxy_host>:7001/.
4 Определяет сокет для HTTP/HTTPS-трафика Airflow.
5 Определяет бекенд, содержащий доступные экземпляры Airflow Server и метод балансировки трафика.
ПРИМЕЧАНИЕ

Параметр haproxy-airflowcfg представляет собой Jinja-шаблон. Он генерируется и применяется ADO. Не редактируйте сгенерированный файл конфигурации непосредственно на хостах Airflow, поскольку изменения, внесенные на хосте, могут быть перезаписаны при изменении конфигурации.

Подробнее о конфигурации HAProxy можно прочитать в документации HAProxy.

Маршрутизация трафика

Режим маршрутизации трафика настраивается в параметрах сервиса Airflow в ADCM. По умолчанию используется режим аварийного переключения.

В режиме аварийного переключения (balance first) HAProxy использует один Airflow Server в качестве активного сервера. Остальные доступные экземпляры серверов являются запасными. Если активный сервер недоступен, Haproxy прекращает отправлять новые запросы на этот сервер и переадресует их на другой доступный экземпляр.

Этот режим подходит, если все запросы должен обрабатывать основной Airflow Server пока он доступен, а остальные экземпляры Airflow Server должны использоваться в качестве запасных.

В режиме балансировки нагрузки (roundrobin) HAProxy распределяет запросы между доступными экземплярами сервера.

Настройки HAProxy повторно генерируется при изменении топологии Airflow Server или конфигурации маршрутизации трафика. Это обеспечивает включение новых экземпляров в маршрутизацию и исключение удаленных или недоступных экземпляров.

Чтобы изменить метод маршрутизации трафика на балансировку нагрузки через ADCM:

  1. На странице Clusters выберите нужный кластер.

  2. Перейдите на вкладку Services и нажмите Airflow.

  3. Перейдите на вкладку Components и выберите Airflow Haproxy.

  4. Выберите параметр haproxy-airflowcfg и измените конфигурацию следующим образом:

    backend airflow_http_servers
        balance roundrobin
  5. Подтвердите изменения, нажав Save.

  6. В раскрывающемся меню Actions выберите Restart, убедитесь, что для параметра Apply configs from ADCM установлено значение true, и нажмите Run.

Доступ к Airflow Web UI и REST API

Точка доступа Airflow Haproxy является общей точкой входа для HTTP-трафика Airflow.

При включенном HAProxy пользователям следует открывать Airflow Web UI через точку доступа HAProxy. Пользователи REST API также должны использовать этот эндпоинт вместо адреса API Server.

Например, REST API-запрос через HAProxy имеет следующий формат:

$ curl --insecure https://<haproxy_host>:<port>/api/v2/<endpoint>

где:

  • <haproxy_host> — хост, на котором установлен компонент Airflow Haproxy;

  • <port> — HTTP- или HTTPS-порт, настроенный для точки доступа Airflow Haproxy;

  • <endpoint> — эндпоинт REST API.

Подробнее о REST API Airflow читайте в статье Подключение к Airflow через REST API.

Та же точка доступа используется для Airflow Web UI. Ссылка на Airflow Web UI доступна на вкладке Info сервиса Airflow в ADCM.

Конфигурация Airflow Worker

Воркеры Airflow используют Task Execution API, предоставляемый Airflow API Server. При использовании компонента Airflow Haproxy воркеры настраиваются на подключение к точке доступа HAProxy через параметр execution_api_server_url.

Это позволяет воркерам продолжать взаимодействовать с Airflow по HTTP, если отдельный экземпляр сервера недоступен.

Конфигурация генерируется автоматически в соответствии с доступными компонентами Airflow Haproxy и Airflow Server. Ручная настройка отдельных хостов воркеров не требуется.

Изменения топологии кластера

ADO автоматически обновляет конфигурацию HAProxy при изменении топологии кластера.

При добавлении сервера его адрес включается в конфигурацию HAProxy. При удалении сервера его адрес удаляется из конфигурации.

Проверки доступности в HAProxy также предотвращают отправку запросов на сервер, который временно недоступен.

Если компонент Airflow Haproxy переносится с одного хоста или кластера на другой, компоненты Airflow Server, затронутые изменением топологии, автоматически перезапускаются. Это необходимо для согласованного применения конфигурации Airflow.

Конфигурация SSL

Компонент Airflow Haproxy поддерживает HTTP- и HTTPS-точки доступа.

Когда для сервиса Airflow включен SSL, Jinja-шаблон определяет расположение сертификата из конфигурации SSL сервиса или, если она не указана, из конфигурации SSL кластера.

Логика выбора сертификата задается в следующих строчках конфигурации:

{% set tls_haproxy_pem = '' %}
{%- if airflow_ssl_enable -%}
{% set service_ssl = services.airflow.haproxy.config.config_properties_ssl | default('', true) | trim %}
{% set cluster_ssl = cluster.config.ssl_default_config.tls_haproxy_pem | default('', true) | trim %}
{% if service_ssl %}
{% set tls_haproxy_pem = 'ssl crt ' ~ service_ssl %}
{% elif cluster_ssl %}
{% set tls_haproxy_pem = 'ssl crt ' ~ cluster_ssl %}
{% endif %}
{% endif %}

Сертификат должен быть представлен в стандартном формате PEM.

Путь к сертификату необходимо указать в опции Specifies the location of the certificate in standard .PEM format в ADCM.

Если указаны оба сертификата, конфигурация сертификата на уровне сервиса имеет приоритет над сертификатом по умолчанию (на уровне кластера).

Логирование

Компонент Airflow Haproxy отправляет логи в выделенный локальный сокет syslog. По умолчанию при использовании rsyslog логи хранятся в /var/log/ado-haproxy/haproxy-airflow.log.

Параметры логирования определяются конфигурацией syslog-ng, представленной ниже:

/etc/syslog-ng/conf.d/haproxy-airflow.conf
source s_haproxy_airflow {
    unix-dgram("/var/lib/ado-haproxy/airflow/dev/log");
};

destination d_haproxy_airflow {
    file("/var/log/ado-haproxy/haproxy-airflow.$YEAR-$MONTH-$DAY.log"
    template("$DATE $FULLHOST $PROGRAM: ${HAPROXY.CLIENT_IPPORT} \\[${HAPROXY.DATE}\\] ${HAPROXY.FRONTEND} ${HAPROXY.BACKEND} ${HAPROXY.TIME} ${HAPROXY.STATUS_CODE} ${HAPROXY.BYTES_READ} ${HAPROXY.COOKIE_REQ} ${HAPROXY.COOKIE_RESP} ${HAPROXY.TERM_STATE} ${HAPROXY.RUN_STATE} ${HAPROXY.QUEUE_STATE} \\{${HAPROXY.HOST}|${HAPROXY.USER_AGENT}\\} \\"${HAPROXY.METHOD} ${HAPROXY.FRONTEND_PROTOCOL}://${HAPROXY.HOST}${HAPROXY.URL} ${HAPROXY.HTTP_VERSION}\\"\n")
    group(adm)
    perm(0640)
    dir_perm(0750)
    template_escape(no)
    );
};

filter f_haproxy_airflow {
    program("haproxy_airflow") or program("haproxy");
};

filter f_haproxy_airflow_ssl {
    message("~ ");
};

rewrite r_haproxy_airflow_set_frontend_protocol {
    set("http", value("HAPROXY.FRONTEND_PROTOCOL") condition(filter(f_haproxy_airflow)));
    set("https", value("HAPROXY.FRONTEND_PROTOCOL") condition(filter(f_haproxy_airflow_ssl)));
};

parser p_haproxy_airflow {
    csv-parser(
        columns(
            "HAPROXY.CLIENT_IPPORT",
            "HAPROXY.DATE",
            "HAPROXY.FRONTEND",
            "HAPROXY.BACKEND",
            "HAPROXY.TIME",
            "HAPROXY.STATUS_CODE",
            "HAPROXY.BYTES_READ",
            "HAPROXY.COOKIE_REQ",
            "HAPROXY.COOKIE_RESP",
            "HAPROXY.TERM_STATE",
            "HAPROXY.RUN_STATE",
            "HAPROXY.QUEUE_STATE",
            "HAPROXY.HEADERS_REQ",
            "HAPROXY.REQUEST"
        )
        flags(escape-double-char, strip-whitespace, greedy)
        delimiters(" ")
        quote-pairs('""[]{}')
        template("${MESSAGE}")
    );
};

parser p_haproxy_airflow_request {
    csv-parser(
        columns(
            "HAPROXY.METHOD",
            "HAPROXY.URL",
            "HAPROXY.HTTP_VERSION"
        )
        delimiters(" ")
        flags(escape-none, greedy)
        template("${HAPROXY.REQUEST}")
    );
};

parser p_haproxy_airflow_headers_req {
    csv-parser(
        columns(
            "HAPROXY.HOST",
            "HAPROXY.USER_AGENT"
        )
        delimiters("|")
        flags(escape-none, greedy)
        template("${HAPROXY.HEADERS_REQ}")
    );
};

log {
    source(s_haproxy_airflow);
    filter(f_haproxy_airflow);
    parser(p_haproxy_airflow);
    parser(p_haproxy_airflow_request);
    parser(p_haproxy_airflow_headers_req);
    rewrite(r_haproxy_airflow_set_frontend_protocol);
    destination(d_haproxy_airflow);
};

Чтобы изменить конфигурацию syslog-ng через ADCM:

  1. На странице Clusters выберите нужный кластер.

  2. Перейдите на вкладку Services и нажмите Airflow.

  3. Перейдите на вкладку Components и выберите Airflow Haproxy.

  4. Выберите параметр /etc/syslog-ng/conf.d/haproxy-airflow.conf.

  5. Внесите необходимые изменения и нажмите Save.

  6. В раскрывающемся меню Actions выберите Restart, убедитесь, что для параметра Apply configs from ADCM установлено значение true, и нажмите Run.

Если вместо syslog-ng используется rsyslog, соответствующая конфигурация хранится в /etc/rsyslog.d/haproxy-airflow.conf.

/etc/rsyslog.d/haproxy-airflow.conf
module(load="imuxsock")
input(type="imuxsock" Socket="/var/lib/ado-haproxy/airflow/dev/log")

# Send HAProxy messages to a dedicated logfile
:programname, startswith, "airflow-haproxy" {
    /var/log/ado-haproxy/haproxy-airflow.log
    stop
}

Чтобы изменить конфигурацию rsyslog через ADCM, выберите параметр /etc/rsyslog.d/haproxy-airflow.conf в конфигурации компонента Airflow Haproxy.

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