HAProxy Edge (VIP + Auto Reload + Let's Encrypt) — пошаговая инструкция
📌 ОписаниеСхема:
* 2 VPS с HAProxy
* keepalived (VIP, active/passive)
* GlusterFS:
* /etc/haproxy
* /etc/letsencrypt
* Certbot (Let's Encrypt)
Цель:
* reload HAProxy при изменении конфигов/maps
* автоматическое обновление сертификатов
* исключение гонок и двойных reload
1. Скрипт безопасного reload HAProxyСоздаём файл:
nano /usr/local/bin/haproxy-safe-reload.sh
Содержимое:
#!/bin/bash
set -euo pipefail
VIP="10.10.10.10"
# Проверяем, что нода активная (есть VIP)
ip addr | grep -q "$VIP"
if [ $? -ne 0 ]; then
echo "[HAProxy] Not active node → skip reload"
exit 0
fi
LOCK=/var/lock/haproxy-reload.lock
flock -n "$LOCK" bash -c '
echo "[HAProxy] validating config..."
haproxy -c -f /etc/haproxy/haproxy.cfg
if [ $? -ne 0 ]; then
echo "[HAProxy] CONFIG INVALID → abort"
exit 1
fi
echo "[HAProxy] reloading..."
systemctl reload haproxy
echo "[HAProxy] reload OK"
'
Делаем исполняемым:
chmod +x /usr/local/bin/haproxy-safe-reload.sh
2. Watcher изменений конфигурацииУстанавливаем:
apt install inotify-tools -y
Создаём watcher:
nano /usr/local/bin/haproxy-watch.sh
Содержимое:
#!/bin/bash
WATCH="/etc/haproxy"
LOCK=/var/lock/haproxy-watch.lock
LAST_RUN=0
inotifywait -m -r -e close_write --format '%f' $WATCH | while read file; do
```
# игнор временных файлов
case "$file" in
*.swp|*.swx|*.tmp|4913)
continue
;;
esac
# реагируем только на нужные файлы
if [[ "$file" != "haproxy.cfg" && "$file" != *.map ]]; then
continue
fi
NOW=$(date +%s)
# debounce (защита от повторов)
if (( NOW - LAST_RUN < 3 )); then
continue
fi
LAST_RUN=$NOW
echo "[WATCH] Change detected: $file"
flock -n $LOCK /usr/local/bin/haproxy-safe-reload.sh
```
done
Делаем исполняемым:
chmod +x /usr/local/bin/haproxy-watch.sh
3. systemd сервис для watcherСоздаём:
nano /etc/systemd/system/haproxy-watch.service
Содержимое:
[Unit]
Description=HAProxy config watcher
After=network.target
[Service]
ExecStart=/usr/local/bin/haproxy-watch.sh
Restart=always
[Install]
WantedBy=multi-user.target
Включаем:
systemctl daemon-reload
systemctl enable --now haproxy-watch
Проверка:
systemctl status haproxy-watch
4. Автоматическая сборка сертификатов для HAProxyСоздаём deploy-hook:
nano /etc/letsencrypt/renewal-hooks/deploy/haproxy-deploy-cert.sh
Содержимое:
#!/bin/bash
set -euo pipefail
CERT_DIR="/etc/haproxy/certs"
if [ -n "${RENEWED_LINEAGE:-}" ]; then
DOMAIN=$(basename "$RENEWED_LINEAGE")
```
cat "$RENEWED_LINEAGE/fullchain.pem" \
"$RENEWED_LINEAGE/privkey.pem" \
> "$CERT_DIR/$DOMAIN.pem"
```
else
for d in /etc/letsencrypt/live/*/; do
DOMAIN=$(basename "$d")
cat "$d/fullchain.pem" "$d/privkey.pem" > "$CERT_DIR/$DOMAIN.pem"
done
fi
/usr/local/bin/haproxy-safe-reload.sh
Права:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy-deploy-cert.sh
5. Важные принципы работы- Reload выполняется только на ACTIVE node (через VIP check)
- flock защищает от параллельных reload
- haproxy -c проверяет конфиг перед применением
- Watcher реагирует только на реальные изменения (cfg + maps)
- Игнорируются временные файлы редакторов
6. ТестированиеРедактируем конфиг:
nano /etc/haproxy/haproxy.cfg
Ожидаем:
[WATCH] Change detected: haproxy.cfg
[HAProxy] reload OK
🎯 ИтогПолучаем:
* автоматический reload HAProxy
* безопасный деплой конфигурации
* корректную работу в HA (VIP)
* автоматическую интеграцию с Let's Encrypt
[/hr]