|
|
(не показаны 3 промежуточные версии этого же участника) |
Строка 1: |
Строка 1: |
− | Установку будем проводить на Debian 11. Если текущая версия устраивает, то просто <code>apt install haproxy</code>. Если требуется последняя, то подключаем репозиторий.
| |
| | | |
− |
| |
− | Добавляем ключ репозитория
| |
− | 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.''' Глобальные настройки, распространяемые на все публикации.<br>
| |
− | * '''defaults.''' Настройки, применяемые по умолчанию, если они не указаны явно в публикации.<br>
| |
− | * '''frontend.''' Правила обработки запросов, приходящих на сервер и передачи этих запросов серверам backend. Может быть несколько.<br>
| |
− | * '''backend.''' Настройка конечных серверов, которые обрабатывают запросы и возвращают результаты. Может быть несколько.<br>
| |
− | Также есть возможность создать дополнительные секции, например '''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
| |
− |
| |
− | defaults
| |
− | log global
| |
− | mode http
| |
− | option httplog
| |
− | option dontlognull
| |
− | timeout connect 5000
| |
− | timeout client 50000
| |
− | timeout server 50000
| |
− |
| |
− | 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.
| |
− |
| |
− |
| |
− | '''Алгоритмы балансировки нагрузки'''<br>
| |
− |
| |
− | * '''Roundrobin:''' каждый сервер используется по очереди в соответствии со своим весом. Это самый плавный и честный алгоритм, когда время обработки серверами остается равномерно распределенным. Этот алгоритм является динамическим, что позволяет регулировать вес сервера на лету.<br>
| |
− | * '''Leastconn:''' выбирается сервер с наименьшим количеством соединений. Циклический перебор выполняется между серверами с одинаковой нагрузкой. Использование этого алгоритма рекомендуется для длинных сеансов, таких как LDAP, SQL, TSE и т.д., но он не очень подходит для коротких сеансов, таких как HTTP.<br>
| |
− | * '''First:''' первый сервер с доступными слотами для подключения получает соединение. Серверы выбираются от самого низкого числового идентификатора до самого высокого, который по умолчанию соответствует положению сервера в ферме. Как только сервер достигает значения maxconn, используется следующий сервер.<br>
| |
− | * '''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 AcmeCorp 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
| |
− |
| |
− | '''<font color=red>В работе url_reg и use_backend есть нюанс — Haproxy найдет все возможные acl для запросов, а перенаправит на тот use_backend, который первый встретится в конфигурации. Таким образом, если адрес страницы будет соответствовать нескольким acl, результат работы может быть непредсказуем. В этом случае, необходимо более частный acl ставить выше при описании use_backend.</font>
| |
− | '''
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | Примеры форматов для логов
| |
− | 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"
| |