Уважаемые, любимые люди на ServerFault. Я пытаюсь (и не могу) настроить массив серверов MySQL с балансировкой нагрузки. Пожалуйста, просветите меня, покажите мне ошибку в моем пути.
Текущая настройка: два сервера MySQL с выделенными фиксированными IP-адресами (10.116.219.47 и 10.116.219.48) и один виртуальный IP-адрес, который используется совместно с keepalived (10.116.219.12). Эта установка успешно обеспечивает аварийное переключение. DB2-сервер быстро вступит во владение, если мы отключим DB1-сервер. Только при добавлении блока virtual_server в конфигурацию все начинает ломаться.
DB1
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 60
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 3S83hbt200SbwY6
}
virtual_ipaddress {
10.116.219.12
}
}
DB2
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 60
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 3S83hbt200SbwY6
}
virtual_ipaddress {
10.116.219.12
}
}
Мы пытались добавить балансировку нагрузки в конфигурацию keepalived, но здесь DB2 перестает отвечать.
virtual_server 10.116.219.12 3306 {
delay_loop 2
lb_algo rr
lb_kind DR
protocol TCP
real_server 10.116.219.47 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
real_server 10.116.219.48 3306 {
weight 10
TCP_CHECK {
connect_port 3306
connect_timeout 1
}
}
}
Попытка подключиться к виртуальному ip (10.116.219.12) будет чередоваться при успешном ответе от DB1 или тайм-ауте от DB2.
На данный момент отладка:
Таким образом, похоже, что сервер MySQL MySQL отказывается отвечать, я предполагаю, что место назначения входящего пакета (общий виртуальный IP-адрес) не известно серверу DB2, потому что DB1 передает его как ведущее устройство поддержки активности.
Поскольку вы используете прямую маршрутизацию, виртуальный IP-адрес необходимо настроить на обоих серверах одновременно. Вы можете добиться этого, имея второй экземпляр vrrp, который настраивает VIP (10.116.219.12) на интерфейсе обратной связи вторичного сервера. Когда соединение перенаправляется от балансировщика нагрузки на вторичный сервер, он будет отвечать на eth0 как обычно.
Если вы сделаете это, вам нужно будет отключить маршрутизацию от источника через sysctl. Например:
# Do not accept source routing net.ipv4.conf.default.accept_source_route = 0
Кроме того, вам необходимо изменить способ объявления ARP и ответа на запросы (больше информации):
net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2
Также настройте фильтрацию rp:
net.ipv4.conf.eth0.rp_filter = 1 # Works for CentOS 5 or net.ipv4.conf.eth0.rp_filter = 2 # Works for CentOS 6+
Параметр rp_filter по умолчанию может варьироваться в зависимости от версии ядра, поэтому убедитесь, что вы выбрали правильный параметр. Больше информации.
Чтобы расширить ответ Джина и получить jnovack, который "не утерян", на CentOS 7 у меня сработало следующее:
На обоих серверах MySQL создайте файл /etc/sysconfig/network-scripts/ifcfg-lo:1
содержащий
DEVICE=lo:1
BOOTPROTO=static
ONBOOT=yes
IPADDR=***your keepalived virtual IP***
NETMASK=255.255.255.255
На обоих серверах MySQL настройте sysctl с помощью (не забудьте sysctl -p
перезагрузить)
net.ipv4.ip_nonlocal_bind=1
net.ipv4.ip_forward=1
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.default.arp_announce=2
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0
net.ipv4.tcp_syncookies=1
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
Перезапустите сетевую службу
systemctl restart network
# service network restart on CentOS 6
(вы можете проверить свой новый виртуальный интерфейс при выполнении loopback ifconfig
)
Перезапустите keepalived
служба
systemctl restart keepalived
# service keepalived restart on CentOS 6