HAProxy в systemd: почему не запускается
HAProxy проверяет конфигурацию перед запуском, и unit-файл обычно делает это предварительной командой. Поэтому отказы почти всегда видны как неудача проверки: ошибка в конфигурации, недоступный адрес привязки или проблема с файлом сертификата.
О службе
Проверка выполняется командой haproxy -c -f /etc/haproxy/haproxy.cfg. Она печатает строку и раздел с ошибкой, и это первое, что нужно смотреть. В unit-файле дистрибутивов эта команда стоит в ExecStartPre=, поэтому её код и попадает в состояние службы.
Особенность HAProxy — привязка к адресам, которых может не быть на машине. Балансировщик часто слушает плавающий адрес кластера, поднятый только на активном узле. Для этого нужен параметр ядра, разрешающий привязку к отсутствующему адресу, иначе на пассивном узле служба не запустится.
Мягкая перезагрузка (systemctl reload haproxy) поднимает новый процесс и передаёт ему слушающие сокеты, не разрывая соединения. Это штатный способ применять правки, и полный перезапуск для балансировщика почти всегда лишний.
Как устроена
| Проверка конфигурации | haproxy -c -f /etc/haproxy/haproxy.cfg |
|---|---|
| Мягкая перезагрузка | systemctl reload haproxy — соединения не рвутся |
| Плавающий адрес | требует net.ipv4.ip_nonlocal_bind=1 для привязки на пассивном узле |
| Сертификаты | в одном файле цепочка и ключ; при обновлении нужен reload |
| Дескрипторы | при большом числе соединений нужен повышенный LimitNOFILE |
Частые ошибки
10 записей базы отмечены за этой службой.
Коды выхода
- status=1/FAILURE в systemdКод 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
Сообщения журнала
- Cannot assign requested address при привязкеОшибка 99 при привязке: адрес не принадлежит машине или ещё не поднят. Разбор с network-online.target и ip_nonlocal_bind.
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Permission denied в журнале службыОтказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- Connection reset by peer в журнале службыСоединение сброшено другой стороной: обрыв клиента, перезапуск сервера, промежуточное устройство.
Ресурсы и ограничения
- Too many open files в журнале службыСлужба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
- kernel: TCP: request_sock … overflowСоединения теряются при наплыве: переполнена очередь ожидающих соединений. Как считать somaxconn и backlog.
- nf_conntrack: table full, dropping packetСоединения обрываются под нагрузкой: заполнена таблица отслеживания соединений ядра.
Ошибки служб
- HAProxy: cannot bind socket и плавающий адресHAProxy не запускается на пассивном узле кластера: адрес не поднят. Параметр ip_nonlocal_bind.
- HAProxy: все серверы группы недоступныБалансировщик отдаёт 503: проверки состояния не проходят. Разбор проверок и таймаутов.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
| status | Что означает у этой службы | Куда смотреть |
|---|---|---|
1/FAILURE |
ошибка конфигурации или невозможность привязки к адресу. | разбор |
Диагностика
Проверка конфигурации с указанием строки ошибки.
sudo haproxy -c -f /etc/haproxy/haproxy.cfgПоказывает, упала проверка или сам процесс.
systemctl status haproxy --no-pager -lЕсть ли адрес привязки и разрешена ли привязка к отсутствующему адресу.
ip -brief addr && sysctl net.ipv4.ip_nonlocal_bindСообщения балансировщика при запуске и перезагрузке.
journalctl -u haproxy -n 40 --no-pagerПараметры unit, которые тут важны
- ExecStartPre=проверка конфигурации до запуска
- ExecReload=мягкая перезагрузка с передачей сокетов
- LimitNOFILE=каждое соединение — дескриптор, значение по умолчанию мало
- Type=notify в современных сборках
Источники
- Документация HAProxy
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)