Данная инструкция применима для Linux CentOS и Ubuntu. Мы рассмотрим как процесс установки, так и примеры настройки.
Установка
Принцип настройки
Frontend
Backend
Firewall
Примеры
HTTPS
Weight
Sticky Session
Пароль
URL_REG
Дополнительные настройки
Логирование
Keep-alive
Установка
HAProxy присутствует в репозиториях Linux. Команды для установки немного различаются и зависят от типа операционной системы.
а) RPM (Rocky Linux, CentOS, Red Hat, Fedora):
yum install haproxy
б) DEB (Debian, Ubuntu):
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 запросов вводим следующие команды:
firewall-cmd –permanent –add-port=80/tcp
firewall-cmd –permanent –add-port=443/tcp
firewall-cmd –reload
Подробнее про настройку брандмауэра в Linux при помощи firewalld и iptables.
Примеры использования
Рассмотрим часто встречаемые варианты использования 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
Дополнительные настройки
Рассмотрим настройки, которые могут оказаться полезными.
Логирование
Открываем конфигурационный файл:
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