Установка и настройка HAProxy на Linux


Используемые термины: Haproxy, CentOS, Ubuntu.
Данная инструкция применима для Linux CentOS и Ubuntu. Мы рассмотрим как процесс установки, так и примеры настройки.
Установка
Принцип настройки
Frontend
Backend
Firewall
Примеры
HTTPS
Weight
Sticky Session
Пароль
URL_REG
RDP
Дополнительные настройки
Логирование
Keep-alive
Установка
HAProxy присутствует в репозиториях Linux. Команды для установки немного различаются и зависят от типа операционной системы.
а) RPM (Rocky Linux, CentOS, Red Hat, Fedora):
yum install haproxy
б) DEB (Debian, Ubuntu):
apt update
apt install haproxy
После устрановки запустим сервис и разрешим его автозапуск.
Это можно сделать командами:
systemctl enable haproxy
systemctl start haproxy
На этом установка и запуск закончены.
Принцип настройки
Конфигурирование HAProxy выполняется в файле /etc/haproxy/haproxy.cfg. Все основные настройки находятся в 4-х секциях:
- global. Глобальные настройки, распространяемые на все публикации.
- defaults. Настройки, применяемые по умолчанию, если они не указаны явно в публикации.
- frontend. Правила обработки запросов, приходящих на сервер и передачи этих запросов серверам backend. Может быть несколько.
- backend. Настройка конечных серверов, которые обрабатывают запросы и возвращают результаты. Может быть несколько.
Также есть возможность создать дополнительные секции, например userlist.
Настройка frontend
При настройке прослушивания внешних запросов, основное, что мы указываем:
- IP-адрес и порт прослушивания.
- Правила, по которым обрабатываются запросы.
- Группы серверов, на которые будет перекинут запрос.
Пример:
frontend balance_http
bind 192.168.0.15:80
acl url_stat path_end -i .css .js
use_backend static if url_stat
default_backend webserver
* в данном случае мы слушаем веб-запросы и если они идут на файлы с расширениями .css или .js, передаем запрос на бэкэнд с название static. Все остальные запросы передаем на бэкэнд webserver.
* где balance_http — название фронтэнда; bind 192.168.0.15:80 — слушаем на адресе 192.168.0.15, порту 80; url_stat — название правила; use_backend static if url_stat — правило обработки, при котором запросы, попавшие под действие правила url_stat, должны быть обработаны бэкэндом static; default_backend — указывает, какой бэкэнд будет использоваться по умолчанию.
Настройка backend
При настройке указываем:
- Как распределяется нагрузка между серверами. Доступны варианты:
- roundrobin — серверы используются по очереди. Нагрузка распространяется равномерно, в зависимости от указанного веса. Вес может быть изменен на лету.
- static-rr — серверы используются по очереди. Нагрузка распространяется равномерно, в зависимости от указанного веса. Вес не может быть изменен на лету.
- lessconn — запросы идут к серверу с наименьшим количеством активных подключений.
- source — запросы от одного и того же IP-адреса идут на один и тот же сервер.
- uri — запросы с одним и тем же URL (до знака вопроса) будут переправляться на один и тот же сервер.
- url_param — запросы с одинаковыми параметрами GET (все, что после знака вопроса) будут переправляться на один и тот же сервер.
- На какие именно серверы передавать запросы.
Пример:
backend webserver
balance roundrobin
server server1 192.168.0.20:80 check
server server2 192.168.0.30:80 check
* где webserver — название бэкэнда; balance — опция определения алгоритма распределения запросов между серверами; server — указывает имя и IP-адрес сервера, на который передается запрос; check — указываем, что необходимо проверять состояние сервера.
* для работы достаточно и одного сервера, но несколько добавят отказоустойчивости.
После внесения изменений в настройку HAProxy, необходимо перезапустить сервис:
systemctl restart haproxy
или просто перечитать настройки:
systemctl reload haproxy
Брандмауэр
Для корректной работы сервера, не забываем открывать соответствующие порты. Например, для обработки http и https запросов вводим следующие команды.
а) В firewalld:
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
б) В iptables:
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
Для сохранения правил можно использовать утилиту iptables-persistent:
apt install iptables-persistent
netfilter-persistent save
Подробнее про настройку брандмауэра в Linux при помощи firewalld и iptables.
Примеры использования
Рассмотрим часто встречаемые варианты использования HAProxy.
После выполнения настройки не забываем перезапустить сервис командой:
systemctl reload haproxy
1. HTTPS запросы
Frontend:
frontend https-frontend
bind *:443 ssl crt /etc/ssl/domaincert.pem
reqadd X-Forwarded-Proto:\ https
default_backend https-backend
* где https-frontend — название фронтэнда; bind *:443 — сервер слушает на всех IP-адресах на порту 443 (https); /etc/ssl/domaincert.pem — файл, в котором хранятся алгоритмы для закрытого и открытого ключей; https-backend — бэкэнд, на который будут отправляться запросы.
Backend:
backend https-backend
redirect scheme https if !{ ssl_fc }
server s1 192.168.0.20:80 check
server s2 192.168.0.30:80 check
* где https-backend — название бэкэнда; s1 и s2 — название серверов, на которые переправляем запросы; 192.168.0.20 и 192.168.0.30 — IP-адреса серверов, на которые переправляем запросы.
2. Распределение запросов по весу (weight)
Если необходимо на определенный сервер отправлять больше запросов, можно применить weight при настройке бэкэнда:
backend weight-backend
...
server server1 192.168.0.20:80 weight 100
server server2 192.168.0.30:80 weight 80
* в данном примере запросы будут отправляться чаще на сервер server1.
3. Поддержка sticky session
Поддержка sticky session позволит перенаправлять http-запросы пользователя всегда на один и тот же сервер. Это необходимо в том случае, когда не предусмотрен механизм хранения PHP-сессий в общем каталоге.
backend sticky-backend
...
server server1 192.168.0.20:80 cookie check
server server2 192.168.0.30:80 cookie check
4. Защита паролем
Сделаем необходимость вводить пароль при подключении к серверу.
Сначала получим хэш пароля:
echo -n 'password' | md5sum
В конфиге haproxy создаем список пользователей (отдельная секция):
userlist http-users
user user1 password 5f4dcc3b5aa765d61d8327deb882cf99
* где http-users — название списка пользователей; user1 — имя пользователя; 5f4dcc3b5aa765d61d8327deb882cf99 — хэш пароля.
В бэкэнде:
backend web-servers
...
acl AuthAccept http_auth(http-users)
http-request auth realm AcmeCorp if !AuthAccept
5. Распределение запросов по серверам с помощью url_reg
С помощью url_reg мы можем распределить запросы по группам серверов исходя из URL страницы.
vi /etc/haproxy/haproxy.cfg
Во frontend добавляем:
frontend https-frontend
acl url_page1 url_reg -i ^/page1/[a-z0-9]{10}/(img|doc)/$
acl url_page2 url_reg -i ^/page2/[a-zA-Z0-9]*/$
use_backend serers1 if url_page1
use_backend serers2 if url_page2
default_backend www
* в данном примере мы ищем страницы, которые начинаются на page1, затет слеш и 10 любых символов в нижнем регистре и/или цифр, еще один слеш и в конце либо img, либо doc — такому урлу присваиваем acl url_page1. Второй урл — page2, затет слеш и любое количество символов в нижнем регистре регистре и/или цифры — acl url_page2. Для url_page1 используем группу серверов serers1, для url_page2 — serers2. По умолчанию все запросы отправляем на backend www.
В работе url_reg и use_backend есть нюанс — Haproxy найдет все возможные acl для запросов, а перенаправит на тот use_backend, который первый встретится в конфигурации. Таким образом, если адрес страницы будет соответствовать нескольким acl, результат работы может быть непредсказуем. В этом случае, необходимо более частный acl ставить выше при описании use_backend.
Пример backend:
backend serers1
server www1 192.168.0.20:80 check
server www2 192.168.0.30:80 check
backend serers2
server www3 192.168.0.40:80 check
server www4 192.168.0.50:80 check
6. Проксирование RDP
Для проксирования запросов при подключении к удаленному рабочему столу используем конфигурацию для frontend и backend:
vi /etc/haproxy/haproxy.cfg
frontend rdp-frontend
mode tcp
bind *:3389 name rdp
log global
option tcplog
tcp-request inspect-delay 2s
tcp-request content accept if RDP_COOKIE
default_backend rdp-server
backend rdp-server
mode tcp
balance leastconn
timeout server 5s
timeout connect 4s
log global
option tcplog
stick-table type string len 32 size 10k expire 8h
stick on rdp_cookie(mstshash),bytes(0,6)
stick on rdp_cookie(mstshash)
option tcp-check
tcp-check connect port 3389
default-server inter 3s rise 2 fall 3
server TS01 1.2.3.4:3389 weight 10 check
* в данном примере все запросы на порт 3389 будут перенаправлены на сервер 1.2.3.4 и порт 3389.
Дополнительные настройки
Рассмотрим настройки, которые могут оказаться полезными.
Логирование
Открываем конфигурационный файл:
vi /etc/haproxy/haproxy.cfg
Проверяем наличие следующей строки в секции global:
global
...
log 127.0.0.1 local2
* при ее отсутствии, добавляем.
Создаем файл с настройками логов для haproxy:
vi /etc/rsyslog.d/haproxy.conf
local2.* /var/log/haproxy.log
Перезапускаем rsyslog:
systemctl restart rsyslog
Если мы используем Debian или Ubuntu, то также открываем конфигурационный файл rsyslog.conf:
vi /etc/rsyslog.conf
Добавляем, если нет:
...
$ModLoad imudp
$UDPServerRun 514
...
Постоянное HTTP-соединение
По аналогии с keep-alive у NGINX и Apache. В новых версиях HAProxy настроено по умолчанию. В случае необходимости настройки таймаута, в секции defaults правим:
defaults
...
option http-server-close
timeout http-keep-alive 10s