HAProxy для кластеров PGSQL, RabbitMQ, Redis

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

1.1. Установка и запуск сервиса

dnf install haproxy

systemctl enable haproxy --now

1.2. Настройка

В файле /etc/haproxy/haproxy.cfg укажите адреса нод кластеров psql, rabbitmq, redis

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    log /dev/log local0
    log /dev/log local1 notice
    #chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
  
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    tcp
    log                     global
    retries                 3
    timeout queue           5s
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout check           10s
 
listen stats
    mode http
    bind :7000
    stats enable
    stats uri /
 
### PostgreSQL ###
listen postgres_master
    bind :5000
    option tcplog
    option httpchk OPTIONS /master
    http-check expect status 200
    default-server inter 3s fastinter 1s fall 3 rise 4 on-marked-down shutdown-sessions
    server psql1 192.168.27.239:5432 check port 8008 #адрес первой ноды БД
    server psql2 192.168.27.219:5432 check port 8008 #адрес второй ноды БД
    server psql3 192.168.27.108:5432 check port 8008 #адрес третьей ноды БД
 
listen postgres_replicas
    bind :5001
    option tcplog
    option httpchk OPTIONS /replica
    balance roundrobin
    http-check expect status 200
    default-server inter 3s fastinter 1s fall 3 rise 2 on-marked-down shutdown-sessions
    server psql1 192.168.27.239:5432 check port 8008 #адрес первой ноды БД
    server psql2 192.168.27.219:5432 check port 8008 #адрес второй ноды БД
    server psql3 192.168.27.108:5432 check port 8008 #адрес третьей ноды БД
### PostgreSQL ###
 
### RabbitMQ ###
listen rabbitmq
    bind :5672
    mode tcp
    balance roundrobin
    server rabmq1 rabmq1.localdomain:5672 check inter 2s rise 2 fall 3 #адрес первой ноды брокера сообщений
    server rabmq2 rabmq2.localdomain:5672 check inter 2s rise 2 fall 3 #адрес второй ноды брокера сообщений
    server rabmq3 rabmq3.localdomain:5672 check inter 2s rise 2 fall 3 #адрес третьей ноды брокера сообщений
 
listen rabbitmq_management
    bind :15672
    balance source
    server rabmq1 rabmq1.localdomain:15672 check inter 2s #адрес первой ноды брокера сообщений
    server rabmq2 rabmq2.localdomain:15672 check inter 2s #адрес второй ноды брокера сообщений
    server rabmq3 rabmq3.localdomain:15672 check inter 2s #адрес третьей ноды брокера сообщений
### RabbitMQ ###
 
### Redis ###
frontend redis_master
  bind :6379
  mode tcp
  option tcplog
  option clitcpka
  timeout client 24h
  default_backend redis_master
 
backend redis_master
  balance first
  mode tcp
  timeout queue 2s
  timeout connect 2s
  timeout check 1s
  option srvtcpka
  timeout server 24h
  option tcp-check
  tcp-check connect
  tcp-check send AUTH\ SecretPassword\r\n #укажите пароль для мастера из пункта 3.2
  tcp-check send PING\r\n
  tcp-check expect string +PONG
  tcp-check send info\ replication\r\n
  tcp-check expect string role:master
  tcp-check send QUIT\r\n
  tcp-check expect string +OK
  server redis1 192.168.27.208:6379 check inter 5s
  server redis2 192.168.27.133:6379 check inter 5s
  server redis3 192.168.27.185:6379 check inter 5s
### Redis ###
  • haproxy -f /etc/haproxy/haproxy.cfg -d — для проверки конфигурации
  • sysmtectl status haproxy — для проверки статуса сервиса

2.1. Дополнительные ноды для отказоустойчивости — опционально

Для минимизации времени простоя сервера с внутренним балансером возможно реализовать отказоустойчивый кластер с использованием нескольких экземпляров HAProxy.

Для реализации потребуется дополнительный IP адрес в сети, рекомендуется использовать внутренний для обеспечения безопасности доступа к кластерами других нод. Ноды будут использовать один виртуальный IP адрес при обращении к сервисам PostgreSQL, RabbitMQ, Redis.

В статье используется внутренний IP адрес 192.168.26.27 как VRRP (Virtual Router Redundancy Protocol) — это сетевой протокол, предназначенный для обеспечения отказоустойчивости маршрутизаторов или шлюзов в локальной сети. При настройке использовался на сервере с одним портом с внутренним IP. В дальнейшем к этому интерфейсу будет привязан виртуальный адрес 192.168.26.27

2.2. Установка

На основной ноде потребуется дополнительно установить сервис:

dnf install keepalived -y

На всех дополнительных нодах потребуется установка сервисов:

dnf install haproxy keepalived -y

и добавьте в автозагрузку

systemctl enabled keepalived haproxy

2.3. Настройка

2.3.1. На основной ноде

2.3.1.1. Создайте каталог
mkdir -p /usr/libexec/keepalived

и создайте файл /usr/libexec/keepalived/haproxy_check.sh с содержимым:

#!/bin/bash
/bin/kill -0 $(cat /var/run/haproxy.pid)

Скрипт проверяет, запущен ли процесс HAProxy, используя его PID для мониторинга состояния службы.

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

/etc/keepalived/keepalived.conf

global_defs {
  router_id haproxy-server1
  enable_script_security
  script_user root
}
 
vrrp_script haproxy_check {
  script "/usr/libexec/keepalived/haproxy_check.sh"
  interval 1
  weight -20
  fall 2
  rise 2
}
 
vrrp_instance VI_1 {
  interface ens3
  virtual_router_id 101
  priority 100
  advert_int 1
  state MASTER
  virtual_ipaddress {
    192.168.26.27
  }
  track_script {
    haproxy_check weight 20
  }
  authentication {
    auth_type PASS
    auth_pass SecretPassword
  }
}

Где введённые параметры:

  • router_id — ID роутера, уникальное значение на каждом узле;
  • script_user — пользователь, от имени которого будут запускаться скрипты VRRP;
  • interface — наименование интерфейса, к которому будет привязан keepalived;
  • virtual_router_id — ID виртуального роутера, общее значение на всех узлах;
  • priority — приоритет нод внутри виртуального роутера;
  • state — тип роли ноды в виртуальном роутере;
  • virtual_ipaddress — виртуальный IP;
  • auth_type — тип аутентификации в виртуальном роутере;
  • auth_pass — указывается пароль.

2.4. На дополнительных нодах

2.5. Скопируйте ранее установленные значения из /etc/hosts и укажите значения на новых нодах

2.6. Скопируйте конфигурацию /etc/haproxy/haproxy.cfg и укажите конфигурацию на новых нодах

2.7. Создайте каталог

mkdir -p /usr/libexec/keepalived

Создайте файл /usr/libexec/keepalived/haproxy_check.sh с содержимым:

#!/bin/bash
/bin/kill -0 $(cat /var/run/haproxy.pid)

2.8. Измените конфигурацию

/etc/keepalived/keepalived.conf

global_defs {
  router_id haproxy-server2
  enable_script_security
  script_user root
}
 
vrrp_script haproxy_check {
  script "/usr/libexec/keepalived/haproxy_check.sh"
  interval 1
  weight -20
  fall 2
  rise 2
}
 
vrrp_instance VI_1 {
  interface ens3
  virtual_router_id 101
  priority 90
  advert_int 1
  state BACKUP
  virtual_ipaddress {
    192.168.26.27
  }
  track_script {
    haproxy_check weight 20
  }
  authentication {
    auth_type PASS
    auth_pass SecretPassword
  }
}

За основу взята конфигурация с основной ноды и внесены правки в параметры:

  • router_id — укажите уникальные названия для каждой ноды
  • priority — приоритет нод внутри виртуального роутера;
  • state — тип роли ноды в виртуальном роутере;

2.9. Перезапустите на всех нодах сервисы:

systemctl restart keepalived haproxy

3.1. Настройка Корпоративного сервера

3.1.1. Внесите правки в конфигурации на всех нодах api

/opt/r7-office/Api/appsettings.json

"ConnectionStrings": {
    "R7StorageServerUserActions": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "R7StorageServer": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "CommunityRepository": "Server=localhost;UserID=root;Password=test;Database=r7-office",
    "Payments": "Database=Payments;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "GeoNames": "Database=GeoNames;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;"
  },
  "rabbitMq": {
    "host": "192.168.26.27",
    "username": "r7office",
    "password": "r7office",
    "timeout": 10
  },

/opt/r7-office/Sso.Api/appsettings.json:

"ConnectionStrings": {
    "R7StorageServerUserActions": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "R7StorageServer": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "CommunityRepository": "Server=localhost;UserID=root;Password=p@ssw0rd;Database=r7-office",
    "Payments": "Database=Payments;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "GeoNames": "Database=GeoNames;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;"
  },
"rabbitMq": {
    "host": "192.168.26.27",
    "username": "r7office",
    "password": "r7office",
    "timeout": 10
  },

и нодах processing

/opt/r7-office/Processing/appsettings.json

"ConnectionStrings": {
    "R7StorageServerUserActions": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "R7StorageServer": "Database=cddisk;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "CommunityRepository": "Server=localhost;UserID=root;Password=test;Database=r7-office",
    "Payments": "Database=Payments;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;",
    "GeoNames": "Database=GeoNames;Username=cddisk;Password=cddisk;Host=192.168.26.27;Port=5000;"
  },
  "DbType": "postgre",
  "rabbitMq": {
    "host": "192.168.26.27",
    "username": "r7office",
    "password": "r7office",
    "timeout": 10
  }

с указанием параметров подключения к виртуальному IP адресу 192.168.26.27

3.1.2. Перезапустите на нодах api и processing службы:

supervisorctl restart all

4.1. Настройка Сервера документов

4.1.1. Выполните повторную конфигурацию

скриптом documentserver-configure.sh по пункту 6.3.1. этой статьи и укажите параметры с виртуальным IP адресом 192.168.26.27

4.1.2. Далее внесите правки

в /etc/r7-office/documentserver/local.json и в /etc/r7-office/documentserver/default.json, указав параметры с виртуальным IP адресом 192.168.26.27

4.1.3. Выполните перезапуск служб сервера документов:

systemctl restart ds-*
Была ли полезна статья?
Позвольте нам стать лучше