11. Известные подводные камни, которых следует избегать
Время от времени кто-нибудь сообщает, что после перезагрузки системы служба haproxy не запустилась, но при ручном запуске работает. Чаще всего такие пользователи применяют механизм кластерного IP-адреса, например keepalived, чтобы назначать IP-адрес службы только главному узлу. Пока haproxy был привязан к адресу 0.0.0.0, всё работало, но после привязки к виртуальному IP-адресу запуск перестал удаваться. Причина в том, что при запуске службы виртуальный IP-адрес ещё не принадлежит локальному узлу, и, когда HAProxy пытается к нему привязаться, система отклоняет запрос, поскольку адрес не локальный. Решение состоит не в задержке запуска службы haproxy (это не помогло бы при перезапуске), а в правильной настройке системы, разрешающей привязку к нелокальным адресам. В Linux это легко сделать, установив параметр sysctl net.ipv4.ip_nonlocal_bind в 1. Это также необходимо для прозрачного перехвата IP-трафика, проходящего через HAProxy к определённому адресу назначения.
Многопроцессные конфигурации с диапазонами исходящих портов могут выглядеть работоспособными, но при высокой нагрузке вызывают случайные сбои: несколько процессов могут попытаться использовать один и тот же исходящий порт для подключения к одному серверу, что невозможно. Система сообщит об ошибке, после чего будет выполнена повторная попытка с выбором другого порта. Высокое значение параметра “retries” может в некоторой степени скрыть этот эффект, но также увеличивает загрузку CPU и время обработки. В журналах тоже будет отражено некоторое число повторных попыток. Поэтому в многопроцессных конфигурациях следует избегать диапазонов портов.
Поскольку HAProxy использует SO_REUSEPORT и поддерживает привязку нескольких независимых процессов к одному IP:port, при устранении неполадок может оказаться, что старый процесс не остановили перед запуском нового. Это приводит к абсурдным результатам проверок, создающим впечатление, что любые изменения конфигурации игнорируются. Причина в том, что, даже если новый процесс перезапущен с новой конфигурацией, старый тоже принимает часть входящих соединений и обрабатывает их, возвращая неожиданные результаты. При сомнениях просто остановите новый процесс и проверьте снова. Если всё ещё работает, скорее всего, старый процесс остался активен и его нужно остановить. Здесь хорошо помогает Linux-команда “netstat -lntp”.
При добавлении записей в ACL из командной строки (например, при внесении исходного адреса в чёрный список) важно помнить, что эти записи не синхронизируются с файлом и при перезагрузке конфигурации будут потеряны. Хотя часто это желаемый эффект (для чёрного списка), он может не соответствовать ожиданиям, если изменение было внесено для исправления проблемы. См. действие “add acl” интерфейса CLI.