#!/bin/bash # Инструмент осмотра датапаса. Запускается внутри контейнера lb-router: # docker compose exec lb-router lbctl <команда> set -euo pipefail LB_DIR=/opt/lb # shellcheck disable=SC1091 source "$LB_DIR/topology.env" usage() { cat < вывести член из балансировки (пробы продолжаются) enable <член> вернуть член в балансировку metrics метрики в формате Prometheus conns таблица соединений ct (зона $CT_ZONE) trace [src_port] ofproto/trace для TCP-сессии клиент -> VIP:$VIP_PORT reload перегенерировать и применить пайплайн USAGE } api() { curl -fsS --max-time 5 "http://$HC_API$1"; } case "${1:-}" in ports) ovs-vsctl show ovs-ofctl -O "$OF" show "$BR" | grep -E '^\s+[0-9]+\(' ;; flows) if [ -n "${2:-}" ]; then ovs-ofctl -O "$OF" dump-flows "$BR" "table=$2" else ovs-ofctl -O "$OF" dump-flows "$BR" fi ;; health) api /status.txt ;; status) api /status ;; slots) echo "Раскладка по данным датапаса (счётчики правил дают per-member статистику):" ovs-ofctl -O "$OF" dump-flows "$BR" table=11 \ | sed -n 's/.*n_packets=\([0-9]*\).*set_field:\(0x[0-9a-f]*\)->reg2.*/\2 \1/p' \ | awk '{slots[$1]++; pkts[$1]+=$2} END {for (m in slots) printf " член id=%s: слотов %d, пакетов %d\n", m, slots[m], pkts[m]}' \ | sort drops=$(ovs-ofctl -O "$OF" dump-flows "$BR" table=11 | sed -n 's/.*n_packets=\([0-9]*\).*priority=0.*/\1/p') echo " отброшено правилом fail-close: ${drops:-0}" api /status.txt | sed -n '2p' ;; drain) api "/drain?member=${2:?укажите имя члена}" ;; enable) api "/enable?member=${2:?укажите имя члена}" ;; metrics) api /metrics ;; conns) ovs-appctl dpctl/dump-conntrack | grep -F "zone=$CT_ZONE" || echo "соединений нет" ;; trace) src_ip="${2:?укажите IP клиента}" src_port="${3:-40000}" ovs-appctl ofproto/trace "$BR" \ "in_port=$PUB_OFPORT,dl_src=00:11:22:33:44:55,dl_dst=$PUB_MAC,dl_type=0x0800,nw_src=$src_ip,nw_dst=$VIP,nw_proto=6,nw_ttl=64,tp_src=$src_port,tp_dst=$VIP_PORT,tcp_flags=syn" ;; reload) "$LB_DIR/apply.sh" ;; *) usage ;; esac