Pull to refresh

Балансировка нагрузки с Pacemaker и IPaddr (Active/Active cluster)

Reading time5 min
Views32K


Хочу рассказать вам еще об одном способе балансировки нагрузки. Про Pacemaker и IPaddr (ресурс-агент) и настройке его для Active/Passive кластера сказано уже и так достаточно много, но информации по организации полноценного Active/Active кластера, используя этот модуль я нашел крайне мало. Постараюсь исправить эту ситуацию.


Для начала расскажу подробнее чем такой метод балансировки примечателен:


  • Отсутсвие внешнего балансировщика — На всех нодах в кластере настраивается один общий виртуальный IP-адрес. Все запросы отправляются на него. Ноды отвечают на запросы на этот адрес случайно и по договоренности между ссобой.
  • Высокая доступность — Если одна нода падает ее обязаности подхватывает другая.
  • Простота настройки — Настройка осуществляется всего в 3-5 команд.

Вводные данные


Давайте посмотрим на картинку в начале статьи, мы увидим следующие устройства:


  • Gateway — IP: 192.168.100.1
  • HostA — IP: 192.168.100.101
  • HostB — IP: 192.168.100.102
  • HostC — IP: 192.168.100.103

Клиенты будут обращаться на внешний адрес нашего шлюза, тот будет перенаправлять все запросы на виртуальный IP 192.168.100.100, который будет настроен на всех трех нодах нашего кластера.


Подготовка


Для начала нам нужно убедиться в том, что все наши ноды могут обращаться друг к другу по single hostname, для надежности лучше сразу добавить адреса нод в /etc/hosts:


192.168.100.101    hostA
192.168.100.102    hostB
192.168.100.103    hostC

Установим все необходимые пакеты:


yum install pcs pacemaker corosync #CentOS, RHEL
apt-get install pcs pacemaker corosync #Ubuntu, Debian

При установке pcs создает пользователя hacluster, давайте зададим ему пароль:


echo CHANGEME | passwd --stdin hacluster 

Дальше операции выполняются на одном узле.
Настраиваем аутентификацию:


pcs cluster auth HostA HostB HostC -u hacluster -p CHANGEME --force 

Создаём и запускаем кластер “Cluster” из трех узлов:


pcs cluster setup --force --name Cluster hostA hostB hostC
pcs cluster start --all

Смотрим результат:


pcs cluster status

Вывод
Cluster Status:
 Last updated: Thu Jan 19 12:11:49 2017
 Last change: Tue Jan 17 21:19:05 2017 by hacluster via crmd on hostA
 Stack: corosync
 Current DC: hostA (version 1.1.14-70404b0) - partition with quorum
 3 nodes and 0 resources configured
 Online: [ hostA hostB hostC ]

PCSD Status:
  hostA: Online
  hostB: Online
  hostC: Online

Некоторые шаги были позаимствованы из статьи Lelik13a, спасибо ему за это.


В нашем конкретном случае ни кворум ни stonith нашему кластеру не требуется, так что смело отключаем и то и другое:


pcs property set no-quorum-policy=ignore
pcs property set stonith-enabled=false

В дальнейшем, если у вас появятся ресурсы для которых это необходимо, вы можете обратиться к статье Silvar.


Пара слов о MAC-адресах


Прежде чем мы приступим, нам нужно понимать что на всех наших нодах будет настроен одинаковый IP и одинаковый mac-адрес, по запросу на который они будут поочередно давать ответы.


Проблема в том, что каждый коммутатор работает таким образом, что во время работы он составляет свою таблицу коммутации, в которой каждый mac-адрес связывается с определенным физическим портом. Таблица коммутации составляется автоматически, и служит для разгрузки сети от "ненужных" L2-пакетов.


Так вот, если mac-адрес есть в таблице коммутации, то пакеты будут отправляться только в один порт за которым и закреплен этот самый mac-адрес.


К сожалению, нам это не подходит и нам необходимо удостовериться в том, что бы все наши хосты в кластере одновременно "видели" все эти пакеты. В противном случае эта схема работать не будет.


Для начала нам нужно удостовериться в том, что используемый нами mac-адрес является multicast-адресом. То есть находится в диапазоне 01:00:5E:00:00:0001:00:5E:7F:FF:FF. Получив пакет для такого адреса наш коммутатор будет передавать его во все остальные порты, кроме порта источника. Кроме того, некоторые управляемые коммутаторы позволяют настроить и определить несколько портов для конткретного MAC-адреса.


Также вам вероятно придется отключить функцию Dynamic ARP Inspection, если она поддерживается вашим коммутатором, так как она может стать причиной блокировки arp-ответов от ваших хостов.


Настройка IPaddr-ресурса


Вот мы и добрались до самого интересного.


На данный момент существует две версии IPaddr с поддержкой клонирования:


  • IPaddr2 (ocf:heartbeat:IPaddr2) — Стандартный ресурс-агент для создания и работы виртуального IP-адреса. Как правило устанавливается вместе со стандартным пакетом resource-agents.


  • IPaddr3 (ocf:percona:IPaddr3) — Улучшенная версия IPaddr2 от Percona.
    В эту версию включены исправления ориентированные на работу именно в режиме clone.
    Требуется отдельная установка.

Для установки IPaadr3 выполните эти команды на каждом хосте:


curl --create-dirs -o /usr/lib/ocf/resource.d/percona/IPaddr3 \
    https://raw.githubusercontent.com/percona/percona-pacemaker-agents/master/agents/IPaddr3
chmod u+x /usr/lib/ocf/resource.d/percona/IPaddr

Дальше операции выполняются на одном узле.


Создадим ресурс для нашего виртуального IP-адреса:


pcs resource create ClusterIP ocf:percona:IPaddr3 \
    params ip="192.168.100.100" cidr_netmask="24" nic="eth0" clusterip_hash="sourceip-sourceport" \
    op monitor interval="10s"

clusterip_hash — здесь нужно указать желаемый тип распределения запросов.
Всего может быть три варианта:


  • sourceip — распределение только по IP-адресу источника, это гарантирует что все запросы от одного источника всегда будут попадать на один и тот же хост.
  • sourceip-sourceport — распределение по IP-адресу источника и исходящему порту. Каждое новое соединение будет попадать на новый хост. Оптимальный вариант.
  • sourceip-sourceport-destport — распределение по IP-адресу источника исходящему порту и порту назначения. Обеспечивает наилучшее распределение, актуально если у вас работает несколько сервисов на разных портах.

Для IPaddr2 обязательно нужно указать параметр mac=01:00:5E:XX:XX:XX с mac-адресом из multicast-диапазона. IPaddr3 устанавливает его автоматически.


Теперь склонируем наш ресурс:


pcs resource clone ClusterIP \
    meta clone-max=3 clone-node-max=3 globally-unique=true

Это действие создаст следующее правило в iptables:


Правило
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
  all  --  anywhere             192.168.100.100       CLUSTERIP hashmode=sourceip-sourceport clustermac=01:00:5E:21:E3:0B total_nodes=3 local_node=1 hash_init=0

Как вы можете заметить, здесь используется модуль CLUSTERIP.


Работает он следующим образом:


На три ноды приходят все пакеты, но все три Linux-ядра знают сколько нод получает пакеты, все три ядра нумеруют получаемые пакеты по единному правилу, и, зная сколько всего нод и номер своей ноды, каждый сервер обрабатывает только свою часть пакетов, остальные пакеты сервером игнорируются — их обрабатывают другие сервера.


Подробнее об этом написанно в этой статье.


Давайте еще раз посмотрим на наш кластер:


pcs cluster status

Вывод
Cluster Status:
Cluster name: cluster
Last updated: Tue Jan 24 19:38:41 2017
Last change: Tue Jan 24 19:25:44 2017 by hacluster via crmd on hostA

 Stack: corosync
 Current DC: hostA (version 1.1.14-70404b0) - partition with quorum
 3 nodes and 0 resources configured
 Online: [ hostA hostB hostC ]

Full list of resources:

Clone Set: ClusterIP-clone [ClusterIP-test] (unique)
    ClusterIP:0   (ocf:percona:IPaddr3): Started hostA
    ClusterIP:1   (ocf:percona:IPaddr3): Started hostB
    ClusterIP:2   (ocf:percona:IPaddr3): Started hostC

PCSD Status:
  hostA: Online
  hostB: Online
  hostC: Online

IP-адреса успешно запустились. Пробуем обратиться к ним снаружи.
Если все работает как надо, то на этом настройку можно считать законченой.


Ссылки


Tags:
Hubs:
Total votes 15: ↑15 and ↓0+15
Comments10

Articles