Files
poc-frr-anycast/README.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

85 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# poc_frr_anycast
POC anycast-топологии на FRR: две площадки, eBGP full-mesh, ECMP-балансировка трафика клиентов площадки B к anycast-адресу площадки A.
- **Дизайн (HLD):** [hld.md](hld.md) (в т.ч. Mermaid-диаграмма топологии)
- **История изменений:** [docs/](docs/) — на каждое изменение отдельный план внедрения и summary.
## Lab-окружение (Docker Compose)
Топология из `hld.md` поднимается локально в Docker Compose: 5 FRR-роутеров (a1/a2/a3 — площадка A, b1/b2 — площадка B) + 6 клиентских контейнеров площадки B. Каждый линк HLD — отдельная Docker-сеть с фиксированной адресацией, 1:1 соответствующая схеме из `hld.md`.
Детали архитектуры и обоснование решений: [docs/2026-09-03-anycast-lab-plan.md](docs/2026-09-03-anycast-lab-plan.md), результаты — [docs/2026-09-03-anycast-lab-summary.md](docs/2026-09-03-anycast-lab-summary.md).
### Запуск
```bash
docker compose up -d # поднять топологию (13 контейнеров)
./scripts/verify.sh # проверить BGP-сессии и ECMP-маршрут до 10.200.200.1/32
./scripts/traffic-test.sh [client] [count] # прогнать трафик к anycast, увидеть распределение по A1/A2/A3
docker compose down # разобрать окружение
```
Пример: `./scripts/traffic-test.sh c1 30` — 30 запросов с клиента `c1` (площадка B1) к anycast-адресу с варьированием src-port; ответ каждого anycast-узла (`a1`/`a2`/`a3`) содержит его hostname, что показывает распределение трафика.
### Структура
```
hld.md HLD-дизайн топологии
docker-compose.yml 13 контейнеров, 8 сетей (1 на линк)
frr/{a1,a2,a3,b1,b2}/ конфиги FRR (daemons, frr.conf, vtysh.conf)
entrypoints/ создание dummy0 + anycast-responder (A), маршрут по умолчанию (клиенты)
scripts/ verify.sh, traffic-test.sh
docs/ план внедрения + summary по каждому изменению
```
### Проверка окружения
Всё это уже автоматизировано в `./scripts/verify.sh` (BGP + маршруты) и `./scripts/traffic-test.sh` (трафик), но ниже — те же проверки вручную, командами на самих узлах.
#### На маршрутизаторах (`vtysh`)
Выполняются как `docker compose exec -T <node> vtysh -c "<command>"` или интерактивно: `docker compose exec <node> vtysh`.
| Команда | Где | Что должно быть в норме |
|---|---|---|
| `show bgp summary` | все 5 узлов | все соседи в состоянии `Established` (число вместо `Idle`/`Active` в колонке `State/PfxRcd`) — 2 соседа на a1/a2/a3, 3 на b1/b2 |
| `show ip route 10.200.200.1/32` | b1, b2 | 3 записи `* <ip>, via ethN, weight 1` — ECMP-маршрут до anycast через a1/a2/a3 |
| `show bgp ipv4 unicast 10.200.200.1/32` | b1, b2 | тот же префикс в BGP-таблице, 3 валидных пути, `Local AS 65001` у всех |
| `show ip bgp neighbor <ip> advertised-routes` | a1/a2/a3 (`<ip>` — сосед в сторону B) | среди анонсируемых — `10.200.200.1/32` |
| `show ip bgp neighbor <ip> advertised-routes` | b1, b2 (`<ip>` — сосед в сторону A) | среди анонсируемых — `10.100.1.0/24` (b1) / `10.100.2.0/24` (b2) |
| `show interface brief` | любой | все интерфейсы `up`, IP соответствуют `hld.md` |
Пример:
```bash
docker compose exec -T b1 vtysh -c "show bgp summary"
docker compose exec -T b1 vtysh -c "show ip route 10.200.200.1/32"
docker compose exec -T a1 vtysh -c "show ip bgp neighbor 10.0.1.2 advertised-routes"
```
#### На клиентах (площадка B, доверенная сеть)
Выполняются как `docker compose exec -T <client> <command>`, где `<client>` — один из `c1`…`c6`.
| Команда | Что должно быть в норме |
|---|---|
| `ping -c 4 10.200.200.1` | `0% packet loss`, ответы приходят с `ttl=63` (1 транзитный хоп — B-роутер) |
| `traceroute -n 10.200.200.1` | 2 хопа: локальный B-роутер (`10.100.1.1` / `10.100.2.1`), затем сразу `10.200.200.1` |
| `curl -s http://10.200.200.1/` | в ответе — hostname одного из `a1`/`a2`/`a3` (мини-HTTP на dummy0, см. `entrypoints/a-entrypoint.sh`) |
| серия `curl` с разным `--local-port` (см. `scripts/traffic-test.sh`) | ответы приходят от **разных** anycast-узлов — подтверждает, что ECMP реально распределяет трафик по 5-tuple, а не всегда уходит в один и тот же узел |
Пример:
```bash
docker compose exec -T c1 ping -c 4 10.200.200.1
docker compose exec -T c1 traceroute -n 10.200.200.1
docker compose exec -T c1 curl -s http://10.200.200.1/
./scripts/traffic-test.sh c1 30 # готовый прогон с разбивкой по узлам
```
Если `curl`/`ping` не проходят — сначала проверить BGP (`show bgp summary` на затронутых узлах), затем ECMP-маршрут (`show ip route 10.200.200.1/32` на b1/b2).
### Важные технические нюансы
- Линки между A и B заведены как `/29` (не `/30`, как в hld.md буквально) — Docker резервирует первый адрес подсети под gateway моста даже для `internal: true`-сетей, поэтому реальным peering-адресам (`.1`/`.2`, как в hld.md) нужно место рядом с ним. IP-адресация роутеров и логика BGP при этом полностью соответствуют hld.md.
- ECMP-балансировка на b1/b2 требует `net.ipv4.fib_multipath_hash_policy=1` (в `docker-compose.yml`) — по умолчанию (`0`) Linux хеширует next-hop только по src/dst IP, без учёта портов, из-за чего один клиент всегда попадал бы в один и тот же anycast-узел.