воскресенье, 1 марта 2015 г.

Отказоустойчивый, масштабируемый кластер приложения с балансировкой нагрузки, часть 2 (про масштабирование и про ARP Flux)

Возвращаясь к статье Отказоустойчивый, масштабируемый кластер приложения с балансировкой нагрузки, может создаться впечатление, что масштабировать кластер можно, просто добавляя дополнительные ноды. Масштабируемость, на первый взгляд, будет ограничена количеством адресов в сетевом сегменте. Но внимание: чем больше нод, тем больше будет утилизация конечного приложения, и тем больше будет не целевого трафика в сегменте. Этому виной будут перекрестные проверки нод на доступность ресурсов. Следовательно, количество нод, которые могут выполнять функции балансировки, должно быть разумно ограниченным. По моему мнению четыре вполне достаточно. Рассмотрим, как можно преодолеть эту проблему.
Создадите сервер приложения аналогично предыдущим, но keepalived не ставьте. Добавьте интерфейс loopback с общим ip кластера:

# cat /etc/sysconfig/network-scripts/ifcfg-lo:0
DEVICE=lo:0
IPADDR=192.168.3.100
NETMASK=255.255.255.255
ONBOOT=yes

Не спешите применять настройки. Поговорим вот еще о каком аспекте: по умолчанию linux сервер c несколькими интерфейсами в одной сети будет отвечать на ARP запрос, пришедший на любой локальный интерфейс и содержащий любой целевой локальный ip адрес. Звучит запутанно, покажу на примере: предположим на хосте есть два интерфейса с ip 192.168.3.200 и 192.168.3.201, тогда:

# arping -I eth0 192.168.3.200
ARPING 192.168.3.4 from 192.168.3.102 eth0
Unicast reply from 192.168.3.200 [52:54:00:BD:DF:C2]  1.362ms
Unicast reply from 192.168.3.200 [52:54:00:10:11:35]  1.209ms

Мы получаем два разных ARP ответа, эта проблема называется ARP Flux. Если мы сейчас включим интерфейс lo:0 это, в свою очередь, может стать причиной ARP Poisoning. Для того, чтобы решить эту проблему, необходимо поменять эту модель поведения работы ARP (host based model) на интерфейсо-зависимую (interface based model). Выставите следующие переменные ядра:

# echo -e "net.ipv4.conf.all.arp_ignore = 1 \nnet.ipv4.conf.all.arp_announce = 2" >> /etc/sysctl.d/99-sysctl.conf

Что эти переменные означают:
net.ipv4.conf.all.arp_ignore - определяет различные режимы ответа, на входящие ARP запросы, которые производят разрешение локальных IP адресов. Возможные значения:
  • 0 - установлено по умолчанию. Ответ производится на ARP запрос, пришедший на любой сетевой интерфейс системы, на разрешение любого целевого локального IP адреса.
  • 1 - ответ производится в случае, если ARP запрос на разрешение IP адреса пришел на интерфейс, содержащий этот IP адрес.
  • 2 - ответ производится в случае, если ARP запрос на разрешение IP адреса пришел на интерфейс, содержащий этот IP адрес, причем IP адрес отправителя должен находится в одной подсети целевым IP адресом.
  • 3 - не отвечать, если IP адрес источника находится в той же сети.
  • 4-7 - зарезервированы.
  • 8 - не отвечать на запросы.
net.ipv4.conf.all.arp_announce - определяет, каким образом будет анонсироваться локальный IP адрес в исходящих ARP запросах:
  • 0 - установлено по умолчанию. Используется любой локальный адрес, настроенный на любом интерфейсе.
  • 1 - попытаться исключить локальные адреса, которые не принадлежат к подсети. в которой находится целевой IP адрес. В случае отсутствия такого локального IP адреса будет использоваться поведение за номером 2.
  • 2 - Всегда использовать лучший локальный адрес, с которого нам удобно посылать запрос в целевую подсеть. Такой IP адрес выбирается из первичных IP адресов, находящихся в той же подсети, что и целевой IP адрес, на всех локальных интерфейсах. Если ничего подходящего нет, то будет использован первый ip адрес на интерфейсе, с которого будет произведен запрос или на всех других интерфейсах.
Теперь можно применить изменения и добавить новый сервер приложения в конфигурацию keepalived на всех нодах балансировщиках.