
Привет! Хочу поделиться реализованным кейсом на тему георезервирования между двумя инфраструктурными площадками. Эта информация может быть полезной для компаний или коллективов, которым нужно обеспечить автоматическую доступность критически важных сервисов, даже если один из инфраструктурных сегментов (ЦОДов) выйдет из строя.
На схеме продемонстрировано: способ подключения площадок между собой (direct connect), компоненты с настроенным пирингом (t0 asa), узлы haproxy и bird (ha1 ha2), а также критический сервис, состоящий из двух application узлов (app1 app2) и арбитра, руководящего процессом переключения в случае отказа основного узла (ControlNode).
Смысл состоит в ситуации, что если основная правая цепочка (dc asa -> ha1 -> app1) выходит из строя, то vip (10.10.1.15), как и критический app, все-равно остается доступен для серверного и пользовательского сегментов. Заранее могу сказать, что арбитр, стоящий в отличном от данных площадок месте, в случае выхода из строя никакой критики не несет.
С правой стороны маршрутизацией занимается asa cluster, который выступает в качестве пира для haproxy.
interface Port-channel47.137
bfd interval 500 min_rx 500 multiplier 3 ##таймеры bfd на интерфейсе
interface Port-channel47.180
bfd interval 500 min_rx 500 multiplier 3 ##таймеры bfd на интерфейсе
neighbor 10.100.1.11 remote-as 65668 ##сосед 1
neighbor 10.100.1.11 description * PAM *
neighbor 10.100.1.11 password 0 *****
neighbor 10.100.1.11 version 4
neighbor 10.100.1.11 fall-over bfd ##включеный bfd
neighbor 10.100.1.11 activate
neighbor 10.100.1.11 default-originate ##анонс дефолта
neighbor 10.100.1.11 prefix-list BGPAnycast_IN in ##что принимаем от соседа
neighbor 10.100.1.11 prefix-list BGPAnycast_OUT out ##что отдаём соседу
##Префис листы что принимаем, что отдаём
prefix-list BGPAnycast_IN seq 10 permit 10.10.1.0/24 le 32
!
prefix-list BGPAnycast_OUT seq 5 permit 0.0.0.0/0
На основании данного конфига ASA, конфигурация bird выполнена следующим образом:
log syslog all;
router id 10.100.1.11;
filter OUT {
if net ~ [ 10.10.1.15/32 ] then accept;
reject;
}
filter IN {
if net ~ [ 0.0.0.0/0 ] then accept;
reject;
}
protocol device {
debug { states,routes,filters,interfaces,events,packets };
}
protocol direct {
# disabled;
interface "ens160";
}
protocol kernel {
learn;
persist;
scan time 10;
import all;
export all;
graceful restart;
}
template bgp bgp_template {
debug { states,routes,filters,interfaces,events,packets };
description "Connection to BGP peer";
local as 65668;
gateway recursive;
add paths on;
graceful restart;
connect delay time 2;
connect retry time 5;
error wait time 5,30;
import filter IN;
export filter OUT;
bfd on;
}
protocol bgp ASA from bgp_template {
neighbor 10.100.1.1 as 65500;
source address 10.100.1.11;
password "ваш пароль";
}
# bfd
protocol bfd {
interface "ens160" {
min rx interval 500 ms;
multiplier 3;
};
import all;
export none;
neighbor 10.100.1.1;
}
protocol static {
route 10.10.1.15/32 via "ens160";
}
С левой стороны tier-0 gateway, но к сожалению поделится конфигурацией на уровне сетевых компонентов не могу, т.к. настраивалось коллегами предоставляющими данный инфраструктурный сервис/площадку.
Конфигурация bird с левой стороны выполнена следующим образом:
log syslog all;
router id 10.50.1.5;
filter OUT {
if net ~ [ 10.10.1.15/32 ] then accept;
reject;
}
filter IN {
if net ~ [ 0.0.0.0/0 ] then accept;
reject;
}
protocol device {
debug { states,routes,filters,interfaces,events,packets };
}
protocol direct {
# disabled;
interface "ens160";
}
protocol kernel {
learn;
persist;
scan time 10;
import all;
export all;
graceful restart;
}
template bgp bgp_template {
debug { states,routes,filters,interfaces,events,packets };
description "Connection to BGP peer";
local as 65668;
gateway recursive;
add paths on;
graceful restart;
connect delay time 2;
connect retry time 5;
error wait time 5,30;
import filter IN;
export filter OUT;
bfd on;
}
protocol bgp CLOUD_TO_1 from bgp_template {
neighbor 10.50.1.11 as 4241300161;
source address 10.50.1.5;
password "ваш пароль";
}
protocol bgp CLOUD_TO_2 from bgp_template {
neighbor 10.50.1.12 as 4241300161;
source address 10.50.1.5;
password "ваш пароль";
}
protocol bfd {
interface "ens160" {
min rx interval 500 ms;
multiplier 3;
};
import all;
export none;
neighbor 10.50.1.11;
neighbor 10.50.1.12;
}
protocol static {
route 10.10.1.15/32 via "ens160";
}
Стоит также добавить, что узлы HAProxy, после настройки BIRD, убирается на уровне ОС шлюз, так как BGP-пиринг самостоятельно предоставит шлюз вместе с требуемыми маршрутами. Узлы BIRD + HAProxy работают в составе Ubuntu 22.04. В качестве интерфейса для VIP выполнен dummy-адаптер, который описан в netplan. Для адаптера добавлена служба, чтобы в случае перезапуска узла IP (10.10.1.15) автоматически поднимался.
#!/bin/bash
sudo ip link add ens165 type dummy # Размещаем скрипт например /usr/local/bin/add_dummy_interface.sh
///
[Unit] # Сделаем службу для поднятия интерфейса в случае рестарта сервера
Description=Add Dummy
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/add_dummy_interface.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
///
network:
ethernets:
ens160:
addresses:
- 10.50.1.5/28
#gateway4: 10.50.1.1 # Шлюз комментим после применения bird, т.к. будет через пиринги
nameservers:
addresses:
- "ваши dns"
version: 2
network: # Второй интерфейс
ethernets:
ens165:
addresses:
- 10.10.1.15/32 # Используемый VIP
version: 2
///
#Для автоматического отключения bgp анонса в случае "падения" службы haproxy, можно использовать подобное решение
cat << EOF > /usr/local/bin/bird-haproxy-check.sh
#!/bin/bash
if ! systemctl is-active --quiet haproxy; then
birdc disable "name bgp"
else
birdc enable "name bgp"
fi
EOF
cat << EOF > /etc/systemd/system/bird-haproxy-check.service
[Unit]
Description=Monitor HAProxy
[Service]
ExecStart=/usr/local/bin/bird-haproxy-check.sh
EOF
cat << EOF > /etc/systemd/system/bird-haproxy-check.timer
[Unit]
Description=Run
[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
[Install]
WantedBy=timers.target
EOF
chmod o+x /usr/local/bin/bird-haproxy-check.sh
systemctl daemon-reload
systemctl enable bird-haproxy-check.timer
systemctl start bird-haproxy-check.timer
Ну и пример конфигурации haproxy для правой стороны
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option tcplog
option dontlognull
option http-server-close
option log-health-checks
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 15m
timeout server 15m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen stats
mode http
bind *:7000
stats enable
stats uri /
listen ssh
bind *:22
mode tcp
option allbackups
default-server inter 3s fall 2 rise 2 on-marked-down shutdown-sessions
server app01 app01:22 check
server app02 app02:22 check backup
Для левой стороны предполагаемый SSH будет выглядеть следующим образом:
listen ssh
bind *:22
mode tcp
option allbackups
default-server inter 3s fall 2 rise 2 on-marked-down shutdown-sessions
server app02 app02:22 check
server app01 app01:22 check backup
Естественно, данные настройки индивидуальны.