HAProxy. Установка и настройка — различия между версиями
Root (обсуждение | вклад) |
Root (обсуждение | вклад) |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 34: | Строка 34: | ||
group haproxy | group haproxy | ||
daemon | daemon | ||
+ | maxconn 10000 | ||
defaults | defaults | ||
Строка 43: | Строка 44: | ||
timeout client 50000 | timeout client 50000 | ||
timeout server 50000 | timeout server 50000 | ||
+ | maxconn 10000 | ||
frontend http_front | frontend http_front | ||
Строка 202: | Строка 204: | ||
Запретить доступ из сети 192.168.0.0/24 | Запретить доступ из сети 192.168.0.0/24 | ||
− | http-request deny if { src 192.168.10.0/24 } | + | http-request deny if { src 192.168.10.0/24 } |
Текущая версия на 10:45, 25 марта 2024
Установку будем проводить на Debian 11. Если текущая версия устраивает, то просто apt install haproxy
. Если требуется последняя, то подключаем репозиторий.
Добавляем ключ репозитория
curl https://haproxy.debian.net/bernat.debian.org.gpg | gpg --dearmor > /usr/share/keyrings/haproxy.debian.net.gpg
Добавляем сам репозиторий
echo deb "[signed-by=/usr/share/keyrings/haproxy.debian.net.gpg]" http://haproxy.debian.net bullseye-backports-2.6 main > /etc/apt/sources.list.d/haproxy.list apt update
Ставим HAProxy
apt-get install haproxy=2.6.\*
Конфигурирование HAProxy выполняется в файле /etc/haproxy/haproxy.cfg. Все основные настройки находятся в 4-х секциях:
- global. Глобальные настройки, распространяемые на все публикации.
- defaults. Настройки, применяемые по умолчанию, если они не указаны явно в публикации.
- frontend. Правила обработки запросов, приходящих на сервер и передачи этих запросов серверам backend. Может быть несколько.
- backend. Настройка конечных серверов, которые обрабатывают запросы и возвращают результаты. Может быть несколько.
Также есть возможность создать дополнительные секции, например userlist.
Простейший конфиг будет выглядеть примерно так
global log /dev/log local0 log /dev/log local1 notice log 127.0.0.1 local2 chroot /var/lib/haproxy stats timeout 30s user haproxy group haproxy daemon maxconn 10000 defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 maxconn 10000 frontend http_front bind *:80 mode http log global bind *:1937 #for stats page stats enable stats uri /stats stats hide-version stats realm Haproxy\ Statistics stats auth username:password log-format %ci\ %ft\ %b/%s\ %ST\ %B\ %CC\ \%CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %bq\ %hr\ %hs\ %{+Q}r monitor-uri /monitoruri default_backend homepage_back backend homepage_back balance roundrobin server 192.168.150.54:80 check server 192.168.150.55:80 check
Конфиг определяет балансировщик нагрузки транспортного уровня (layer 4) с внешним именем http_front, прослушивающий порт 80, который затем направляет трафик к бэкенду по умолчанию с именем homepage_back, состоящий из двух веб-серверов. Трафик на них распределяется по очереди. По /stats подключается страница статистики, защищённая паролем.
Настройка балансировки нагрузки на прикладном уровне(layer 7)
Полезно, когда части веб-приложения расположены на разных хостах. Например, основная страница на одном хосте, а блог на другом. Это может быть достигнуто путем регулирования передачи соединения, например, по URL.
frontend http_front bind *:80 stats uri /stats acl url_blog path_beg /blog use_backend blog_back if url_blog default_backend homepage_back backend homepage_back balance roundrobin server 192.168.150.54:80 check server 192.168.150.55:80 check backend blog_back server 192.168.150.56:80 check
Фронтенд объявляет правило ACL с именем url_blog, которое применяется ко всем соединениям с путями, начинающимися с /blog. Use_backend определяет, что соединения, соответствующие условию url_blog, должны обслуживаться бэкендом с именем blog_back, а все остальные запросы обрабатываются бэкендом по умолчанию.
frontend http_front bind 192.168.150.55:80 acl url_stat path_end -i .css .js use_backend static if url_stat default_backend webserver
В данном случае слушаем веб-запросы и если они идут на файлы с расширениями .css или .js, передаем запрос на бэкэнд static. Все остальные запросы передаем на бэкэнд webserver.
Алгоритмы балансировки нагрузки
- Roundrobin: каждый сервер используется по очереди в соответствии со своим весом. Это самый плавный и честный алгоритм, когда время обработки серверами остается равномерно распределенным. Этот алгоритм является динамическим, что позволяет регулировать вес сервера на лету.
- Leastconn: выбирается сервер с наименьшим количеством соединений. Циклический перебор выполняется между серверами с одинаковой нагрузкой. Использование этого алгоритма рекомендуется для длинных сеансов, таких как LDAP, SQL, TSE и т.д., но он не очень подходит для коротких сеансов, таких как HTTP.
- First: первый сервер с доступными слотами для подключения получает соединение. Серверы выбираются от самого низкого числового идентификатора до самого высокого, который по умолчанию соответствует положению сервера в ферме. Как только сервер достигает значения maxconn, используется следующий сервер.
- Source: IP-адрес источника хешируется и делится на общий вес запущенных серверов, чтобы определить, какой сервер будет получать запрос. Таким образом, один и тот же IP-адрес клиента будет всегда доставаться одному и тому же серверу, в то время как серверы остаются неизменными.
- Static-rr — серверы используются по очереди. Нагрузка распространяется равномерно, в зависимости от указанного веса. Вес не может быть изменен на лету.
- Uri — запросы с одним и тем же URL (до знака вопроса) будут переправляться на один и тот же сервер.
- Url_param — запросы с одинаковыми параметрами GET (все, что после знака вопроса) будут переправляться на один и тот же сервер.
Примеры использования
- HTTPS запросы
Frontend:
frontend https-frontend bind *:443 ssl crt /etc/ssl/domaincert.pem reqadd X-Forwarded-Proto:\ https default_backend https-backend
Backend:
backend https-backend redirect scheme https if !{ ssl_fc } server back1 192.168.150.54:80 check server back2 192.168.150.55:80 check
- Распределение запросов по весу (weight)
Backend:
backend weight-backend ... server back1 192.168.150.54:80 weight 100 server back2 192.168.150.55:80 weight 80
в данном примере запросы будут отправляться чаще на сервер back1
- Поддержка sticky session
Backend:
backend sticky-backend ... server back1 192.168.150.54:80 cookie check server back2 192.168.150.55:80 cookie check
Поддержка sticky session позволит перенаправлять http-запросы пользователя всегда на один и тот же сервер. Это необходимо в том случае, когда не предусмотрен механизм хранения PHP-сессий в общем каталоге.
- Защита паролем
Сделаем необходимость вводить пароль при подключении к серверу.
Получаем хеш пароля
echo -n 'password' | md5sum
В haproxy создаем список пользователей
userlist http-users user user1 password 5f4dcc3b5aa765d61d8327deb882cf99
Backend:
backend web-servers ... acl AuthAccept http_auth(http-users) http-request auth realm Site if !AuthAccept
- Распределение запросов по серверам с помощью url_reg
С помощью url_reg можно распределить запросы по группам серверов исходя из URL страницы.
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 back1 if url_page1 use_backend back2 if url_page2 default_backend www
в данном примере ищем страницы, которые начинаются на page1, затем слеш и 10 любых символов в нижнем регистре и/или цифр, еще один слеш и в конце либо img, либо doc - этому урлу присваиваем acl url_page1. Второй урл — page2, затем слеш и любое количество символов в нижнем регистре регистре и/или цифры — acl url_page2. Для url_page1 используем группу серверов back1, для url_page2 - back2. По умолчанию все запросы отправляем на backend www
Backend:
backend back1 server www1 192.168.150.54:80 check server www2 192.168.150.53:80 check backend back2 server www3 192.168.150.55:80 check server www4 192.168.150.56:80 check
В работе url_reg и use_backend есть нюанс — Haproxy найдет все возможные acl для запросов, а перенаправит на тот use_backend, который первым встретится в конфигурации. Таким образом, если адрес страницы будет соответствовать нескольким acl, результат работы может быть непредсказуем. В этом случае, необходимо более частный acl ставить выше при описании use_backend.
Примеры директив
Заблокировать url если путь начинается с /admin
http-request deny if { path beg -i -m /admin }
Включение http/2(alpn h2) http1.1 тоже оставляем
bind *:443 ssl cert iwad.pem alpn h2,http/1.1
Запретить доступ из сети 192.168.0.0/24
http-request deny if { src 192.168.10.0/24 }
Примеры форматов для логов
frontend tcp_frontend log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
frontend engy_frontend log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {valid:%[ssl_c_verify],User:%{+Q}[ssl_c_s_dn(cn)]}
frontend https_frontend log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {valid:%[ssl_c_verify],User:%{+Q}[ssl_c_s_dn(cn)]}
frontend http_frontend log-format %ci\ %ft\ %b/%s\ %ST\ %B\ %CC\ \%CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %bq\ %hr\ %hs\ %{+Q}r
frontend mail_frontend log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
frontend k8s_api_frontend log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"