Files
poc-frr-anycast/docs/2026-09-03-anycast-lab-plan.md
T
ayurishchevandClaude Sonnet 5 eaa577e6b7 Add FRR anycast lab: HLD, containerized topology, docs
Реализует HLD-дизайн (hld.md) в виде развёртываемого Docker Compose
окружения: 5 FRR-роутеров (A1-A3 anycast 10.200.200.1/32 на AS 65001,
B1/B2 на AS 65002/65003) + 6 клиентских контейнеров, ECMP-балансировка
трафика клиентов площадки B к anycast-адресу площадки A.

- docker-compose.yml, frr/*, entrypoints/* — топология и конфиги FRR
- scripts/verify.sh, scripts/traffic-test.sh — проверка BGP/ECMP и трафика
- hld.md — HLD-дизайн + Mermaid-диаграмма топологии
- README.md — запуск, структура, команды проверки на роутерах и клиентах
- docs/ — планы внедрения и summary по каждому изменению

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bc3HkMiDwooSyLBLoMKNyF
2026-09-03 12:52:44 +03:00

4.4 KiB
Raw Blame History

План внедрения: контейнерный POC anycast-топологии FRR

Дата: 2026-09-03 Источник: hld.md

Цель

Развернуть в Docker Compose топологию из hld.md (5 FRR-роутеров, anycast 10.200.200.1/32 на площадке A, клиентские сети площадки B) и убедиться, что трафик от клиентов B реально распределяется по ECMP между тремя anycast-узлами A1/A2/A3.

Проверка окружения (выполнена)

  • Docker 28.3.2 + Compose plugin v2.38.2 — доступны, NET_ADMIN-контейнеры работают.
  • frrouting/frr:latest (Alpine 3.16) — тянется из Docker Hub, содержит vtysh, zebra, bgpd, staticd, ip, ping, python3, nc. Кастомный образ не нужен.
  • Модуль ядра dummy доступен — anycast-интерфейс на A-узлах создаётся в рантайме через ip link add dummy0 type dummy.
  • containerlab не устанавливаем — Docker Compose с internal-сетями на каждый p2p-линк полностью закрывает задачу без дополнительных зависимостей.

Архитектура

Каждый линк HLD (/30 A↔B, /24 клиентские сегменты) — отдельная Docker-сеть internal: true со статическими IP на участниках (без Docker-gateway, который иначе занял бы адрес в /30).

Сеть CIDR Участники
link-a1-b1 10.0.1.0/30 a1 (.1), b1 (.2)
link-a1-b2 10.0.2.0/30 a1 (.1), b2 (.2)
link-a2-b1 10.0.3.0/30 a2 (.1), b1 (.2)
link-a2-b2 10.0.4.0/30 a2 (.1), b2 (.2)
link-a3-b1 10.0.5.0/30 a3 (.1), b1 (.2)
link-a3-b2 10.0.6.0/30 a3 (.1), b2 (.2)
net-b1-clients 10.100.1.0/24 b1 (.1), c1 (.11), c2 (.12), c3 (.13)
net-b2-clients 10.100.2.0/24 b2 (.1), c4 (.14), c5 (.15), c6 (.16)
  • a1/a2/a3: frrouting/frr:latest, cap_add: [NET_ADMIN, NET_RAW]. Кастомный entrypoint создаёт dummy0 (10.200.200.1/32) и поднимает HTTP-responder на этом адресе (отдаёт hostname контейнера — видно, какой узел ответил), затем стартует штатный docker-start FRR. Конфиг — прямая транскрипция A1/A2/A3 из hld.md.
  • b1/b2: frrouting/frr:latest, конфиг — транскрипция B1/B2 из hld.md (bgp bestpath as-path multipath-relax, maximum-paths 3).
  • c1…c6: nicolaka/netshoot (ping/curl/traceroute/iperf3/mtr), entrypoint выставляет статический IP и ip route add default via <B-роутер>.

Файлы

docker-compose.yml
frr/{a1,a2,a3,b1,b2}/{daemons,frr.conf,vtysh.conf}
entrypoints/{a-entrypoint.sh,b-entrypoint.sh,client-entrypoint.sh}
scripts/{verify.sh,traffic-test.sh}
docs/2026-09-03-anycast-lab-plan.md      (этот файл)
docs/2026-09-03-anycast-lab-summary.md   (по завершении)
README.md                                 (дополняется)

Шаги

  1. FRR-конфиги для 5 узлов (daemons, frr.conf, vtysh.conf).
  2. Entrypoint-скрипты (dummy0 + anycast responder для A; статическая адресация для клиентов).
  3. docker-compose.yml — 8 сетей + 5 роутеров + 6 клиентов.
  4. scripts/verify.sh — проверка BGP-сессий (Established) и ECMP-маршрута до 10.200.200.1/32 (3 пути) на b1/b2.
  5. scripts/traffic-test.sh — ping/traceroute/curl-цикл с клиентов, демонстрирующий распределение трафика по A1/A2/A3.
  6. Поднятие (docker compose up -d), прогон проверок.
  7. Обновление README.md.
  8. Summary-артефакт с результатами.

Definition of done

  • Все 13 контейнеров поднимаются без ошибок.
  • На b1/b2: 3 Established BGP-сессии, 3 ECMP-пути до 10.200.200.1/32.
  • С клиентов ping 10.200.200.1 проходит; traffic-test.sh показывает ответы от разных anycast-узлов (a1/a2/a3) при варьировании src-port.