Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
linux_faq:haproxy_high_availability_cluster [2019/05/28 09:57] – admin | linux_faq:haproxy_high_availability_cluster [2019/05/28 11:10] (current) – [Настройка keepalived] admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Задача ====== | ||
+ | В двух датацентрах хостятся одинаковые web-сервисы (**Microsoft Exchange 2016**) на нескольких серверах (в ДЦ каждом по два сервера). \\ | ||
+ | Запросы к web-сервисам могут приходить как от процессов в одном из датацентров (пользователи VDI), так и из внешнего интернета. \\ | ||
+ | Датацентры неравноправны. Один из них - основной (постоянно обслуживает основную массу запросов), | ||
+ | Зачача - настроить отказоустойчивый опенсорсный балансировщик, | ||
+ | * падение одного или нескольких бекенд-серверов. | ||
+ | * падение одной из нод балансировщика (либо падение процесса балансировщика). | ||
+ | * нарушение связи между датацентрами. | ||
+ | |||
+ | ====== Решение ====== | ||
+ | Функционал **high reliability** реализуется с помощью демона, | ||
+ | Кроме **keepalived** можно использовать **heartbeat**. \\ | ||
+ | **keepalived** попроще, | ||
+ | \\ | ||
+ | Будем настраивать **active-passive** связку из двух **haproxy + keeapalived**. \\ | ||
+ | На каждой ноде будет практически однаково настроен **haproxy**. В конфигурациях backend-серверов будут прописаны серверы, | ||
+ | В конфигурации **keepalived** на каждой ноде балансировщика будет прописан скрипт, | ||
+ | |||
+ | |||
+ | ====== Настройка haproxy ====== | ||
+ | **haproxy** - балансировщик. Осуществляет проверку состояния **backend**-серверов, | ||
+ | Установка: | ||
+ | sudo apt-get update && sudo apt-get -y install haproxy | ||
+ | Вот пример настройки **haproxy** (**/ | ||
+ | < | ||
+ | log / | ||
+ | log / | ||
+ | chroot / | ||
+ | stats socket / | ||
+ | stats timeout 30s | ||
+ | user haproxy | ||
+ | group haproxy | ||
+ | daemon | ||
+ | |||
+ | ######## Default values for all entries till next defaults section | ||
+ | defaults | ||
+ | option | ||
+ | option | ||
+ | option | ||
+ | option | ||
+ | retries 3 # Try to connect up to 3 times in case of failure | ||
+ | timeout connect 5s # 5 seconds max to connect or to stay in queue | ||
+ | timeout http-keep-alive 1s # 1 second max for the client to post next request | ||
+ | timeout http-request 15s # 15 seconds max for the client to send a request | ||
+ | timeout queue 30s # 30 seconds max queued on load balancer | ||
+ | timeout tarpit 1m # tarpit hold tim | ||
+ | backlog 10000 # Size of SYN backlog queue | ||
+ | mode tcp #alctl: protocol analyser | ||
+ | option tcplog | ||
+ | log global | ||
+ | timeout client 300s # | ||
+ | timeout server 300s # | ||
+ | default-server inter 3s rise 2 fall 3 # | ||
+ | |||
+ | frontend ft_exchange_tcp | ||
+ | bind *:443 name https #alctl: listener https configuration. | ||
+ | maxconn 100000 | ||
+ | default_backend exchange_2016_backend | ||
+ | |||
+ | backend exchange_2016_backend | ||
+ | balance roundrobin | ||
+ | # maximum SSL session ID length is 32 bytes. | ||
+ | stick-table type binary len 32 size 30k expire 10s | ||
+ | acl clienthello req_ssl_hello_type 1 | ||
+ | acl serverhello rep_ssl_hello_type 2 | ||
+ | # use tcp content accepts to detects ssl client and server hello. | ||
+ | tcp-request inspect-delay 5s | ||
+ | tcp-request content accept if clienthello | ||
+ | # no timeout on response inspect delay by default. | ||
+ | tcp-response content accept if serverhello | ||
+ | # SSL session ID (SSLID) may be present on a client or server hello. | ||
+ | # Its length is coded on 1 byte at offset 43 and its value starts | ||
+ | # at offset 44. | ||
+ | |||
+ | # Match and learn on request if client hello. | ||
+ | stick on payload_lv(43, | ||
+ | # Learn on response if server hello. | ||
+ | stick store-response payload_lv(43, | ||
+ | |||
+ | fullconn 100000 | ||
+ | |||
+ | option httpchk GET / | ||
+ | |||
+ | server exch_server1 exch1.domain.com: | ||
+ | server exch_server2 exch2.domain.com: | ||
+ | |||
+ | email-alert mailers mta | ||
+ | email-alert level info | ||
+ | email-alert from haproxy-alert@domain.com | ||
+ | email-alert to admin@domain.com | ||
+ | |||
+ | mailers mta | ||
+ | mailer smtp1 smtp.domain.com: | ||
+ | |||
+ | frontend stats | ||
+ | bind *:8080 | ||
+ | mode http | ||
+ | stats enable | ||
+ | # stats auth admin: | ||
+ | stats uri / | ||
+ | </ | ||
+ | |||
+ | Тут настраивается единственный **frontend** для единственного **backend** в режиме **tcp**. \\ | ||
+ | Балансировка - round-robin. \\ | ||
+ | Прописан **session sticking**, чтобы клиент не прыгал по серверам в пределах одной сессии. \\ | ||
+ | Проверка состояния backend-серверов осуществляется с помощью запроса: | ||
+ | option httpchk GET / | ||
+ | Если ответ **200**, то backend-сервер считается живым. \\ | ||
+ | \\ | ||
+ | Для второй ноды конфигурация такая же, но список backend-серверов другой: | ||
+ | < | ||
+ | server exch_server4 exch4.domain.com: | ||
+ | ====== Настройка keepalived ====== | ||
+ | **keepalived** следит за состоянием нод в пределах **виртуального роутера** (нод **keepalive** с одинаковым параметром **virtual_router_id**) и с заданным интервалом вычисляет **приоритет** (priority) ноды (в зависимости от результатов выполнения скрипта). Если **приоритет** ноды меняется | ||
+ | Установка **keepalived**: | ||
+ | sudo apt-get update && sudo apt-get install keepalived | ||
+ | \\ | ||
+ | Вот конфигурация основной (**master**) ноды (**/ | ||
+ | < | ||
+ | | ||
+ | admin@domain.com | ||
+ | } | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | vrrp_script chk_haproxy { | ||
+ | script "/ | ||
+ | interval 2 | ||
+ | weight 2 | ||
+ | } | ||
+ | |||
+ | vrrp_instance VI_1 { | ||
+ | state MASTER | ||
+ | interface ens160 | ||
+ | virtual_router_id 101 | ||
+ | priority 101 | ||
+ | advert_int 1 | ||
+ | smtp_alert | ||
+ | authentication { | ||
+ | auth_type PASS | ||
+ | auth_pass superpassword | ||
+ | } | ||
+ | virtual_ipaddress { | ||
+ | 172.30.129.131 | ||
+ | } | ||
+ | track_script { | ||
+ | chk_haproxy | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | Тут прописаны секции: | ||
+ | * **global_defs** - глобальные параметры, | ||
+ | * **vrrp_script chk_haproxy** - сценарий проверки сосотяния **haproxy** - проверка наличия процесса **haproxy** и проверка доступности сервиса через **haproxy**, | ||
+ | * **vrrp_instance VI_1** - описание инстанса **VRRP**. В этой секции некоторые параметры имеют различные значения на **master** и **slave** нодах): | ||
+ | \\ | ||
+ | Вот конфигурация резервной (slave) ноды: | ||
+ | < | ||
+ | | ||
+ | admin@domain.com | ||
+ | } | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | vrrp_script chk_haproxy { | ||
+ | script "/ | ||
+ | interval 2 | ||
+ | weight 2 | ||
+ | } | ||
+ | |||
+ | vrrp_instance VI_1 { | ||
+ | state MASTER | ||
+ | interface ens192 | ||
+ | virtual_router_id 101 | ||
+ | priority 100 | ||
+ | advert_int 1 | ||
+ | smtp_alert | ||
+ | authentication { | ||
+ | auth_type PASS | ||
+ | auth_pass superpassword | ||
+ | } | ||
+ | virtual_ipaddress { | ||
+ | 172.30.129.131 | ||
+ | } | ||
+ | track_script { | ||
+ | chk_haproxy | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Подключение клиентов ===== | ||
+ | Для подключения клиентов: | ||
+ | * Для внутренних клиентов мы создаем запись в DNS, которая указывает на виртуальный IP, а клиенты подключаются к сервису по DNS-имени. | ||
+ | * Для внешних клиентов делаем port-mapping с внешнего IP на внутренний виртуальный IP. | ||
+ | |||
+ | ====== Ссылки ====== | ||
+ | |||
+ | https:// | ||
+ | https:// | ||
+ | https:// | ||
+ | \\ | ||