Route Health Injection
Как автоматически снимать BGP-анонс VIP-адреса с Application Delivery Controller, когда связанные с ним upstream недоступны.
|
В статье описан сценарий с BGP, но этот подход может использоваться и с другими протоколами динамической маршрутизации. |
Что это
RHI (Route Health Injection) — механизм, который управляет анонсом маршрутов на основе состояния upstream в Application Delivery Controller.
Он нужен, чтобы наша система переставала получать трафик для VIP, если за ней нет доступных бэкендов. Когда upstream становятся недоступны, RHI удаляет VIP-адрес с интерфейса, за которым следит динамический маршрутизатор. После этого маршрут перестаёт анонсироваться. Когда upstream восстанавливаются, RHI возвращает VIP на интерфейс, и анонс снова появляется.
Когда пригодится
Предположим, ваш сервис обслуживают несколько дата-центров (ДЦ) в разных городах. В каждом стоит Application Delivery Controller, а запросы пользователей попадают в ближайший ДЦ через Anycast и BGP-анонсы одного и того же VIP-адреса.
Если в каком-то ДЦ все ваши бэкенды стали недоступны, RHI снимает анонс VIP с находящегося там Application Delivery Controller. Маршрутизаторы перенаправляют трафик в другие ДЦ, где сервис доступен. В результате пользователи не попадают на недоступный бэкенд и не получают связанные с этим ошибки.
Когда бэкенды восстановятся, RHI вернёт VIP в анонс из этого ДЦ.
Через что реализовано
RHI реализован через отдельный сервис RHI Service.
RHI Service работает как демон под управлением systemd и использует конфигурационный файл /etc/rhi/rhi.yaml. Основные компоненты:
| Компонент | За что отвечает |
|---|---|
|
Опрос состояния upstream, принятие решения об анонсе или отзыве VIP, добавление и удаление адресов на интерфейсе |
Application Delivery Controller |
Предоставление данных о состоянии всех upstream на основе health check |
|
Интерфейс, с которого RHI удаляет/добавляет обратно VIP-адреса в зависимости от состояния upstream |
|
Динамический маршрутизатор, который анонсирует адреса с |
|
|
Как работает
Application Delivery Controller постоянно выполняет health check всех upstream. RHI Service использует эти данные:
-
RHI Serviceс заданным интервалом обращается к API ADC (к эндпоинтам вида/v1/healthcheck/upstreams/<имя>) и узнаёт результаты health check. -
В результатах health check
RHI Serviceвидит, в каких upstream есть хотя бы одна нода в состоянииhealthy. -
RHI Serviceсмотрит конфигурациюvipsи определяет, какие upstream связаны с каждым VIP. -
Для каждого VIP
RHI Serviceопределяет, можно считать его доступным или нет. Для этого применяет условие, заданное вcondition. Есть два варианта:-
all— VIP считается доступным, если в каждом связанном upstream есть хотя бы однаhealthy-нода. -
any— VIP считается доступным, если хотя бы в одном связанном upstream есть хотя бы однаhealthy-нода.
-
-
Если все VIP доступны,
RHI Serviceничего не делает. Если какой-то VIP недоступен,RHI Serviceудаляет его с интерфейсаrhi0. -
BIRD отслеживает адреса на
rhi0. Увидев, что VIP исчез с интерфейса, BIRD перестаёт анонсировать этот маршрут. -
RHI Serviceпродолжает опрашивать API Application Delivery Controller. Если состояние upstream меняется, RHI снова пересчитывает доступность VIP. Когда VIP снова станет доступен,RHI Serviceдобавит его наrhi0, а BIRD подхватит анонс.
|
|
Как настроить
Настройки RHI задаются в файле /etc/rhi/rhi.yaml. Их можно разделить на четыре типа:
-
глобальные настройки,
-
политика недоступности API Application Delivery Controller,
-
VIP и привязка к upstream,
-
условия анонса VIP.
Глобальные настройки
apisix_poll_interval: 3s
apisix_control_url: http://127.0.0.1:9090
apisix_timeout: 5s
interface: rhi0
main_log: /var/log/rhi/main.log
error_log: /var/log/rhi/error.log
| Параметр | Что задаёт |
|---|---|
|
Временной интервал в секундах — как часто RHI будет опрашивать API ADC |
|
Адрес API ADC, из которого RHI получает состояние health checks |
|
Сколько времени RHI ждёт ответ от API ADC, прежде чем считать запрос неуспешным |
|
Интерфейс, с которого RHI удаляет и на который добавляет VIP-адреса |
|
Файл основного журнала RHI |
|
Файл журнала ошибок RHI |
Политика при недоступности API ADC
failure_policy:
control_api_unreachable: withdraw
max_failed_polls: 3
Если API ADC не отвечает, RHI считает неуспешные опросы. После max_failed_polls подряд неудачных опросов применяется действие из control_api_unreachable:
| Значение | Что произойдёт |
|---|---|
|
RHI удалит с интерфейса все VIP-адреса, указанные в его конфигурации. BIRD прекратит их анонсировать. |
|
RHI не будет удалять VIP-адреса с интерфейса. Анонсирование продолжится, даже если API ADC недоступен. |
VIP и привязка к upstream
vips:
- address: 10.0.0.100
description: "Production API"
upstreams:
- "/apisix/upstreams/api"
- address: 10.0.0.101
description: "Admin portal"
upstreams:
- "/apisix/upstreams/auth"
- "/apisix/upstreams/admin"
condition: all
- address: 10.0.0.102
description: "Legacy app"
upstreams:
- "/apisix/upstreams/legacy"
| Параметр | Что задаёт |
|---|---|
|
VIP-адрес, которым RHI управляет на интерфейсе: добавляет его при доступности связанных upstream и удаляет при недоступности. |
|
Описание VIP для администратора. |
|
Список upstream, связанных с этим VIP. По их состоянию RHI будет делать вывод о доступности/недоступности VIP. |
|
Правило, по которому RHI оценивает доступность VIP (возможные значения описаны в разделе Условия анонса VIP). |
Один VIP может зависеть как от одного, так и от нескольких upstream сразу.
Условия анонса VIP
Параметр condition задаёт, как RHI оценивает доступность нескольких upstream.
| Значение | Что означает |
|---|---|
|
VIP должен остаться в анонсе, если у каждого указанного upstream есть хотя бы одна нода в состоянии |
|
VIP должен остаться в анонсе, если хотя бы у одного указанного upstream есть хотя бы одна нода в состоянии |
Если condition не задан, используется all.
Что учесть перед настройкой
rhi0 в примерах — условное имя интерфейса. В рабочей конфигурации используйте имя интерфейса, на который должен смотреть BIRD.
BIRD должен быть настроен так, чтобы анонсировать адреса, добавленные на интерфейс rhi0.
Пример настройки
В этом примере RHI опрашивает API ADC каждые 3 секунды, управляет VIP-адресами на интерфейсе rhi0 и снимает анонсы, если API ADC остаётся недоступным после трёх попыток.
apisix_poll_interval: 3s
apisix_control_url: http://127.0.0.1:9090
apisix_timeout: 5s
interface: rhi0
main_log: /var/log/rhi/main.log
error_log: /var/log/rhi/error.log
failure_policy:
control_api_unreachable: withdraw
max_failed_polls: 3
vips:
- address: 10.0.0.100
description: "Production API"
upstreams:
- "/apisix/upstreams/api"
- address: 10.0.0.101
description: "Admin portal"
upstreams:
- "/apisix/upstreams/auth"
- "/apisix/upstreams/admin"
condition: all
- address: 10.0.0.102
description: "Public app"
upstreams:
- "/apisix/upstreams/app-primary"
- "/apisix/upstreams/app-reserve"
condition: any
Как будет работать эта конфигурация:
-
10.0.0.100— анонсируется, если у upstream/apisix/upstreams/apiесть хотя бы однаhealthy-нода; -
10.0.0.101— анонсируется, если у/apisix/upstreams/authи/apisix/upstreams/adminесть хотя бы по однойhealthy-ноде; -
10.0.0.102— анонсируется, если хотя бы один из upstream/apisix/upstreams/app-primaryили/apisix/upstreams/app-reserveимеетhealthy-ноду.