Mascota HectorziN
Blogul lui HectorziN

Cum transformi un GL.iNet Flint 3 cu OpenWrt în QNetd pentru un cluster Proxmox

într-un cluster Proxmox format din două noduri există o problemă destul de cunoscută: pentru a menține quorum-ul, trebuie să evităm situațiile în care fiecare nod are exact jumătate din voturi. O soluție obișnuită este adăugarea unui QDevice, care folosește un al treilea echipament independent ce rulează QNetd pentru a acționa ca arbitru. în cazul meu, aveam deja un QDevice funcțional, dar QNetd era găzduit pe altă mașină. Voiam să elimin această dependență și să folosesc un dispozitiv care este aproape întotdeauna pornit și, în plus, este independent fizic de serverele Proxmox: routerul meu GL.iNet Flint 3 (GL-BE9300). Problema este că Flint 3 folosește OpenWrt, nu Debian, iar depozitele disponibile în firmware-ul meu nu includ corosync-qnetd. Important: acest ghid documentează exact soluția folosită în instalarea mea. OpenWrt, GL.iNet, Debian, Corosync și Proxmox evoluează, așa că este bine să verifici versiunile, căile și parametrii înainte de a-i copia ca atare.

Pe YouTube împărtășesc mai multe tutoriale, teste practice și proiecte reale de casă inteligentă. Abonează-te pe YouTube

GL.iNet Flint 3 cu OpenWrt rulând QNetd pentru un cluster Proxmox

Video asociat pe YouTube

Video

1. Mediul utilizat

în instalarea mea:

Código
Router:
GL.iNet Flint 3 / GL-BE9300
IP: 192.168.1.1
OpenWrt 23.05-SNAPSHOT
Arhitectură ARM64

Cluster:
Nume: hectormox

Nod 1:
miniproxmox
192.168.1.6

Nod 2:
zimaproxmox
192.168.1.7

Debian minimal a fost instalat în:

/opt/debian-qnetd

QNetd ascultă pe portul standard:

TCP 5403

2. Conectarea la Flint 3 prin SSH

în Windows, putem utiliza direct clientul SSH inclus în PowerShell:

ssh root@192.168.1.1

Introducem parola de administrare a routerului.

După conectare, vom vedea ceva asemănător cu:

Código
BusyBox
OpenWrt
root@GL-BE9300:~#

înainte de a instala orice, merită să aflăm ce avem de fapt la dispoziție.

3. Verificarea sistemului, arhitecturii, pachetelor și spațiului disponibil

Executăm:

bash
cat /etc/os-release
cat /etc/openwrt_release

uname -a
uname -m

command -v opkg
command -v apk

opkg print-architecture

df -h

Pe Flint-ul meu am obținut un sistem:

OpenWrt 23.05-SNAPSHOT

aarch64

și opkg ca manager de pachete.

Am verificat și ce instrumente erau disponibile:

bash
command -v ar
command -v tar
command -v gzip
command -v xz
command -v wget
command -v curl
command -v mount
command -v chroot

și, în special, dacă OpenWrt oferea deja Corosync:

bash
opkg update
opkg list | grep -Ei 'corosync|qnetd|qdevice|libnss|libqb'

în firmware-ul meu nu era disponibil corosync-qnetd.

Prin urmare, nu puteam pur și simplu să executăm:

opkg install corosync-qnetd

cum am face cu un pachet nativ pentru OpenWrt.

4. De ce să folosim un Debian minimal în OpenWrt

în loc să încerc să compilez Corosync și toate dependențele sale direct pentru OpenWrt, am ales o soluție mult mai simplă:

să creez un Debian ARM64 minimal într-un director și să rulez QNetd prin chroot.

OpenWrt rămâne sistemul de operare al routerului. Nu instalăm alt kernel, nu virtualizăm nimic și nu înlocuim firmware-ul.

Structura este pur și simplu:

Código
OpenWrt
└── /opt/debian-qnetd
    └── Debian 12 ARM64
        └── corosync-qnetd

Așadar, Flint-ul continuă să funcționeze ca router OpenWrt, dar dispune de un mediu Debian mic, din care putem rula software care nu există în depozitele sale.

5. Instalarea debootstrap pe Flint

Mai întâi actualizăm indexurile:

opkg update

Instalăm debootstrap:

opkg install debootstrap

Verificăm dacă este disponibil:

bash
command -v debootstrap
debootstrap --version

și verificăm spațiul disponibil:

df -h /overlay

în cazul meu, erau liberi câțiva gigabaiți, suficienți pentru un Debian minimal.

6. Problema cu GPG și Debian Bookworm

Aici a apărut una dintre primele probleme specifice versiunii mele de OpenWrt.

debootstrap trebuie să verifice semnăturile depozitelor Debian, dar gpgv disponibil inițial pe router era prea vechi pentru unele semnături folosite de Bookworm.

Soluția a fost să instalez:

opkg install gpgv2

Putem verifica folosind:

gpgv2 --version

Avem nevoie și de cheile oficiale Debian.

Pregătim un director temporar:

bash
BASE="/tmp/qnetd-bootstrap"

mkdir -p "$BASE"
mkdir -p "$BASE/bin"

Descărcăm pachetul debian-archive-keyring corespunzător Debian Bookworm.

Este bine să verificăm versiunea actuală a pachetului atunci când urmăm acest ghid, în loc să păstrăm permanent un anumit URL.

După descărcare:

DEB="$BASE/debian-archive-keyring.deb"

și extragem conținutul:

bash
ar p "$DEB" data.tar.xz |
    xz -dc |
    tar -xf - -C "$BASE"

Cheia este disponibilă în:

bash
KEY="$BASE/usr/share/keyrings/debian-archive-keyring.gpg"
ls -l "$KEY"

Pentru a ne asigura că debootstrap utilizează gpgv2, creăm temporar un mic override:

ln -sf /usr/bin/gpgv2 "$BASE/bin/gpgv"

Acest lucru afectează doar PATH pe care îl vom utiliza la rularea debootstrap.

7. Crear Debian 12 ARM64 minbase

Stabilim unde vrem să îl instalăm:

TARGET="/opt/debian-qnetd"

Executăm:

bash
PATH="$BASE/bin:$PATH" \
debootstrap \
    --arch=arm64 \
    --variant=minbase \
    --keyring="$KEY" \
    bookworm \
    "$TARGET" \
    https://deb.debian.org/debian

Aceasta descarcă și instalează un Debian 12 minimal în:

/opt/debian-qnetd

și putem verifica conținutul:

ls -la /opt/debian-qnetd

și putem intra manual:

chroot /opt/debian-qnetd /bin/bash

Pentru a reveni la OpenWrt:

exit

8. Actualizarea Debian și instalarea QNetd

Din OpenWrt putem executa direct comenzi în interiorul chroot-ului:

chroot "$TARGET" /usr/bin/apt-get update

înainte de instalare, verificăm dacă pachetul este disponibil:

bash
chroot "$TARGET" \
    /usr/bin/apt-cache policy corosync-qnetd

în cazul meu, Debian oferea:

corosync-qnetd 3.0.3-1

Instalarea inițială a găsit câteva dependențe lipsă în mediul minbase.

Mai întâi am reparat baza de pachete cu:

bash
chroot "$TARGET" \
    /usr/bin/apt-get --no-remove -y --fix-broken install

Apoi am instalat:

bash
chroot "$TARGET" \
    /usr/bin/apt-get install -y \
    --no-install-recommends \
    corosync-qnetd \
    libnss3-tools

Printre dependențele instalate în cele din urmă de Debian s-au numărat biblioteci NSS, Perl, netbase și alte pachete necesare.

9. /proc și /dev/pts în timpul instalării

în timpul instalării au apărut câteva avertismente referitoare la /proc și /dev/pts.

Am montat temporar:

bash
mount -o bind \
    /proc \
    /opt/debian-qnetd/proc

și:

bash
mount -o bind \
    /dev/pts \
    /opt/debian-qnetd/dev/pts

Acest lucru ne-a ajutat la pregătirea Debian.

Ulterior am verificat că QNetd nu are nevoie de aceste bind mount-uri pentru a rula normal, așadar nu fac parte din serviciul final.

10. Inițializarea certificatelor QNetd

QNetd folosește o bază NSS pentru gestionarea certificatelor.

în Debian-ul nostru avem utilitarul:

corosync-qnetd-certutil

O inițializăm din OpenWrt:

bash
chroot /opt/debian-qnetd \
    /usr/bin/corosync-qnetd-certutil \
    -i

Privită din OpenWrt, baza NSS se află în:

/opt/debian-qnetd/etc/corosync/qnetd/nssdb

O putem verifica cu:

bash
ls -lah \
    /opt/debian-qnetd/etc/corosync/qnetd/nssdb

în interiorul chroot-ului, aceeași cale este:

/etc/corosync/qnetd/nssdb

CA publică se află în:

/opt/debian-qnetd/etc/corosync/qnetd/nssdb/qnetd-cacert.crt

11. Verificarea utilizatorului coroqnetd

Pachetul Debian creează un utilizator dedicat rulării QNetd.

și verificăm identificatorii:

chroot /opt/debian-qnetd id coroqnetd

în instalarea mea am obținut:

UID 100

GID 101

Acest lucru este important deoarece mai târziu voi rula QNetd cu:

--userspec=100:101

Aceste numere nu trebuie copiate fără a le verifica mai întâi.

Fiecare instalare trebuie să execute:

chroot /opt/debian-qnetd id coroqnetd

și să utilizeze valorile obținute.

Verificăm și permisiunile bazei NSS:

bash
DB="/opt/debian-qnetd/etc/corosync/qnetd/nssdb"
ls -ln "$DB"

în cazul meu, a trebuit să ajustez:

bash
chgrp 101 \
    "$DB/pwdfile.txt" \
    "$DB/pkcs11.txt"

chmod 640 \
    "$DB/pwdfile.txt" \
    "$DB/pkcs11.txt"

și în cazul meu, 101 era GID-ul specific instalării.

12. Testarea manuală a QNetd

înainte de a-l transforma într-un serviciu, este important să verificăm că daemonul pornește efectiv.

Am testat:

bash
timeout -s TERM 10 \
    chroot --userspec=100:101 \
    /opt/debian-qnetd \
    /usr/bin/corosync-qnetd \
    -f \
    -4 \
    -l 192.168.1.1 \
    -p 5403 \
    -s req

Parametrii utilizați sunt:

  • -f: rulare în foreground.
  • -4: utilizarea IPv4.
  • -l 192.168.1.1: adresa la care ascultă QNetd.
  • -p 5403: portul.
  • -s req: impunerea TLS în versiunea utilizată.

înainte de a copia opțiunile, este bine să verificăm ajutorul versiunii instalate:

bash
chroot /opt/debian-qnetd \
    /usr/bin/corosync-qnetd \
    -h

13. Problema LD_PRELOAD din OpenWrt

La rularea programelor Debian din OpenWrt au apărut avertismente legate de variabila firmware-ului LD_PRELOAD.

Pentru ca procesul din chroot să nu moștenească variabile proprii OpenWrt, am ajuns să îl rulez într-un mediu curat:

bash
/usr/bin/env -i \
    PATH=/usr/sbin:/usr/bin:/sbin:/bin \
    ...

Acest detaliu a devenit parte a serviciului final.

14. Crearea serviciului QNetd în OpenWrt

Aceasta este una dintre cele mai importante diferențe față de un Debian obișnuit.

în Debian am utiliza systemd.

în OpenWrt utilizăm procd și scripturi în:

/etc/init.d/

Creăm fișierul:

bash
cat > /etc/init.d/qnetd-debian <<'EOF'
#!/bin/sh /etc/rc.common

USE_PROCD=1
START=98
STOP=10

start_service() {
    procd_open_instance

    procd_set_param command \
        /usr/bin/env -i \
        PATH=/usr/sbin:/usr/bin:/sbin:/bin \
        /usr/sbin/chroot --userspec=100:101 \
        /opt/debian-qnetd \
        /usr/bin/corosync-qnetd \
        -f -4 -l 192.168.1.1 -p 5403 -s req

    procd_set_param respawn 3600 5 5
    procd_set_param stdout 1
    procd_set_param stderr 1

    procd_close_instance
}
EOF

Setăm permisiunile:

chmod 755 /etc/init.d/qnetd-debian

Activăm pornirea automată:

/etc/init.d/qnetd-debian enable

Putem verifica legăturile create:

ls -l /etc/rc.d/*qnetd*

Pe Flint-ul meu au rămas:

/etc/rc.d/S98qnetd-debian

/etc/rc.d/K10qnetd-debian

Pornim serviciul:

/etc/init.d/qnetd-debian start

15. Verificarea funcționării QNetd

Mai întâi căutăm procesul:

pidof corosync-qnetd

Apoi verificăm portul:

netstat -lntp 2>/dev/null | grep 5403

Ar trebui să vedem:

192.168.1.1:5403 LISTEN

Putem verifica și procesul complet:

ps w | grep '[c]orosync-qnetd'

și interogăm direct procd:

bash
ubus call service list \
    '{"name":"qnetd-debian"}'

O stare corectă conține:

"running": true

în cazul meu se putea vedea și:

Código
/usr/bin/corosync-qnetd
-f
-4
-l 192.168.1.1
-p 5403
-s req

16. Verificarea repornirii automate a procesului

Serviciul include:

procd_set_param respawn 3600 5 5

Astfel, procd poate reporni QNetd dacă procesul se încheie neașteptat.

în timpul testelor am oprit procesul manual și am verificat că reapărea cu alt PID și asculta din nou pe:

192.168.1.1:5403

17. Pregătirea Proxmox

Trecem acum la primul nod al clusterului:

ssh root@192.168.1.6

Verificăm starea actuală:

pvecm status

și:

corosync-qdevice-tool -s

Clusterul meu se numește:

hectormox

Anterior, un alt QNetd era la:

192.168.1.5:5403

Noul QNetd va fi la:

192.168.1.1:5403

18. Crearea unei copii de rezervă înainte de modificarea QDevice

înainte de a modifica certificatele, am salvat:

/etc/corosync/qdevice

/etc/pve/corosync.conf

De exemplu:

bash
BACKUP="/root/qdevice-backup-$(hostname)-$(date +%Y%m%d-%H%M%S).tar.gz"

tar -czf "$BACKUP" \
    -C / \
    etc/corosync/qdevice \
    etc/pve/corosync.conf

sha256sum "$BACKUP"

ls -lh "$BACKUP"

Nu recomand să continuați fără această copie de rezervă.

19. Crearea unei baze NSS noi pe Proxmox

Pe miniproxmox:

bash
DIR="/root/qnetd-migration"
DB="$DIR/nssdb-new"
PASS="$DIR/pwdfile-new.txt"

mkdir -p "$DIR"
mkdir -m 700 "$DB"

: > "$PASS"
chmod 600 "$PASS"

Inicializamos NSS:

certutil -N \
    -d "sql:$DB" \
    -f "$PASS"

20. Copierea CA de pe Flint pe Proxmox

De pe miniproxmox:

bash
scp \
    root@192.168.1.1:/opt/debian-qnetd/etc/corosync/qnetd/nssdb/qnetd-cacert.crt \
    /root/qnetd-migration/qnetd-cacert.crt

Importăm CA:

bash
certutil -A \
    -d "sql:$DB" \
    -n "QNet CA" \
    -t "CT,c,c" \
    -i "$DIR/qnetd-cacert.crt" \
    -f "$PASS"

Verificăm:

bash
certutil -L \
    -d "sql:$DB" \
    -f "$PASS"

Ar trebui să vedem:

QNet CA CT,c,c

21. Crearea CSR-ului clusterului

Generăm puțină entropie:

bash
dd if=/dev/urandom \
    of="$DIR/noise-new.txt" \
    bs=1024 \
    count=1 \
    status=none

Creăm CSR-ul:

bash
CSR="$DIR/qdevice-net-node.crq"
certutil -R \
    -d "sql:$DB" \
    -f "$PASS" \
    -z "$DIR/noise-new.txt" \
    -s "CN=hectormox" \
    -g 3072 \
    -o "$CSR"

Trebuie înlocuit:

hectormox

cu numele real al clusterului.

îl putem verifica folosind:

pvecm status

22. Trimiterea CSR-ului către Flint

Din Proxmox:

bash
scp \
    "$CSR" \
    root@192.168.1.1:/opt/debian-qnetd/tmp/hectormox.crq

Ne conectăm din nou la Flint:

ssh root@192.168.1.1

și îl semnăm:

bash
chroot /opt/debian-qnetd \
    /usr/bin/corosync-qnetd-certutil \
    -s \
    -c /tmp/hectormox.crq \
    -n hectormox

Certificatul semnat se află în:

/opt/debian-qnetd/etc/corosync/qnetd/nssdb/cluster-hectormox.crt

23. Recuperarea certificatului semnat

De pe miniproxmox:

bash
scp \
    root@192.168.1.1:/opt/debian-qnetd/etc/corosync/qnetd/nssdb/cluster-hectormox.crt \
    /root/qnetd-migration/cluster-hectormox.crt

îl putem converti în PEM:

bash
cd /root/qnetd-migration

openssl x509 \
    -inform DER \
    -in cluster-hectormox.crt \
    -out cluster-hectormox.pem

și îl putem verifica:

bash
openssl verify \
    -CAfile qnetd-cacert.crt \
    cluster-hectormox.pem

Rezultatul corect este:

OK

24. Importarea certificatului clusterului

Adăugăm certificatul semnat în NSS:

bash
certutil -A \
    -d "sql:$DB" \
    -n "Cluster Cert" \
    -t "u,u,u" \
    -i "$DIR/cluster-hectormox.crt" \
    -f "$PASS"

Verificăm:

bash
certutil -L \
    -d "sql:$DB" \
    -f "$PASS"

Acum ar trebui să apară:

QNet CA CT,c,c

Cluster Cert u,u,u

25. Exportarea certificatului și a cheii private în format PKCS#12

Generăm:

bash
pk12util \
    -o "$DIR/qdevice-net-node.p12" \
    -d "sql:$DB" \
    -k "$PASS" \
    -W "" \
    -n "Cluster Cert"

Rezultatul așteptat:

PKCS12 EXPORT SUCCESSFUL

Acest fișier conține o cheie privată. Nu trebuie publicat sau partajat.

26. Pregătirea celui de-al doilea nod Proxmox

Copiem pe al doilea nod:

bash
scp \
    /root/qnetd-migration/qnetd-cacert.crt \
    root@192.168.1.7:/root/qnetd-migration/

și:

bash
scp \
    /root/qnetd-migration/qdevice-net-node.p12 \
    root@192.168.1.7:/root/qnetd-migration/

Pe zimaproxmox:

bash
DIR="/root/qnetd-migration"
DB="$DIR/nssdb-new"
PASS="$DIR/pwdfile-new.txt"
CA="$DIR/qnetd-cacert.crt"
P12="$DIR/qdevice-net-node.p12"

mkdir -m 700 "$DB"

: > "$PASS"
chmod 600 "$PASS"

certutil -N \
    -d "sql:$DB" \
    -f "$PASS"

Importăm CA:

bash
certutil -A \
    -d "sql:$DB" \
    -n "QNet CA" \
    -t "CT,c,c" \
    -i "$CA" \
    -f "$PASS"

Importăm PKCS#12:

bash
pk12util \
    -i "$P12" \
    -d "sql:$DB" \
    -k "$PASS" \
    -W ""

Rezultatul corect este:

PKCS12 IMPORT SUCCESSFUL

și verificăm:

bash
certutil -L \
    -d "sql:$DB" \
    -f "$PASS"

27. Pregătirea unei baze NSS definitive

înainte de a modifica baza utilizată efectiv de QDevice, am pregătit un alt director:

/root/qnetd-migration/nssdb-ready

Pe fiecare nod:

bash
DIR="/root/qnetd-migration"
READY="$DIR/nssdb-ready"

mkdir -m 700 "$READY"

cp -a \
    "$DIR/nssdb-new/." \
    "$READY/"

install -m 600 \
    "$DIR/pwdfile-new.txt" \
    "$READY/pwdfile.txt"

Verificăm:

bash
certutil -L \
    -d "sql:$READY" \
    -f "$READY/pwdfile.txt"

și putem verifica identitatea:

bash
certutil -L \
    -d "sql:$READY" \
    -n "Cluster Cert" \
    -a |
openssl x509 \
    -noout \
    -subject \
    -issuer

în cazul meu:

subject=CN=hectormox

issuer=CN=QNet CA

28. înlocuirea acreditărilor active

Am efectuat acest pas nod cu nod.

Oprim doar QDevice:

systemctl stop corosync-qdevice

Nu oprim Corosync.

Salvăm baza veche:

bash
ACTIVE="/etc/corosync/qdevice/net/nssdb"
BACKUP="${ACTIVE}.pre-glinet-$(date +%Y%m%d-%H%M%S)"
mv "$ACTIVE" "$BACKUP"

O copiem pe cea nouă:

bash
cp -a \
    /root/qnetd-migration/nssdb-ready \
    "$ACTIVE"

Ajustăm permisiunile:

bash
chown -R root:root "$ACTIVE"
chmod 700 "$ACTIVE"
chmod 600 "$ACTIVE"/*

Verificăm:

bash
certutil -L \
    -d "sql:$ACTIVE" \
    -f "$ACTIVE/pwdfile.txt"

și pornim QDevice:

systemctl start corosync-qdevice

Repetăm aceeași procedură pe celălalt nod.

29. Schimbarea IP-ului vechiului QNetd

în cazul meu, QDevice era deja configurat să folosească alt server:

192.168.1.5

și trebuia mutat pe Flint:

192.168.1.1

înainte, am făcut încă o copie de rezervă:

bash
cp \
    /etc/pve/corosync.conf \
    "/root/corosync-pre-glinet-$(date +%Y%m%d-%H%M%S).conf"

Modificarea a fost:

- host: 192.168.1.5

+ host: 192.168.1.1

Am mărit și:

- config_version: 3

+ config_version: 4

Blocul corespunzător a ajuns să arate astfel:

bash
quorum {
  device {
    model: net
    net {
      algorithm: ffsplit
      host: 192.168.1.1
      tls: on
    }
    votes: 1
  }
}

Reține că config_version trebuie incrementat față de valoarea existentă în fiecare instalare.

Nu copia literal 3 → 4.

30. Repornirea exclusivă a QDevice

După modificare, Corosync a preluat noua configurație, dar procesul QDevice a continuat să folosească adresa veche până când l-am repornit.

Executăm:

systemctl restart corosync-qdevice

Verificăm:

corosync-qdevice-tool -s

Rezultatul corect a fost:

Cluster name: hectormox

QNetd host: 192.168.1.1:5403

Algorithm: Fifty-Fifty split

State: Connected

Repetăm repornirea QDevice și pe al doilea nod.

31. Verificarea quorum-ului

Executăm:

pvecm status

în cazul nostru, rezultatul final a fost:

Expected votes: 3 Highest expected: 3 Total votes: 3 Quorum: 2 Quorate: Yes

Iar în informațiile despre membri:

0x00000001 1 A,V,NMW 192.168.1.6

0x00000002 1 A,V,NMW 192.168.1.7

0x00000000 1 Qdevice

Asta înseamnă:

  • miniproxmox: 1 voto.
  • zimaproxmox: 1 voto.
  • QDevice/QNetd: 1 vot.

Total:

3 voturi

Quorum-ul necesar rămâne:

2

32. Crearea unei copii complete de rezervă pentru QNetd de pe Flint

După ce am terminat totul, am făcut o copie completă de rezervă a mediului.

Definim:

bash
SERVICE="/etc/init.d/qnetd-debian"
BACKUP="/overlay/qnetd-backup-completo-$(date +%Y%m%d-%H%M%S).tar.gz"

Oprim QNetd pentru scurt timp:

"$SERVICE" stop

Creăm copia de rezervă:

bash
tar -czf "$BACKUP" \
    -C / \
    --exclude=opt/debian-qnetd/proc \
    --exclude=opt/debian-qnetd/dev/pts \
    --exclude=opt/debian-qnetd/run \
    --exclude=opt/debian-qnetd/tmp \
    opt/debian-qnetd \
    etc/init.d/qnetd-debian \
    etc/rc.d/S98qnetd-debian \
    etc/rc.d/K10qnetd-debian

Pornim din nou serviciul:

"$SERVICE" start

Verificăm integritatea:

bash
tar -tzf "$BACKUP" >/dev/null
sha256sum "$BACKUP"
ls -lh "$BACKUP"

Copia mea finală ocupa aproximativ:

157 MB

33. Descărcarea copiei de rezervă în Windows

Din PowerShell:

bash
scp -O `
    root@192.168.1.1:/overlay/qnetd-backup-completo-XXXXXXXX.tar.gz `
    "$env:USERPROFILE\Downloads\"

Apoi calculăm hash-ul:

bash
Get-FileHash `
    "$env:USERPROFILE\Downloads\qnetd-backup-completo-XXXXXXXX.tar.gz" `
    -Algorithm SHA256

Valoarea trebuie să coincidă exact cu cea obținută anterior pe Flint.

Copia de rezervă conține certificate și chei private, deci trebuie păstrată într-un loc sigur.

34. Testarea sistemului după repornirea Flint

Nu voiam să consider proiectul încheiat doar pentru că funcționa după pornirea manuală.

Am repornit Flint 3 din interfața web.

Când a redevenit disponibil, m-am conectat din nou:

ssh root@192.168.1.1

Mai întâi am verificat dacă scriptul era încă acolo:

wc -l /etc/init.d/qnetd-debian

Apoi:

pidof corosync-qnetd

Am verificat portul:

netstat -lntp 2>/dev/null | grep 5403

Y finalmente procd:

bash
ubus call service list \
    '{"name":"qnetd-debian"}'

La testul final am obținut:

23 /etc/init.d/qnetd-debian

un PID valid:

28139

portul:

192.168.1.1:5403 LISTEN

și:

"running": true

Asta demonstra că QNetd pornise automat după repornirea routerului.

35. Verificarea reconectării automate a Proxmox

Pe miniproxmox:

corosync-qdevice-tool -s

Starea a revenit automat la:

QNetd host: 192.168.1.1:5403 State: Connected

și:

pvecm status

a afișat din nou:

Expected votes: 3

Total votes: 3

Quorum: 2

Quorate: Yes

Dacă repornim Flint, nodurile Proxmox pierd temporar votul QDevice, dar când QNetd pornește din nou, QDevice se reconectează automat.

36. O problemă neobișnuită întâlnită

în timpul unuia dintre teste s-a întâmplat ceva ciudat.

Serviciul apărea ca activat:

/etc/init.d/qnetd-debian enabled

dar QNetd nu rula.

Am verificat:

pidof corosync-qnetd

Nu era returnat niciun PID.

Niciun proces nu asculta pe port:

bash
netstat -lntp 2>/dev/null |
    grep 5403

Am verificat apoi scriptul:

wc -l /etc/init.d/qnetd-debian

și am descoperit:

0 /etc/init.d/qnetd-debian

Fișierul rămăsese gol.

Cu toate acestea, existau în continuare:

/etc/rc.d/S98qnetd-debian

/etc/rc.d/K10qnetd-debian

De aceea, OpenWrt putea indica faptul că serviciul era activat, deși nu avea de fapt nimic de executat.

Am refăcut scriptul și am repetat integral testul de repornire.

De atunci, a pornit corect.

Concluzia este importantă:

Nu este suficient să verificăm dacă un serviciu este activat.

Merită să verificăm și:

bash
pidof corosync-qnetd
netstat -lntp 2>/dev/null | grep 5403
ubus call service list \ '{"name":"qnetd-debian"}'

37. Diagnostic rapid dacă QNetd nu pornește

Mai întâi verificăm dacă scriptul există și nu este gol:

bash
wc -l /etc/init.d/qnetd-debian
cat /etc/init.d/qnetd-debian

Apoi:

/etc/init.d/qnetd-debian enabled

Căutăm procesul:

pidof corosync-qnetd

Port:

bash
netstat -lntp 2>/dev/null |
    grep 5403

Starea în procd:

bash
ubus call service list \
    '{"name":"qnetd-debian"}'

Iar dacă vrem să testăm QNetd în afara procd:

bash
timeout 5 /usr/bin/env -i \
    PATH=/usr/sbin:/usr/bin:/sbin:/bin \
    /usr/sbin/chroot --userspec=100:101 \
    /opt/debian-qnetd \
    /usr/bin/corosync-qnetd \
    -f -4 \
    -l 192.168.1.1 \
    -p 5403 \
    -s req

echo "EXIT=$?"

Dacă returnează:

124

înseamnă că daemonul încă rula când timeout l-a oprit.

în acest caz, probabil avem o problemă cu serviciul procd, nu cu QNetd.

38. Diagnostic rapid din Proxmox

Mai întâi verificăm serviciile:

bash
systemctl is-active corosync
systemctl is-active corosync-qdevice

Apoi:

corosync-qdevice-tool -s

Rezultatul corect este:

State: Connected

și:

pvecm status

trebuie să afișeze:

Total votes: 3

Quorate: Yes

Dacă apare:

Cannot initialize CMAP service

nu înseamnă neapărat că QNetd are o problemă.

Mai întâi, merită să verificăm:

systemctl is-active corosync

în timpul testelor am avut exact o astfel de situație, care s-a dovedit a fi o problemă independentă de QNetd, legată de montări NFS pe gazda Proxmox.

39. Valori de adaptat la propria instalare

Nu copiați literal toate valorile din acest ghid.

Adresa Flint-ului

în cazul meu:

192.168.1.1

Nodurile Proxmox

192.168.1.6

192.168.1.7

Numele clusterului

hectormox

Verifică folosind:

pvecm status

Arhitectura

Flint-ul meu este:

ARM64

dar trebuie să verificăm folosind:

uname -m

UID și GID pentru coroqnetd

în instalarea mea:

100:101

Dar verifică folosind:

bash
chroot /opt/debian-qnetd \
    id coroqnetd

Calea Debian

Am ales:

/opt/debian-qnetd

Nu este obligatoriu.

Versiunea Debian

în acest ghid:

Debian 12 Bookworm

TLS

Versiunea mea utiliza:

-s req

Trebuie verificat cu:

bash
chroot /opt/debian-qnetd \
    /usr/bin/corosync-qnetd \
    -h

config_version

Nu copiați:

3 → 4

Trebuie să incrementăm cu unu valoarea actuală din corosync.conf.

40. Rezultatul final

După finalizarea întregului proces, Flint 3 funcționează astfel:

Código
OpenWrt
└── Debian 12 ARM64 în chroot
    └── corosync-qnetd

QNetd:

192.168.1.1:5403

TLS

procd

repornire automată

pornire automată

Iar clusterul:

Código
miniproxmox  → QDevice ─┐
                         ├──→ Flint 3 / QNetd
zimaproxmox  → QDevice ─┘

Putem verifica rezultatul final folosind:

corosync-qdevice-tool -s

este:

QNetd host: 192.168.1.1:5403

State: Connected

Iar cu:

pvecm status

obținem:

Expected votes: 3

Total votes: 3

Quorum: 2

Quorate: Yes

Partea interesantă a acestei soluții este că nu am transformat Flint 3 într-un server Debian și nu am înlocuit OpenWrt.

Flint rămâne routerul nostru OpenWrt.

Am profitat pur și simplu de un dispozitiv ARM64 mereu pornit, cu spațiu de stocare suficient și suport pentru chroot, pentru a crea un Debian minimal dedicat rulării QNetd.

Astfel putem avea un al treilea vot independent din punct de vedere fizic pentru un cluster Proxmox cu două noduri, fără să ținem pornit un alt server doar pentru a rula arbitrul.

Echipament recomandat

Dispozitiv folosit în acest proiect: GL.iNet GL-BE9300 Flint 3. Dacă ai nevoie de el, iată unde îl găsești:

Video asociat

CUPOANE ALIEXPRESS