Files
ayurishchevandClaude Opus 5 fa389f119b Шаг 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>
2026-08-19 12:33:48 +03:00

80 lines
2.0 KiB
Bash
Executable File

#!/bin/bash
# Генерация конфигурации демона hcd из topology.env — единственного источника
# правды по адресам стенда. Пока пул задан статически; на следующем шаге его
# место займёт модель Load_Balancer -> Listener -> Pool -> Member в OVSDB.
#
# MAC членов пула здесь не фигурирует (шаг 5): hcd резолвит его сам через
# neigh-таблицу ядра (hc/neigh.go) на интерфейсе "iface" и заливает в таблицу
# "adj_table" по указанному "ofport". См. docs/STEP5_SUMMARY.md.
set -euo pipefail
LB_DIR=/opt/lb
# shellcheck disable=SC1091
source "$LB_DIR/topology.env"
OUT=${1:-/var/run/openvswitch/hc.json}
cat > "$OUT" <<EOF
{
"bridge": "$BR",
"of_version": "$OF",
"pool_id": $POOL_ID,
"slots": $SLOTS,
"slot_table": 11,
"dnat_table": 12,
"adj_table": 21,
"probe": "$HC_PROBE",
"http_path": "$HC_HTTP_PATH",
"interval": "$HC_INTERVAL",
"timeout": "$HC_TIMEOUT",
"rise": $HC_RISE,
"fall": $HC_FALL,
"api": "$HC_API",
"apply_script": "$LB_DIR/apply.sh",
"members": [
{
"id": 1,
"name": "be1",
"address": "$BE1_IP",
"port": $BE1_PORT,
"weight": 1,
"source": "$HC2_IP",
"iface": "$HC2_IFNAME",
"ofport": $BE1_OFPORT
},
{
"id": 2,
"name": "be2",
"address": "$BE2_IP",
"port": $BE2_PORT,
"weight": 1,
"source": "$HC3_IP",
"iface": "$HC3_IFNAME",
"ofport": $BE2_OFPORT
},
{
"id": 3,
"name": "be3",
"address": "$BE3_IP",
"port": $BE3_PORT,
"weight": 1,
"source": "$HC2_IP",
"iface": "$HC2_IFNAME",
"ofport": $BE3_OFPORT
},
{
"id": 4,
"name": "be4",
"address": "$BE4_IP",
"port": $BE4_PORT,
"weight": 1,
"source": "$HC3_IP",
"iface": "$HC3_IFNAME",
"ofport": $BE4_OFPORT
}
]
}
EOF
echo "$OUT"