Files
ROMFASTSQL/proxmox/cluster/docs/oprire-planificata-cluster.md
Marius 730ce94fac feat(cluster): varianta PowerShell a scripturilor de oprire/repornire
Statia de admin e Windows si nu ruleaza .sh direct: `bash` din PATH e cel din
WSL, cu alt filesystem si alta configuratie de chei SSH. Adaug echivalentele
native PowerShell.

- cluster-shutdown.ps1 / cluster-startup.ps1, aceeasi logica si aceleasi
  garantii ca variantele bash
- folosesc clientul OpenSSH din Windows, deja prezent in System32
- compatibile PowerShell 5.1: fara &&/||, fara ternar, fara ?., fara
  -AsHashtable; ping prin System.Net.NetworkInformation.Ping, nu
  Test-Connection (WMI, lent si des blocat)
- nu redirecteaza stderr-ul lui ssh: in 5.1 asta transforma fiecare linie
  intr-un ErrorRecord si strica $LASTEXITCODE chiar cand comanda a reusit
- parsarea `pct list` / `qm list` se face in PowerShell, nu prin awk remote,
  ca sa nu se incurce interpolarea $1/$2 din stringurile PowerShell
- scriu acelasi format de fisier de stare ca variantele bash, deci poti opri
  cu una si porni cu cealalta

Ambele testate cu -DryRun pe clusterul live, rezultat identic cu bash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RRyaDj39hPQ89SZS6URRpS
2026-08-27 14:04:50 +03:00

13 KiB

Oprire planificată a clusterului (lucrări la rețeaua electrică)

Procedura de oprire controlată a tuturor celor 3 noduri Proxmox fără ca HA să relocheze resursele și fără ca watchdog-ul să reseteze hard vreun nod.

Se aplică oricărei opriri planificate a întregului cluster: lucrări electrice, mutare rack, mentenanță UPS, intervenții la switch.

Autor: Claude Code · Ultima verificare pe cluster live: 2026-08-27


Varianta automată

Toată procedura de mai jos e implementată în două scripturi, de rulat de pe stația de admin (nu de pe un nod). Există în două variante echivalente — folosește-o pe cea potrivită shell-ului tău.

PowerShell (Windows, varianta obișnuită aici):

cd E:\proiecte\ROMFASTSQL\proxmox\cluster\scripts

.\cluster-shutdown.ps1 -DryRun     # arată exact ce ar face, nu atinge nimic
.\cluster-shutdown.ps1             # oprire completă, cu confirmări

# ... după revenirea curentului, cu nodurile pornite fizic ...

.\cluster-startup.ps1              # repornire completă

Cere doar clientul OpenSSH din Windows (C:\Windows\System32\OpenSSH\ssh.exe), deja prezent, și cheia SSH pentru root pe noduri. Testate pe PowerShell 5.1.

Dacă politica de execuție blochează scriptul: powershell -ExecutionPolicy Bypass -File .\cluster-shutdown.ps1 -DryRun

Bash (Git Bash, WSL sau de pe CT 171 claude-agent):

cd proxmox/cluster/scripts
./cluster-shutdown.sh --dry-run
./cluster-shutdown.sh
./cluster-startup.sh

Cele două variante scriu același fișier de stare, deci poți opri cu una și porni cu cealaltă.

cluster-shutdown.sh salvează local ce guest-uri rulau, iar cluster-startup.sh pornește exact ce era pornit — nu repornește VM-uri oprite intenționat.

Rulează întâi cu --dry-run. Restul documentului explică de ce fiecare pas e necesar și cum se face manual din GUI, dacă preferi.


TL;DR (procedura manuală)

  1. Datacenter → Options → HA Settings → Shutdown Policy = Freeze ← fără asta, HA mută resursele
  2. Dezactivează cron-urile de alertă (pvemini-down-alert, vm109-watchdog, pveelite-down-alert, oom-alert)
  3. Oprește guest-urile manual — Oracle CT 108 primul, cu shutdown immediate în DB
  4. ha-manager status → toate serviciile trebuie să fie stopped
  5. Oprește nodurile: pveelite → pve1 → pvemini

La revenire: pornești toate trei nodurile aproape simultan (altfel nu ai quorum).


De ce nu poți pur și simplu să apeși „Shutdown"

Capcana 1 — politica implicită de shutdown este conditional

Pe clusterul romfast nu există /etc/pve/datacenter.cfg, deci PVE folosește default-ul shutdown_policy=conditional:

Acțiune pe nod Comportament HA cu conditional
Reboot freeze — serviciile rămân pe nod
Shutdown (poweroff) failover — serviciile se relochează pe alt nod

Adică exact ce vrei să eviți: un „Shutdown" pe pvemini trimite CT 108 Oracle, VM 201 și restul resurselor HA pe pve1/pveelite — pe noduri care oricum urmează să fie și ele oprite, cu 16 GB RAM pe pveelite și riscul din incidentul 2026-04-20.

Capcana 2 — watchdog-ul se auto-fence la pierderea quorumului

Cu 3 noduri, quorum = 2. Dacă oprești două noduri și al treilea încă are servicii HA active, LRM-ul pierde agent lock-ul și watchdog-ul face reset hard după ~60 s. Nu shutdown curat — reset brutal, peste Oracle pornit.

Soluția e la Pasul 3: cu toate resursele HA în state stopped, LRM-ul nu mai are nimic activ, watchdog-ul nu mai e armat, iar pierderea quorumului devine inofensivă.

Ce să NU faci

  • ❌ Nu folosi node maintenance mode (ha-manager crm-command node-maintenance enable <nod>) — acela migrează intenționat resursele, exact opusul scopului.
  • ❌ Nu opri două noduri și nu lăsa unul pornit cu servicii HA active — vezi capcana 2.
  • ❌ Nu lăsa nodul să oprească el guest-urile — Oracle și Windows au nevoie de shutdown curat, nu de timeout.

Pas 0 — Shutdown Policy = Freeze

GUI: Datacenter → Options → HA Settings → Edit → Shutdown Policy: Freeze

CLI (echivalent):

ssh root@10.0.20.201 "echo 'ha: shutdown_policy=freeze' >> /etc/pve/datacenter.cfg"

Freeze = la oprirea nodului serviciile HA sunt înghețate, nu relocate; repornesc pe același nod când nodul revine.

Recomandare permanentă: lasă freeze și după intervenție. Docul de failover descrie deja un incident în care VM 201 a migrat nedorit în timpul unei mentenanțe — freeze e politica potrivită pentru acest cluster.


Pas 1 — dezactivează alertele automate

Altfel primești zeci de mailuri, iar vm109-watchdog.sh conține un qm start 109 care poate porni VM 109 fix când nu trebuie.

Ce trebuie dezactivat pe fiecare nod:

Nod Script De ce
pveelite pvemini-down-alert.sh mail la fiecare minut cât pvemini e jos
pveelite vm109-watchdog.sh conține qm start 109
pveelite oom-alert.sh zgomot
pvemini vm109-watchdog.sh rulează și aici, nu doar pe pveelite
pvemini pveelite-down-alert.sh zgomot
pvemini oom-alert.sh zgomot
pve1 oom-alert.sh zgomot

Comandă unică, rulată pe fiecare nod — face backup și comentează exact liniile astea, lăsând restul crontab-ului neatins:

for h in 10.0.20.200 10.0.20.201 10.0.20.202; do
  ssh root@$h 'crontab -l > /root/crontab.backup-mentenanta.txt; \
    crontab -l | sed -E "/^[^#]/ s%^(.*(oom-alert|pvemini-down-alert|pveelite-down-alert|vm109-watchdog)\.sh.*)$%#MENTENANTA \1%" | crontab -'
done

Restaurare după intervenție:

for h in 10.0.20.200 10.0.20.201 10.0.20.202; do
  ssh root@$h 'crontab /root/crontab.backup-mentenanta.txt && crontab -l | grep -c MENTENANTA'
done   # trebuie sa intoarca 0 pe fiecare nod

pvemini-down-alert.sh doar trimite mail cu comanda de failover, nu o execută singur — verificat în cod. vm109-watchdog.sh însă chiar pornește VM 109, și rulează pe ambele noduri (pvemini și pveelite).

⚠️ Dacă fereastra de lucrări prinde sâmbătă dimineața

weekly-dr-test-proxmox.sh rulează sâmbătă la 06:00, pe pvemini ȘI pe pveelite, și pornește VM 109. Conform incidentului 2026-04-20, scriptul are istoric de a lăsa VM 109 pornit după un eșec (bug set -e) — exact declanșatorul buclei OOM de atunci.

Dacă intervenția atinge sâmbătă 06:00, comentează-l pe ambele noduri. La fel vm109-patch-window.sh (zilele 1-7 ale lunii, ora 03:00) dacă fereastra prinde începutul de lună.

Job-uri de backup

Verifică dacă fereastra de lucrări prinde un job vzdump. Dacă da, dezactivează-l din Datacenter → Backup înainte:

Job Program
backup-impare-oracle (CT 108) zile impare 02:00
backup-impare-rest (100, 103, 106, 171) zile impare 03:00
backup-pare-flowise (CT 104) zile pare 02:00
backup-pare-windows (VM 201) zile pare 03:30
backup-pve1-minecraft (CT 101) zile impare 22:00
backup-f1c87584 (VM 109) sâmbătă 15:00, prima săptămână

Replicarea ZFS (pvesr) nu trebuie dezactivată — job-urile ratate se recuperează singure la primul tick după revenire.


Pas 2 — oprește guest-urile manual

Ordinea corectă e cea de dependențe: consumatorii întâi, Oracle ULTIMUL. VM 201 (IIS) și CT 104 (flowise) folosesc baza din CT 108.

# Nod Guest În HA Cum
1 pvemini VM 303 Win11-Adina Nu Shutdown
2 pvemini VM 302 oracle-test Nu Shutdown
3 pvemini VM 201 roacentral Da Shutdown (guest agent)
4 pve1 CT 101 minecraft Da Shutdown
5 pve1 CT 110 moltbot Da Shutdown
6 pvemini CT 104 flowise Da Shutdown
7 pvemini CT 106 gitea Da Shutdown
8 pvemini CT 103 dokploy Da Shutdown
9 pvemini CT 102 docker.romfast.ro Nu Shutdown
10 pvemini CT 100 portainer Da Shutdown
11 pvemini CT 171 claude-agent Da Shutdown
12 pvemini CT 108 central-oracle Da shutdown immediate în DB, apoi Shutdown CT

pveelite nu are nimic pornit în mod normal (CT 301 și VM 109 sunt stopped).

Din CLI, folosește ha-manager set <sid> --state stopped pentru guest-urile din HA, nu pct shutdown / qm shutdown. Din linia de comandă acestea nu actualizează state-ul HA, iar CRM-ul poate reporni guest-ul în mijlocul opririi. Din GUI nu e o problemă — butonul Shutdown trece oricum prin HA.

Oracle CT 108 — shutdown curat al bazei

ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe bash -lc \
  \"printf 'shutdown immediate\nexit\n' | sqlplus -s / as sysdba\""

Abia după ce comanda întoarce Database closed / Database dismounted / ORACLE instance shut down, oprești containerul din GUI.

Restul

După ce Oracle e jos, poți folosi Bulk Actions → Bulk Shutdown pe fiecare nod.

Oprirea unui guest HA din GUI îi setează automat state-ul HA pe stopped — CRM-ul nu îl va reporni. Consecință: la revenire trebuie să le pornești tu manual (pornirea îi pune state-ul înapoi pe started).


Pas 3 — verificare obligatorie înainte de oprirea nodurilor

ssh root@10.0.20.201 "ha-manager status"

Toate liniile service ... trebuie să arate (nod, stopped).

Dacă vreuna arată started, migrate, relocate sau fence — oprește-te. Nu opri niciun nod până nu se stabilizează, altfel intri fix în scenariul de la capcana 2.

Verificare rapidă că nu a mai rămas nimic pornit:

for h in 10.0.20.200 10.0.20.201 10.0.20.202; do
  echo "=== $h ==="
  ssh root@$h "pct list; qm list"
done

Pas 4 — oprirea nodurilor

Ordine: pveelite (.202) → pve1 (.200) → pvemini (.201)

pvemini ultimul: e nodul principal și serverul NFS.

GUI: selectezi nodul în arbore → Shutdown (dreapta sus). Așteaptă ca nodul să nu mai răspundă la ping înainte de a-l opri pe următorul.


Repornirea

  1. Pornește toate trei nodurile aproximativ simultan. Un singur nod pornit nu are quorum → /etc/pve rămâne read-only → nu poți porni niciun guest și nu poți modifica nimic în GUI.

  2. Așteaptă quorum complet:

    ssh root@10.0.20.201 "pvecm status"      # Quorate: Yes, Total votes: 3
    ssh root@10.0.20.201 "ha-manager status"
    
  3. Pornește guest-urile în ordine inversă: CT 108 Oracle întâi, apoi VM 201, apoi restul. Pornirea unui guest HA îi repune state-ul pe started.

  4. Verifică Oracle:

    ssh root@10.0.20.201 "pct exec 108 -- docker exec oracle-xe bash -lc \
      \"printf 'select status from v\\\$instance;\nexit\n' | sqlplus -s / as sysdba\""
    
  5. Re-activează cron-urile dezactivate la Pasul 1 și job-urile de backup.

  6. Verifică replicarea:

    ssh root@10.0.20.201 "pvesr status"
    

    Job-urile */15 (108, 171, 201) au ratat rulări; recuperează la primul tick.

  7. Decide ce faci cu Shutdown Policy — vezi recomandarea de la Pasul 0.


Capcane de mediu

BIOS „Power On After AC Loss"

Dacă setarea e pe Power On, nodurile pornesc singure în secunda în care revine curentul — posibil eșalonat, posibil înainte să fii tu pregătit. Primul nod care pornește nu are quorum. Incidentul 2026-04-20 conține exact acest simptom („pvemini revine SINGUR — BIOS auto-power-on sau watchdog reset").

Verifică setarea înainte de intervenție sau fii lângă servere la revenirea curentului.

UPS

Dacă lucrarea implică și UPS-ul, vezi ../ups/README.md și ../ups/docs/UPS-SHUTDOWN-README.md — NUT are propria logică de shutdown orchestrat care poate intra peste procedura de aici.


Stare de referință a clusterului (2026-08-27)

Resurse HA configurate — 10 în total:

Serviciu Nod Grup Comentariu
ct:100 pvemini ha-prefer-pvemini portainer
ct:101 pve1 ha-prefer-pve1 minecraft
ct:103 pvemini ha-prefer-pvemini dokploy
ct:104 pvemini ha-prefer-pvemini flowise
ct:106 pvemini ha-prefer-pvemini gitea
ct:108 pvemini ha-prefer-pvemini central-oracle
ct:110 pve1 ha-prefer-pve1 moltbot
ct:171 pvemini ha-prefer-pvemini claude-agent
vm:109 pveelite ha-prefer-pveelite oracle-dr-windows (stopped)
vm:201 pvemini ha-prefer-pvemini roacentral

Guest-uri în afara HA: CT 102, CT 301, VM 302, VM 303, VM 310.

nofailback este 1 doar pe ha-prefer-pveelite; celelalte două grupuri au nofailback 0, deci resursele se întorc automat pe nodul preferat când acesta revine.


Referințe