HAProxy. Установка и настройка — различия между версиями
Root (обсуждение | вклад) (Новая страница: «Установку будем проводить на Debian 11. Если текущая версия устраивает, то просто <code>apt install ha…») |
Root (обсуждение | вклад) |
||
| (не показано 6 промежуточных версий этого же участника) | |||
| Строка 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 | ||
| Строка 75: | Строка 77: | ||
bind *:80 | bind *:80 | ||
stats uri /stats | stats uri /stats | ||
| − | acl url_blog | + | acl url_blog path_beg /blog |
| − | use_backend | + | use_backend blog_back if url_blog |
default_backend homepage_back | default_backend homepage_back | ||
| Строка 91: | Строка 93: | ||
frontend http_front | frontend http_front | ||
bind 192.168.150.55:80 | bind 192.168.150.55:80 | ||
| − | acl url_stat | + | acl url_stat path_end -i .css .js |
| − | use_backend static | + | use_backend static if url_stat |
default_backend webserver | default_backend webserver | ||
В данном случае слушаем веб-запросы и если они идут на файлы с расширениями .css или .js, передаем запрос на бэкэнд static. Все остальные запросы передаем на бэкэнд webserver. | В данном случае слушаем веб-запросы и если они идут на файлы с расширениями .css или .js, передаем запрос на бэкэнд static. Все остальные запросы передаем на бэкэнд webserver. | ||
| Строка 162: | Строка 164: | ||
... | ... | ||
acl AuthAccept http_auth(http-users) | acl AuthAccept http_auth(http-users) | ||
| − | http-request auth realm | + | http-request auth realm Site if !AuthAccept |
| Строка 189: | Строка 191: | ||
'''<font color=red>В работе url_reg и use_backend есть нюанс — Haproxy найдет все возможные acl для запросов, а перенаправит на тот use_backend, который первым встретится в конфигурации. Таким образом, если адрес страницы будет соответствовать нескольким acl, результат работы может быть непредсказуем. В этом случае, необходимо более частный acl ставить выше при описании use_backend.</font> | '''<font color=red>В работе url_reg и use_backend есть нюанс — Haproxy найдет все возможные acl для запросов, а перенаправит на тот use_backend, который первым встретится в конфигурации. Таким образом, если адрес страницы будет соответствовать нескольким acl, результат работы может быть непредсказуем. В этом случае, необходимо более частный acl ставить выше при описании use_backend.</font> | ||
''' | ''' | ||
| + | |||
| + | |||
| + | '''Примеры директив''' | ||
| + | |||
| + | Заблокировать 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 } | ||
Текущая версия на 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"