feat(cluster): corosync ring1 pe insula, test de repornire cu WoL, fixuri in scripturi
Ring1 aplicat si verificat pe cluster live: config_version 17, ring1_addr pe
10.10.10.20x la fiecare nod, interface{linknumber:1}. Validat cu `corosync -t`
inainte de instalare. Testat prin oprirea reala a lui ring0 pe pveelite: link0
disconnected, link1 connected, cvorum 3/3 neatins - exact scenariul care pe
27 august a lasat nodul mort 16 ore.
Test de repornire completa a clusterului, cu Wake-on-LAN (trezire in ~15s).
Insula a urcat singura pe toate trei nodurile; ipoteza enumerarii tarzii a
USB-ului nu s-a materializat. Unealta noua: wake-cluster.ps1.
Testul a scos la iveala o linie ramasa in /etc/fstab pe pve1 si pveelite, care
monta storage-ul NFS de pe IP-ul de productie inaintea lui pvestatd. Backup-ul
trecea tacut pe reteaua gresita, cu storage.cfg corect. cluster-startup verifica
acum asta automat, impreuna cu IP-urile de insula si conectivitatea reala.
Patru bug-uri gasite prin rulare pe cluster live:
- sonda Oracle nu avea timeout: un sqlplus agatat pe o instanta in pornire a
blocat cluster-startup 14 minute, fara mesaj, cu propriul prag de 600s
nefolosit, fiindca bucla n-a apucat o iteratie;
- `bash -c` in loc de `bash -lc`: sqlplus lipsea din PATH, deci baza nu se
oprea si containerul s-ar fi inchis peste ea;
- PowerShell 5.1 pierde ghilimelele duble catre exe-uri native, deci comanda
ajungea rupta pe nod - trecut pe trimitere codificata base64;
- backup-ul de crontab si fisierul de stare se rescriau la o a doua rulare,
lasand monitorizarea oprita permanent si lista de repornit goala.
Documentatia de oprire planificata pornea de la o afirmatie devenita falsa
("nu exista datacenter.cfg") si de la o comanda care ar fi adaugat o a doua
linie `ha:`. Actualizata, impreuna cu inventarul de guest-uri (VM 304 lipsea
din toate listele de ordine si cadea in maturarea de dupa Oracle).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RJFQZcA7uerXRaL1NrsXpS
This commit is contained in:
@@ -46,6 +46,7 @@ GUEST_START_ORDER=(
|
||||
101 # minecraft
|
||||
110 # moltbot
|
||||
303 # Win11-Adina
|
||||
304 # Win11-Marius
|
||||
302 # oracle-test-302
|
||||
109 # oracle-dr-windows — DR, în mod normal rămâne oprit
|
||||
301 # docker-portainer-template
|
||||
@@ -59,9 +60,26 @@ GUEST_START_ORDER=(
|
||||
# 301, 310 — template-uri, nu servicii.
|
||||
NEVER_AUTOSTART=(109 301 310)
|
||||
|
||||
# Rețeaua dedicată de cluster („insula"), existentă din 2026-08-29. De ea atârnă
|
||||
# replicarea ZFS (migration: network=10.10.10.0/24 în datacenter.cfg) și storage-ul
|
||||
# NFS backup-pvemini. Pe pve1 și pveelite IP-ul stă pe dongle-ul USB, adus la boot
|
||||
# de un „auto enx..." din /etc/network/interfaces: dacă nucleul enumerează USB-ul
|
||||
# DUPĂ ce networking.service a terminat, interfața rămâne fără IP, iar nodul pare
|
||||
# perfect sănătos. Detalii: ../docs/switch-2.5g-dedicat-noduri.md
|
||||
declare -A ISLAND_IP=(
|
||||
[pve1]=10.10.10.200
|
||||
[pvemini]=10.10.10.201
|
||||
[pveelite]=10.10.10.202
|
||||
)
|
||||
ISLAND_NFS_MOUNT=/mnt/pve/backup-pvemini
|
||||
ISLAND_NFS_SERVER=10.10.10.201
|
||||
ISLAND_NFS_NODES=(pve1 pveelite)
|
||||
|
||||
ORACLE_CT=108
|
||||
ORACLE_DOCKER=oracle-xe
|
||||
ORACLE_WAIT=600 # secunde așteptate până baza răspunde la interogări
|
||||
# Măsurat pe 2026-08-29, la pornire de la rece după oprirea completă a clusterului:
|
||||
# instanța a avut nevoie de ~10 minute ca să ajungă OPEN. 600s erau prea strâmți.
|
||||
ORACLE_WAIT=1200 # secunde așteptate până baza răspunde la interogări
|
||||
|
||||
NODE_WAIT=1800 # secunde așteptate până apar toate nodurile
|
||||
QUORUM_WAIT=300
|
||||
@@ -177,7 +195,91 @@ ok "quorum OK, $VOTES/3 voturi"
|
||||
|
||||
nssh pvemini "ha-manager status | head -4"
|
||||
|
||||
# ------------------------------------------------- pas 3: ce trebuie pornit
|
||||
# ----------------------------------- pas 3: rețeaua dedicată de cluster (insula)
|
||||
|
||||
# Se verifică ÎNAINTE de pornirea guest-urilor: dacă insula e jos, replicarea și
|
||||
# backup-ul NFS tac fără nicio alertă, iar simptomul apare abia peste ore.
|
||||
# Nu blochează pornirea — la revenirea curentului, Oracle sus contează mai mult
|
||||
# decât replicarea — dar nu te lasă să treci pe lângă problemă fără să o vezi.
|
||||
|
||||
step "Verific rețeaua de cluster (10.10.10.0/24)"
|
||||
|
||||
if (( DRY_RUN )); then
|
||||
warn "dry-run — sar peste verificarea insulei"
|
||||
else
|
||||
ISLAND_BAD=()
|
||||
|
||||
for node in "${!NODE_IP[@]}"; do
|
||||
want="${ISLAND_IP[$node]}"
|
||||
have=$(nssh "$node" "ip -4 -o addr show | grep -c ' $want/' || true")
|
||||
|
||||
if [[ "$have" == "0" ]]; then
|
||||
# Cazul așteptat de eșec: dongle-ul USB enumerat târziu la boot.
|
||||
# ifreload -a aplică doar diferențele față de /etc/network/interfaces,
|
||||
# deci nu atinge interfețele tap/veth ale guest-urilor.
|
||||
warn "$node — lipsește $want, încerc 'ifreload -a'"
|
||||
nssh "$node" "PATH=/usr/sbin:/sbin:/usr/bin:/bin ifreload -a" || true
|
||||
sleep 8
|
||||
have=$(nssh "$node" "ip -4 -o addr show | grep -c ' $want/' || true")
|
||||
fi
|
||||
|
||||
if [[ "$have" == "0" ]]; then
|
||||
ISLAND_BAD+=("$node")
|
||||
warn "$node — TOT fără $want după ifreload"
|
||||
else
|
||||
ok "$node — $want prezent"
|
||||
fi
|
||||
done
|
||||
|
||||
# Un IP configurat local nu garantează și cablul/switch-ul. pvemini e sursa
|
||||
# replicării și serverul NFS, deci se verifică din el spre celelalte două.
|
||||
for node in pve1 pveelite; do
|
||||
ip="${ISLAND_IP[$node]}"
|
||||
if nssh pvemini "ping -c1 -W2 $ip >/dev/null 2>&1"; then
|
||||
ok "pvemini → $node ($ip) — ping OK"
|
||||
else
|
||||
printf '%s\n' "${ISLAND_BAD[@]:-}" | grep -qx "$node" || ISLAND_BAD+=("$node")
|
||||
warn "pvemini → $node ($ip) — NU răspunde (cablu? switch?)"
|
||||
fi
|
||||
done
|
||||
|
||||
NFS_BAD=()
|
||||
for node in "${ISLAND_NFS_NODES[@]}"; do
|
||||
src=$(nssh "$node" "findmnt -no SOURCE $ISLAND_NFS_MOUNT 2>/dev/null || true")
|
||||
if [[ "$src" == *"$ISLAND_NFS_SERVER"* ]]; then
|
||||
ok "$node — NFS $ISLAND_NFS_MOUNT montat de pe $ISLAND_NFS_SERVER"
|
||||
elif [[ -n "${src// /}" ]]; then
|
||||
# Prins pe 2026-08-29 la primul boot la rece: o linie rămasă în /etc/fstab
|
||||
# monta storage-ul de pe IP-ul de producție ÎNAINTE ca pvestatd să apuce,
|
||||
# deci backup-ul mergea tăcut pe rețeaua greșită, cu storage.cfg corect.
|
||||
NFS_BAD+=("$node")
|
||||
warn "$node — NFS montat de pe ALT server: $src (așteptat $ISLAND_NFS_SERVER)"
|
||||
warn " verifică: ssh root@${NODE_IP[$node]} 'grep nfs /etc/fstab'"
|
||||
else
|
||||
# pvestatd remontează singur în câteva zeci de secunde dacă rețeaua e sus.
|
||||
warn "$node — NFS $ISLAND_NFS_MOUNT NEMONTAT (pvestatd îl reia dacă insula urcă)"
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#NFS_BAD[@]} )); then
|
||||
warn "Backup-ul NFS trece pe altă rețea decât cea proiectată pe: ${NFS_BAD[*]}"
|
||||
fi
|
||||
|
||||
if (( ${#ISLAND_BAD[@]} )); then
|
||||
warn ""
|
||||
warn "INSULA E JOS pe: ${ISLAND_BAD[*]}"
|
||||
warn "Consecință: replicarea ZFS și storage-ul NFS backup-pvemini NU vor funcționa."
|
||||
warn "Guest-urile pornesc și merg normal — problema e tăcută, se vede abia în pvesr status."
|
||||
warn "Verifică: ssh root@<nod> \"ip -br a; dmesg | tail -20\" (dongle USB enumerat târziu?)"
|
||||
confirm "Continui cu pornirea guest-urilor, cu replicarea jos?"
|
||||
elif (( ${#NFS_BAD[@]} == 0 )); then
|
||||
ok "insulă completă — replicarea și NFS-ul au calea liberă"
|
||||
else
|
||||
warn "insula e sus, dar NFS-ul nu o folosește — vezi mai sus"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ------------------------------------------------- pas 4: ce trebuie pornit
|
||||
|
||||
step "Ce se pornește"
|
||||
|
||||
@@ -223,7 +325,7 @@ done <<<"$TO_START"
|
||||
|
||||
confirm "Se pornesc guest-urile de mai sus, în ordinea: ${GUEST_START_ORDER[*]}"
|
||||
|
||||
# ------------------------------------------------- pas 4: pornire guest-uri
|
||||
# ------------------------------------------------- pas 5: pornire guest-uri
|
||||
|
||||
step "Pornire guest-uri"
|
||||
|
||||
@@ -269,7 +371,16 @@ wait_oracle() {
|
||||
(( DRY_RUN )) && return 0
|
||||
local waited=0
|
||||
while (( waited < ORACLE_WAIT )); do
|
||||
if nssh "$node" "pct exec $ORACLE_CT -- docker exec $ORACLE_DOCKER bash -c \"printf 'set pagesize 0 feedback off\nselect global_name from global_name;\nexit\n' | sqlplus -s / as sysdba\" 2>/dev/null | grep -q '[A-Z]'"; then
|
||||
# `bash -lc`, NU `bash -c`: fără shell de login nu există sqlplus în PATH, iar
|
||||
# așteptarea ar expira după $ORACLE_WAIT secunde chiar cu baza perfect deschisă.
|
||||
#
|
||||
# `timeout 30` e OBLIGATORIU, nu o precauție. Pe 2026-08-29, la pornirea de la
|
||||
# rece, sqlplus lansat către o instanță încă în startup s-a blocat definitiv:
|
||||
# docker exec a moștenit blocajul, ssh a așteptat, iar bucla n-a apucat să
|
||||
# facă nici măcar o iterație. Scriptul a stat agățat 14 minute fără niciun
|
||||
# mesaj, cu propriul prag de așteptare nefolosit. Sonda trebuie să răspundă
|
||||
# mereu, fie și cu eșec.
|
||||
if nssh "$node" "timeout 30 pct exec $ORACLE_CT -- docker exec $ORACLE_DOCKER bash -lc \"printf 'set pagesize 0 feedback off\nselect status from v\\\$instance;\nexit\n' | sqlplus -s / as sysdba\" 2>/dev/null | grep -q OPEN"; then
|
||||
ok "Oracle deschis și interogabil (${waited}s)"
|
||||
return 0
|
||||
fi
|
||||
@@ -305,7 +416,7 @@ while read -r type node id status ha; do
|
||||
start_guest "$type" "$node" "$id" "$ha" || FAILED+=("$type:$id")
|
||||
done <<<"$TO_START"
|
||||
|
||||
# ------------------------------------------------ pas 5: restaurare cron-uri
|
||||
# ------------------------------------------------ pas 6: restaurare cron-uri
|
||||
|
||||
step "Restaurare cron-uri de monitorizare"
|
||||
|
||||
@@ -325,7 +436,7 @@ for node in "${!NODE_IP[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# ------------------------------------------------------- pas 6: verificare
|
||||
# ------------------------------------------------------- pas 7: verificare
|
||||
|
||||
step "Verificare finală"
|
||||
|
||||
@@ -354,7 +465,10 @@ fi
|
||||
cat <<EOF
|
||||
|
||||
De verificat manual:
|
||||
- shutdown_policy e încă 'freeze' (recomandat să rămână așa)
|
||||
- datacenter.cfg are încă AMBELE linii: 'ha: shutdown_policy=freeze'
|
||||
și 'migration: network=10.10.10.0/24,type=insecure'
|
||||
- dacă lipsesc date recente, compară cu ultima replicare din pvesr status
|
||||
- dacă a fost prima repornire după 2026-08-29: notează în
|
||||
docs/switch-2.5g-dedicat-noduri.md dacă insula a urcat singură la boot
|
||||
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user