
Привет! Хочу поделиться реализованным кейсом на тему георезервирования между двумя инфраструктурными площадками. Эта информация может быть полезной для компаний или коллективов, которым нужно обеспечить автоматическую доступность критически важных сервисов, даже если один из инфраструктурных сегментов (ЦОДов) выйдет из строя.
На схеме продемонстрировано: способ подключения площадок между собой (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
Естественно, данные настройки индивидуальны.
