Hasznos parancsok

Azok az ellenőrzések, amiket egy üzemeltető a leggyakrabban futtat, bemásolható egysorosokként: a verzió és az öndiagnosztika egy brókeren, ugyanez az egész flottán, egy célgép feloldott zárolási szintje, melyik bróker tartja éppen a közös címet, a gyűjtött break-glass napló és a forgatása, az Ansible-audit futás, és a break-glass drill. Utánuk a vezérlőről vezérelt műveletek: egy jóváhagyási kérés döntése, a szolgáltatások az infrastruktúra-gépeken, az ütemezett feladatok, a gördülő frissítés, egy konfiguráció-kiosztás, a tár mentése a visszaállítási drillel, és a csomagolt komponensek verziói. A Web Access-nek saját blokkja van: a rendszer-ellenőrzés sorai, az alkalmazás-munkamenetek és a zárak. Ahol segít tudni, mit kell keresni, egy szakasz ugyanezekkel a helyőrzőkkel kimenet-mintát is mutat.

Ezen a lapon minden blokk környezet-független. A <broker>, <target>, <vip name>, <admin user>, <admin key> és <break-glass key> ennek a telepítésnek a saját neveinek a helyőrzői, az <env> és a <config source> pedig az Ansible-környezetet és a vezérlőn álló konfiguráció-forrás könyvtárát nevezi meg. Mivel az egysorosok ezeket a helyőrzőket hordozzák, nincsenek a forrásfához mérve — ellentétben a portál prózájában álló kód-spanokkal: egy referencia-környezetben mért futások, a nevek kivéve belőlük. Amit egy szakasz arról mond, mit mutat egy parancs, az egy ilyen futásból jön.

Azoknak a parancsoknak, amik a gyűjtött naplót, a forgatás konfigurációját vagy egy jóváhagyási rekordot olvassák, sudo kell a brókeren. A break-glass drillig ezen a lapon semmi nem változtat állapotot, és maga a drill is csak egy valódi belépés. Az utána következő szakaszok szándékosan állapotot változtatnak: frissítés, kiosztás, mentés — mindegyik kimondja, mihez nyúl.

A verzió és az öndiagnosztika egy brókeren

Magán a brókeren fut. Az isg system check ellenőrzésenként egy sort ír ki, elöl az állapot-jelölővel, így a második sor csak azokat a sorokat hagyja meg, amik figyelmet kérnek, a harmadik pedig csak az identitásról, a konfigurációról, a CMDB-ről és a break-glassról szólókat.

isg --version | head -1
isg system check 2>&1 | grep -E '^\[(WARN|FAIL)\]'
isg system check 2>&1 | grep -E '^\[[A-Z ]+\] (ldap\.yaml|LDAP bind|Config key|cmdb\.yaml|Broker version skew|Break-glass)'

Ugyanez minden brókeren

Brókerenként egy ssh az admin-kulccsal, így egy egész flotta egy képernyőn válaszol. Ez az az alak, ami a referencia-környezetben megmutatta a két bróker közötti verzió-eltérést: a sorok egymás mellett állnak, és az az egy olvasandó, amelyik eltér.

for h in <broker> <broker>; do ssh -i <admin key> <admin user>@$h 'isg --version | head -1; isg system check 2>&1 | grep -E "^\[[A-Z ]+\] (cmdb\.yaml|Broker version skew)"'; done

A célgépek zárolási szintje

Az isg servers level szándékosan egyszerre egy gépre válaszol — egy valódi CMDB-konnektornak nincs felajánlható géplistája —, ezért egy ciklus az, ahogy egy teljes inventory kiolvasható. A sor megnevezi a szintet és azt is, honnan jött, és ez utóbbi az igazán olvasandó rész: a gyorsítótárból és a CMDB-ből kiszolgált szint egyébként egyformán néz ki.

for t in <target> <target>; do isg servers level $t 2>/dev/null; done

Melyik bróker tartja a közös címet

Egy keepalived-páron egyszerre pontosan egy bróker viszi a közös címet. Minden más olvasásához számít: azon a brókeren át kapcsolódnak valójában az operátorok, és a gördülő frissítés ezt veszi utoljára. A címet a vezérlő a nevéből oldja fel, és minden bróker a saját hostnevével és egy sima igennel vagy nemmel válaszol.

vip=$(getent hosts <vip name> | awk '{print $1}')
for h in <broker> <broker>; do ssh -i <admin key> <admin user>@$h "hostname; ip -br a | grep -qw $vip && echo 'VIP (<vip name>): yes' || echo 'VIP (<vip name>): no'"; done
<broker-1>
VIP (<vip name>): yes
<broker-2>
VIP (<vip name>): no

A gyűjtött break-glass napló

Minden break-glass belépés és minden továbbított parancs-rekord a /var/log/isg-breakglass-remote.log fájlba érkezik, brókerenként. Sorrendben: a sorok száma; a naponkénti, küldő gépenkénti bontás, ami a syslog-sorból a hónapot, a napot és a gépet olvassa ki; a break-glass sorok maguk, ugyanazzal a mintával számolva, amit a továbbító szűrő átenged; az utolsó bejegyzések; az utolsó sikeres break-glass belépések; és a továbbított parancs-audit (type=EXECVE).

sudo wc -l /var/log/isg-breakglass-remote.log
sudo awk '{print $1, $2, $4}' /var/log/isg-breakglass-remote.log | sort | uniq -c
sudo grep -c -E 'isg-breakglass|isg-bg:|type=EXECVE' /var/log/isg-breakglass-remote.log
sudo tail -5 /var/log/isg-breakglass-remote.log
sudo grep -E '(Accepted|Failed) [a-z]+ for isg-breakglass' /var/log/isg-breakglass-remote.log | tail -3
sudo grep 'type=EXECVE' /var/log/isg-breakglass-remote.log | tail -5

Egy belépés-sor magától megkülönbözteti a két break-glass réteget: a tanúsítvány-út ED25519-CERT alakban jelenik meg, a tanúsítvány saját ID mezőjével, a végső mentsvár statikus kulcs pedig egyik nélkül sem.

A napló forgatásának száraz próbája

A gyűjtött napló forgatása méret alapú, nem napi, ezért a „forgat-e ma éjjel" kérdésre a száraz próba a válasz, nem egy dátum. Közben be is tölti a konfigurációt, ami a kérdés másik fele.

sudo logrotate -d /etc/logrotate.d/isg-breakglass-remote

Az Ansible-audit futás és a deprecation-figyelmeztetései

A verify.yml semmit nem változtat — állít, gépenként —, és egy tiszta futás mindenhol changed=0 értékkel zárul. A DEPRECATION WARNING sorokat külön kell számolni, mert egy deprecation nem bukás, és sosem jut el az összesítőig.

ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> playbooks/verify.yml 2>&1 | tee /tmp/verify.out | tail -15
grep -c 'DEPRECATION WARNING' /tmp/verify.out

Break-glass drill egy célgépre

A drill egy valódi belépés a vészkijáraton, az átjáró teljes megkerülésével: a kulcs a célgép isg-breakglass fiókjának ajánlódik fel, a sudo -n true pedig megmutatja, hogy a fiók továbbra is eléri a rootot jelszó nélkül. Egyúttal otthagyja azt a nyomot is, amit az átjáró mér — az isg system check drill-nyom sora csak akkor tér vissza OK-ra, ha mindkét break-glass rétegnek van friss belépése, tehát a csak statikus kulcsos drill a sort WARN-on hagyja.

ssh -i <break-glass key> -o IdentitiesOnly=yes isg-breakglass@<target> 'id -un; sudo -n true && echo SUDO-OK'

Egy jóváhagyási kérés döntése

Ha egy parancs négyszem-jóváhagyásra vár, a munkamenet kiírja a kérés azonosítóját a request= után. Hogy ki döntött, mikor és milyen indokkal, az a kéréssel együtt tárolódik. Kiolvasni a szolgáltatás- fiókkal lehet, mert a rekord-tár hozzáférési adatait csak az olvashatja. A webUI-n hozott döntést az indok ki is mondja.

sudo setpriv --reuid=isg --regid=isg-operators --clear-groups /usr/local/bin/isg approvals show <approval-id>
State:             approved
Requested at:      <time>
Decided by:        <approver>
Decided at:        <time>
Decision reason:   <reason> (via admin UI)

Web Access: a sorok, az alkalmazás-munkamenetek és a zárak

Egy brókeren futtatandó. Az első sor a rendszer-ellenőrzés három Web Access-sorát tartja meg — a fájl betölt, a közös fiókok titkai olvashatók, a listener figyel és a tanúsítványa minden alkalmazást lefed. A második az alkalmazás-munkameneteket listázza (http protokoll); a rekord-tár olvasásához root kell, mint a fenti jóváhagyási rekordhoz. A harmadik a zárakat mutatja, felhasználókét és alkalmazásokét egyaránt.

isg system check 2>&1 | grep -E '^\[[A-Z ]+\] (apps\.yaml|Web Access)'
sudo env ISG_HOME=/var/lib/isg /usr/local/bin/isg sessions list | grep '(http)'
isg lock list
[OK  ] apps.yaml                    <n> app(s): <app id> <name>→<host> …
[OK  ] Web Access credentials       <n> account(s) readable
[OK  ] Web Access listener          listening on [::]:<port>; certificate covers <n> name(s) …

Egy futó alkalmazás-munkamenet transcriptje, amíg a munkamenet nyitva van, a kiszolgáló brókeren van, kérésenként egy JSON-sor (a command a metódus és az útvonal, az exit_code a státusz, amit a konzol válaszolt):

sudo tail -n 5 /var/lib/isg/transcript-<session-id>.jsonl

A szolgáltatások a tár-, a címtár- és a monitoring-gépen

A megosztott tár, a címtár és a monitoring rootless konténerként fut, gépenként egy nem privilegizált fiók alatt, és minden konténer mögött egy systemd --user unit áll. Gépenként egy ssh mindkét nézetet listázza: a konténert a futási idejével, és a unitot az állapotával.

for h in <store host> <directory host> <monitoring host>; do ssh -i <admin key> <admin user>@$h 'hostname; podman ps --format "{{.Names}}  {{.Status}}"; systemctl --user list-units --type=service --no-legend "isg-*" | awk "{print \$1, \$3, \$4}"'; done
<store host>
isg-postgres  Up <uptime>
isg-bao  Up <uptime>
isg-rustfs  Up <uptime>
isg-postgres.service active running
…

Az ütemezett feladatok a vezérlőn

Az éjszakai tár-mentés, a legfrissebb mentés korának napi mérése (09:00) és a havi upstream-mérés systemd --user timerből fut a vezérlőn, nem a flottán. A lista a következő és az utolsó futást mutatja; a kézi futás ugyanaz a unit, amit a timer indít, tehát pontosan azt méri, amit az ütemezés tenni fog.

systemctl --user list-timers --no-pager 'isg-*'
systemctl --user start isg-upstream-<env>.service; systemctl --user status isg-upstream-<env>.service --no-pager | tail -n 15

Egy sikeresen lefutott oneshot unit inactive (dead) és status=0/SUCCESS.

A mentés-kor mérése a vezérlőn közvetlenül a repóból is futtatható. Piros, ha a legfrissebb archívum 26 óránál régebbi, vagy nincs; -e isg_backup_age_notify=true nélkül levelet nem küld.

ansible-playbook -e isg_env=<env> playbooks/backup-age.yml

A gördülő frissítés, brókerenként

Futó flottán a binárist az upgrade-rolling.yml cseréli, futásonként egy brókeren, az újraindítás előtt drainnel és utána méréssel — nem a site.yml, ami minden brókert egyszerre indítana újra. Előbb az a bróker megy, amelyik NEM tartja a közös címet. A bináris a kiadás tagjéből épített, rögzített másolat; ha a verziója nem egyezik a repóéval, a play még a telepítés előtt megáll.

ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> -e isg_binary_src=<binary copy> playbooks/upgrade-rolling.yml --limit <broker without the shared address>,<store host>
ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> -e isg_binary_src=<binary copy> playbooks/upgrade-rolling.yml --limit <broker with the shared address>,<store host>

Minden futás végén az összefoglaló az, amit olvasni kell:

- 'broker B1 (<broker>): <old version> → <new version> (installed before: <old version>; …
- 'fleet compatibility (B401): 1 → 1; …
- 'drain wait: 1 s, 1 poll(s); sessions at drain on: 0'
- 'post-check: isg system check rc=0 (after 1 attempt(s)); [OK  ] Broker version skew …

A második bróker után az audit-futás (verify.yml, fent) zárja a frissítést.

Egy konfiguráció-változás kiosztása

A repóban a konfiguráció-forrásban tett változás két lépésben ér a gépekre: előbb a vezérlőn álló konfiguráció-forrás újragenerálódik a repóból, utána fut a gépek role-ja. Ugyanannak a parancsnak a második futása az ellenőrzés, hogy az első végigért: changed=0-val zárul.

ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> playbooks/config-src.yml
ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> -l <group> playbooks/site.yml

A <group> annak a gépcsoportnak az inventory-neve, amelyikhez a változás tartozik. A brókerekhez tartozó változás ugyanazért a gördülő frissítésen át megy (előző szakasz), amiért a bináris is.

A tár mentése és a visszaállítási drill

A mentés a rekord-tárat, a titok-tárat és az objektum-tárat egy archívumba viszi a vezérlőre; a drill a legfrissebb archívumot eldobható konténerekbe állítja vissza az élők mellett, és méri a visszaállítási időket, az élő tárhoz nem nyúlva.

ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> playbooks/backup.yml
ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_config_src_dir=<config source> playbooks/backup-restore-drill.yml

A drill összefoglalója tárolónként egy visszaállítási időt (RTO) és az összevetett sor-számokat adja.

A csomagolt komponensek verziói

Minden harmadik féltől származó komponens telepített verzióját a gépekről olvassa ki; a legfrissebb stabil upstream verziót egyedül a vezérlő kérdezi le — a gépek nem hívnak ki. Egy behind komponens tervezendő lelet, nem bukás.

ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_cv_report_dir=<report directory> playbooks/component-versions.yml
ansible-playbook -i inventory/<env>.ini -e isg_env=<env> -e isg_cv_report_dir=<report directory> playbooks/component-upstream.yml
B429 UPSTREAM — 9 komponens; current 8, behind 0, not_measured 1