Шаг 5: динамическое изучение MAC/ARP для бэкендов

MAC каждого члена пула больше не статическая константа в topology.env,
а резолвится демоном hcd через обычный ARP ядра — в реальном
окружении MAC бэкенда заранее не известен (сервер ещё не подключён,
NIC может замениться), топология не описывается статически, в отличие
от стенда.

hcif-порты (единственные адреса узла в ядре) уже были настоящими
L3-интерфейсами в тех же сегментах, что и бэкенды — единственное, что
мешало обычному ARP, это permanent-записи ip neigh в entrypoint.sh.
Убрав их и добавив hc/neigh.go (читает ip -json neigh show, точечно
заливает бандл в таблицу 21 на том же тикере, что и health-пробы),
получили резолвер без нового OpenFlow-контроллера.

Таблица 21 стала единственным источником MAC для обоих путей —
маршрутизируемого и коммутируемого (шаг 3): таблица 12 больше не
дублирует MAC инлайново, ct(commit) ведёт сразу в таблицу 21.

Исправлен попутно найденный баг: после apply.sh (replace-flows)
таблица 21 не восстанавливалась, поскольку syncNeighbors сравнивал
MAC с памятью демона, а не с датапасом. Добавлен force-режим по
аналогии с Agent.apply(), плюс регрессионная проверка в verify.sh.

Проверено на живом стенде: MAC всех четырёх членов резолвлен и
совпадает с реальными интерфейсами; смена MAC "железа" обнаружена и
применена без вмешательства за счёт штатного старения ARP ядра.
Регрессия: 94 из 94 проверок.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ayurishchevandClaude Opus 5 committed 2026-08-19 12:33:48 +03:00
1 parent f34d2edefa
commit fa389f119b
17 files changed
+678 -61

No files matched your search

+76
View File
@@ -666,6 +666,78 @@ docker compose exec lb-router /opt/lb/apply.sh
---
## Блок K. Динамическое изучение MAC/ARP (шаг 5)
MAC каждого члена пула больше не статическая константа — его резолвит демон
`hcd` через обычный ARP ядра. Проверяем, что это действительно так, а не
осталось прежним поведением под новым названием.
**Шаг K.1 [Х]** — MAC членов пула резолвлен и совпадает с реальным:
```bash
make neigh
docker compose exec be1 ip link show eth0 | grep link/ether
```
Ожидается: `lbctl neigh` показывает у `be1` состояние «да» (резолвлен) и MAC,
совпадающий с выводом `ip link show` внутри контейнера `be1`.
**Шаг K.2 [Х]** — MAC действительно используется в датапасе:
```bash
docker compose exec lb-router ovs-ofctl -O OpenFlow15 dump-flows br-lb table=21 \
| grep priority=100
```
Ожидается: по правилу `priority=100,ip,nw_dst=<адрес члена>` на каждого
живого члена, `actions` содержат тот же MAC, что и в `make neigh`.
**Шаг K.3 [Х]** — обнаружение смены MAC «железа» без перезапуска стенда:
```bash
docker compose exec be1 ip link set eth0 down
docker compose exec be1 ip link set eth0 address 02:42:0a:14:00:99
docker compose exec be1 ip link set eth0 up
docker compose exec be1 ip route replace 192.168.5.0/24 via 10.20.0.1
docker compose exec be1 ip route replace 10.30.0.0/24 via 10.20.0.1
docker compose exec be1 ip route replace default via 10.20.0.254
```
Ожидается: не сразу, а в течение примерно двух минут (обычное старение ARP
ядра — `hcd` опрашивает быстро, но отражает только то, что уже узнало ядро)
`make neigh` покажет у `be1` новый MAC `02:42:0a:14:00:99`, и трафик к нему
продолжит доставляться:
```bash
watch -n5 'docker compose exec -T lb-router lbctl neigh'
# в отдельном терминале, после смены MAC в neigh:
docker compose exec cli2 curl -s http://10.20.0.2:8080/
```
Вернуть `be1` в исходное состояние (родной MAC пропишет заново
`scripts/attach-segment.sh`):
```bash
docker compose restart be1
sleep 2 && sudo scripts/attach-segment.sh
sleep 6 && make neigh
```
**Шаг K.4 [Х]** — заливка таблицы 21 переживает перезаливку пайплайна:
```bash
make health | grep -A1 дайджест # или просто make neigh — запомнить MAC
make flows
make neigh # те же MAC на месте, без ручного вмешательства
```
Смысл: `make flows` (`apply.sh`) стирает весь пайплайн вместе с таблицей 21;
`/reapply` у `hcd` обязан восстановить и таблицу слотов, и таблицу adjacency —
без этого второй `make neigh` показал бы пустые записи до следующего
естественного изменения MAC (которого может не случиться никогда).
---
## Итоговый чек-лист
| # | Проверка | Результат |
@@ -694,6 +766,10 @@ docker compose exec lb-router /opt/lb/apply.sh
| J | Ответ от соседа по сегменту приходит с неуменьшенным TTL | ☐ |
| J | Трафик между ВМ сегмента не блокирован | ☐ |
| J | `PRIV_LISTENERS` выключает листенер, не трогая связность | ☐ |
| K | MAC членов пула резолвлен и совпадает с реальным MAC интерфейса | ☐ |
| K | Таблица 21 содержит правило приоритета 100 с этим MAC | ☐ |
| K | Смена MAC «железа» обнаружена без перезапуска стенда | ☐ |
| K | Таблица 21 переживает `make flows` | ☐ |
---