Балансировщик нагрузки HAProxy с SSL

Сегодня балансировка трафика и нагрузки достаточно распространенная практика. По сути балансировщик решает задачу горизонтального масштабирования доступа к приложениям и сервисам, предоставляя единую точку доступа.

HAProxy одна из самых популярных программ для балансировки нагрузки, обеспечивающая высокую доступность и проксирование. HAProxy программа с открытым исходным кодом.

HAProxy однопоточный, неблокирующий, событийный балансировщик с проверкой состояния. Умеет балансировать TCP (не только веб трафик), HTTP/HTTPS в режиме реверс прокси. Балансирует на уровне L4/L7.

HAProxy архитектурно не требователен к ресурсам сервера, работает в режиме одного потока, реагируя на события (запросы) и пересылая запрос на соединение на сервера служб.

HAProxy особенно подходит и часто используется для веб-решений с высоким трафиком, однако встречаются решения балансировки кластеров или групп баз данных (например MySQL).

Попробуем развернуть HAProxy с требованиями:

  • балансирует на бэкенд с тремя серверами Apache;
  • умеет определять доступность хоста и порта сервиса (L4 балансировка);
  • имеет страницу стантистики.

Не будем останавливаться на установках необходимых компонентов, сделать это достаточно просто.

Конфигурация HAProxy:

cat /etc/haproxy/haproxy.cfg

...

frontend http_front
        bind *:80
        default_backend http_back

backend http_back
        balance roundrobin
        server web1 192.168.50.21:80 check
        server web2 192.168.50.22:80 check
        server web3 192.168.50.23:80 check

listen stats 
        bind 192.168.50.10:9999
        mode http
        log global
        maxconn 10
        stats enable
        stats refresh 10s
        stats show-node
        stats auth admin:123456
        stats uri /haproxy?stats

В данном случае настроены frontend, backend и listen.

Frontend

frontend http_front
        bind *:80
        default_backend http_back
  • слушает порт 80 на всех интерфейсах, можно указать конкретный интерфейс;
  • весь принятый трафик (по умолчанию http) на 80-м порту пересылает на бэкенд http_back.

Backend

Здесь показан подробный конфиг для более детального разбора:

backend http_back
        balance roundrobin
        option httpchk HEAD / HTTP/1.1\r\nHost:airmeno.ru
        server web1 192.168.50.21:80 cookie web1b check inter 2000 fall 3 minconn 30 maxconn 70 weight 60
        server web2 192.168.50.22:80 cookie web2b check inter 2000 fall 3 minconn 50 maxconn 100 weight 100
        server web3 192.168.50.23:80 cookie web3b check inter 2000 fall 3 backup
  • режим балансировки — roundrobin;
  • httpchk определяет тип проверки на доступность. Если сервер не отвечает на определенный запрос, он не будет использоваться для балансировки, пока не пройдет тест;
  • cookie web3b check inter 2000 fall 3 backup:
    • cookie web3b — необходимо для правильной балансирови сессий клиентов (куки);
    • check — проверка доступности порта;
    • inter 2000 fall 3 — проверка каждые 2 сек и после 3 ошибках считается недоступным;
    • minconn 50 maxconn 100 — мин и макс одновременных соединения;
    • weight 100 — вес;
    • backup/disable — в качестве резервного или отключен;

Режимы балансировки:

  • Roundrobin: каждый сервер используется по очереди в соответствии со своим весом;
  • Leastconn: выбирается сервер с наименьшим количеством соединений;
  • First: первый сервер с доступными слотами для подключения получает соединение. Серверы выбираются от самого низкого числового идентификатора до самого высокого, который по умолчанию соответствует положению сервера в ферме. Как только сервер достигает значения maxconn, используется следующий сервер;
  • Source: IP-адрес источника хешируется и делится на общий вес запущенных серверов, чтобы определить, какой сервер будет получать запрос. Таким образом, один и тот же IP-адрес клиента будет всегда доставаться одному и тому же серверу.

Listen

listen stats 
        bind 192.168.50.10:9999
        mode http
        log global
        maxconn 10
        stats enable
        stats refresh 10s
        stats show-node
        stats auth admin:123456
        stats uri /haproxy?stats

Определяем адрес и порт страницы статистики нашего балансировщика. Адрес — это адрес самого балансировщика, порт в данном примере определен на 9999. Вся конфигурация достаточно простая и читается вполне интуитивно.

При обращении по адресу http://192.168.50.10:9999/haproxy?stats и авторизации, откроется страница статистики HAProxy.

И немного о глобальных настройках HAProxy, раздел global:

  • log — вести лог в /dev/log local0. Должен быть одним из 24 стандартных типов журналирования (kern user mail daemon auth syslog lpr news uucp cron auth2 ftp ntp audit alert cron2 local0 local1 local2 local3 local4 local5 local6 local7);
  • chroot — запираем HAProxy в указанной директории, для безопасности;
  • stats socket — сокет;
  • maxconn — максимальное количество конкурирующих соединений на один процесс;
  • nbproc [n] (nbproc 2) — задает количество проццессов, по умолчанию = 1;
  • user — пользователь, от имени которого будет запущена программа;
  • group — группа пользователя, от имени которого будет запущена программа;
  • daemon — режим запуска.

и в разделе defaults:

  • log global — включает в журналирование информацию о трафике;
  • mode http — режим работы (может быть и tcp), в http режиме происходит анализ Layer 7 трафика;
  • option httplog — Добавляет в лог HTTP запросы, состояние сеанса и таймеры;
  • option dontlognull — не логировать пустые соединения;
  • retries 3 — количество попыток понять состояние бекенда после обрыва соеденения;
  • option redispatch — перерастределение запросов после обрыва связи;
  • option httpclose — закрывать пассивные соеденения;
  • option forwardfor — включение X-Forwarded-For для передачи IP клиента бекенду;
  • errorfile XXX — страницы ошибок.

Балансировки на прикладном уровне (L7)

Настроить балансировщик на прикладном уровне (L7), можно когда части веб-приложения расположены на разных хостах, например когда веб-ui и admin-ui разнесены на разные хосты.

Изменим нашу конфигурацию:

frontend http_front
        bind *:80
        acl is_admin path_beg /admin
        use_backend admin_back if is_admin
        default_backend http_back

backend http_back
        balance roundrobin
        server web1 192.168.50.21:80 check
        server web2 192.168.50.22:80 check

backend admin_back        
        server web3 192.168.50.23:80 check

При обращении по адресу http://192.168.50.10/admin будет отвечать только web3.

Подробнее:

конфигурация (версия 2.4)- http://cbonte.github.io/haproxy-dconv/2.4/configuration.html

https://www.youtube.com/watch?v=cBLYQ8bbe7c&list=PLfnwKJbklIxwxXKiPv5nAgWwmaUvDjW_t

Подключение SSL

В данном примере реализуем перенаправление HTTPS трафика с балансировщика на бекэнд HTTP:

frontend https-frontend
    bind *:80    
    bind *:443 ssl crt /etc/haproxy/cert.pem
    redirect scheme https if !{ ssl_fc }

    reqadd X-Forwarded-Proto:\ https
    default_backend https-backend

backend https-backend
    redirect scheme https if !{ ssl_fc }
    server web1 192.168.50.21:80 check
    server web2 192.168.50.22:80 check
    server web3 192.168.50.23:80 check    

Перезапустим haproxy, запросы приходящие на балансировщик будут преобразованы в https и перенаправлены на бекэнд сервера по http.

Данная архитектура подходит для решений когда наш бекэнд находится в DMZ и нет необходимости тратить ресурсы на шифрование.

Top