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

Используемые термины: Haproxy , CentOS , Ubuntu .

Данная инструкция применима для Linux CentOS и Ubuntu. Мы рассмотрим как процесс установки, так и примеры настройки.

Установка

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-х секциях:

  1. global. Глобальные настройки, распространяемые на все публикации.
  2. defaults. Настройки, применяемые по умолчанию, если они не указаны явно в публикации.
  3. frontend. Правила обработки запросов, приходящих на сервер и передачи этих запросов серверам backend. Может быть несколько.
  4. 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

При настройке указываем:

  1. Как распределяется нагрузка между серверами. Доступны варианты:
    • roundrobin — серверы используются по очереди. Нагрузка распространяется равномерно, в зависимости от указанного веса. Вес может быть изменен на лету.
    • static-rr — серверы используются по очереди. Нагрузка распространяется равномерно, в зависимости от указанного веса. Вес не может быть изменен на лету.
    • leastconn — запросы идут к серверу с наименьшим количеством активных подключений.
    • source — запросы от одного и того же IP-адреса идут на один и тот же сервер.
    • uri — запросы с одним и тем же URL (до знака вопроса) будут переправляться на один и тот же сервер.
    • url_param — запросы с одинаковыми параметрами GET (все, что после знака вопроса) будут переправляться на один и тот же сервер.
  2. На какие именно серверы передавать запросы.

Пример:

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

EnglishRussianUkrainian