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
This commit is contained in:
commit
eaa577e6b7
30 files changed
+1035
No files matched your search
@@ -0,0 +1,84 @@
|
||||
# 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-узел.
|
||||
Reference in new issue
Block a user