A mellékelt komponensek frissítése
Az átjáró mellé harmadik féltől jövő komponensek is szállítunk: egy címtár, egy identity provider, egy titok-tár, egy adatbázis, egy objektum-tár, egy levélcsapda és a monitoring-pár. Mindegyik olyan konténer-image-ből fut, ami digestre van pinelve, és bármelyik frissítése ugyanaz a két lépés — írd át a pint, futtasd újra a role-t. Ami komponensenként más, az az, hogy mibe kerül az újraindítás. Ez az oldal pontosan ez a lista.
Hogyan van egy komponens pinelve
A szállított automatikában minden image-hivatkozás alakja tag@sha256:…: a tag
az olvasónak szól, a kötés a digest. Egy verziós tag maga nem köt — egy
upstream-kiadás új bájtokra mozdíthatja a tagot anélkül, hogy ebben a repóban
bármi változna —, ezért a konténer-motor a digestet húzza le. Hogy az ugyanazt
az image-et megnevező helyek egyeznek-e, maga is mért: a
make ansible-image-pin-check méri.
A pin a role saját defaultjában áll, komponensenként egy változóban:
| Komponens | Pin-változó |
|---|---|
| PostgreSQL | isg_shared_store_postgres_image |
| OpenBao | isg_shared_store_bao_image |
| RustFS (S3 objektum-tár) | isg_shared_store_rustfs_image |
| OpenLDAP | isg_directory_ldap_image |
| Keycloak | isg_directory_idp_image |
| Mailpit | isg_directory_mail_image |
| Prometheus | isg_monitoring_prom_image |
| Grafana | isg_monitoring_grafana_image |
| node_exporter | isg_monitoring_node_exporter_image |
Egy frissítés tehát: írd át a változót, futtasd a site.yml-t azzal a
--limit-tel, ami azokat a gépeket választja ki, amiken a komponens fut, és a
role handlere újraindítja a unitot. Ezekhez a komponensekhez nincs frissítő
playbook — ami van, az upgrade-rolling.yml, és az magukat az ISG-brókereket
frissíti (drain, csere, mérés, brókerenként egyenként), nem a körülöttük álló
komponenseket.
Előtte és utána: a verzióriport
Futtasd a riportot a pin átírása előtt, és még egyszer a role futása után:
ansible-playbook -i inventory/<environment>.ini -e isg_env=<environment> \
playbooks/component-versions.yml
Csak olvas. Gépenként konténerenként egy sort ír ki, három oszloppal — a pint, a TÉNYLEGESEN futó image-et (nevével és digestjével), és azt a verziót, amit a szoftver önmagáról mond —, majd komponensenként egy összesítő sort az egész flottára. Minden sor hordoz egy verdiktet:
| Verdikt | Mit jelent |
|---|---|
match |
a pin tagje a mért verzió, és a futó digest a pin digestje |
digest-match |
a pin erre a szoftverre nézve nem hordoz verzió-tagot — lebegő tag, csak digestes pin, vagy olyan image, ami a saját verzióját tageli, nem a benne csomagolt szoftverét —, tehát a digest az egyetlen állítás, a verzió pedig tájékoztatásként van kiírva |
mismatch |
a futó digest nem a pin digestje, vagy a tag nem a mért verzió |
not_measured |
a konténert vagy a verzió-parancsot nem sikerült megmérni; az ok ott áll a sor végén |
Egy mismatch elbuktatja a futást — de azután, hogy a táblázat és az összesítő
kiíródott, így egy futásból megvan a teljes kép. Egy not_measured nem
buktat: egy álló gép nem verzió-eltérés.
Egy frissítés előtte-pillanatképénél — a pin már az új verziót nevezi meg, a
gépen még a régi fut — a mismatch a várt állapot. Ilyenkor
-e isg_cv_fail_on_mismatch=false: a riport ugyanúgy kiíródik (és fájlba is
megy), a futás nem bukik.
Mibe kerül egy frissítés, komponensenként
OpenLDAP — a címtár a seedből épül újra
Az image cseréje újra létrehozza a konténert, és a címtár a seedből épül fel ismét. Azokat a csak olvasó fiókokat, amikkel az átjáró bindol, a role visszateszi; ami bejegyzés a címtár futása közben került be, az elveszik, és a brókerek bindja az újraindítás alatt rövid időre kiesik. Kétszer mérve, 2026-10-08-án.
Ennek megfelelően kezeld: ha a seedelt tartalmon kívül bármi él ebben a címtárban, előbb exportáld.
OpenBao — minden újraindítás után zárva
Egy újraindítás a titok-tárat zárva (sealed) hagyja. Ez nem egy kikerülendő
hibamód: a role ezt hangosan, pirossal kimondja, és megáll, nem pedig úgy tesz,
mintha a tár használható lenne. A kinyitás külön, szándékos lépés, és saját
playbookja van — bao-init.yml. A kinyitást ugyanabba a karbantartási ablakba
tervezd, mint a frissítést; amíg az le nem fut, minden elhasal, aminek titok
kell a tárból.
PostgreSQL — a major-verzió egy dump és egy restore
A major-verzió a pin része. Az automatizálás egy telepítést nem visz át egy
major-verzión: új adatkönyvtár kell, és az adat egy dumppal és egy restore-ral
jut el oda. A 18-tól az image az adatot más elrendezésben is tartja — a tár
adatkönyvtára /var/lib/postgresql-ként van csatolva, és a klaszter a
18/docker alkönyvtárában él.
A role megtagadja, hogy egy 18-as image-et a régi elrendezésű adatkönyvtáron
indítson (PG_VERSION a gyökerében): ott a Postgres egy új, üres adatbázist
inicializálna a régi fájlok mellé. Egyszer mérve (2026-10-11, egy
labor-telepítésen, 16.15 → 18.6): friss mentés, a unit leállítva, a régi
könyvtár félreátnevezve, egy üres a helyére, abba restore a dumpból az új
image-dzsel, majd a role — a sor-számok egyeztek a mentés manifestjével. Egy új
telepítés eleve a pinelt majoron indul, és ebből semmi nem kell neki.
Egy minor verziós image-csere a meglévő adatköteten várhatóan esemény nélküli — de ez hipotézis, nem mérés: ebben a telepítésben nem mértük. Előbb mentsd a kötetet, és olvasd el annak a minornak az upstream kiadási jegyzetét, amire lépsz.
Keycloak — a beépített adatbázis egy köteten áll
Az identity provider start-dev módban fut, a beépített adatbázisa a
keycloak/data köteten. Az image cseréje tehát ennek a kötetnek a
DB-migrációját jelenti, amit az új verzió az első induláskor végez el.
Egyszer mérve (2026-10-11, egy labor-telepítésen): 26.3.5 → 26.8.0, öt minor
verzió egy ugrással — a migráció az első induláskor lefutott, az identity
provider nagyjából fél perc után válaszolt, és a realm, a kliens meg az
LDAP-föderáció változatlanul megmaradt. Egy mérés, nem garancia minden ugrásra.
Tehát: előbb mentsd a kötetet, és csak utána írd át a pint. Ha a migráció elromlik, a mentés az út vissza az előtte lévő állapotba. A kötet fájljai a konténer felhasználójáéi, ami a hoszton egy alárendelt uid — a felhasználói névtéren belül olvasd és állítsd vissza őket, például:
podman unshare tar czf <archive> -C <keycloak-home> data
A 26.8-tól a Keycloak újra bekéri a bind-jelszót, valahányszor az LDAP-föderáció connection URL-je vagy bind DN-je változik; maszkolt jelszót nem fogad el. A role erre szolgáló útja (a retransport-kapcsoló) eleve a valódi jelszót küldi. Egy kézi módosításnál az admin-konzolon a jelszót újra be kell írni.
RustFS, Prometheus, Grafana, node_exporter és Mailpit
Ennél az ötnél az automatizálásban nincs külön lépés: írd át a pint, futtasd a role-t, és a unit az új image-dzsel indul újra. Hogy egy adott verzióugrás megváltoztatja-e a komponens adatainak lemezformátumát, az itt nem mért — ugrás előtt olvasd el az upstream kiadási jegyzetét.
Egyikükről érdemes kimondani: a Mailpit egy teszt SMTP-csapda. Azért van ott, hogy egy telepítés látni tudja az átjáró által küldött levelet anélkül, hogy ki is küldené; nem levélszerver semmi valódihoz, és semmi nem veszik el, amikor a konténere kicserélődik.
Amit a riport NEM mond meg
A riport nem kérdezi meg az upstreamtől, mi a legfrissebb verzió, és egyáltalán
nem hív ki a hálózatra: az egyetlen verzió-parancs, ami alapból online
ellenőrizne, a Mailpité, --no-release-check-kel fut. Egy mért verziót az
upstream által közzétetthez hasonlítani külön lépés, egy erre választott gépen.
Havi upstream-ellenőrzés
Ez a külön lépés a playbooks/component-upstream.yml. Csak a vezérlőn fut,
minden pinelt komponens registry-jétől megkérdezi a legmagasabb stabil tagot, és
mindegyikre verdiktet mond: current, behind vagy not_measured. A behind
nem hiba — egy döntés bemenete.
Mit futtat, mikor, és hova ír. A playbooks/upstream-schedule.yml egy
systemd user timert telepít a vezérlőre (az isg_upstream_schedule role). A
timer minden hónap első napján 07:20-kor indul, legfeljebb 30 perc véletlen
késéssel, és a Persistent=true egy kimaradt futást a vezérlő indulása után
behoz. Minden futás a riportot egy JSON- és egy Markdown-fájlba írja, a
vezérlő-felhasználó home-jának isg-component-reports könyvtárába
(isg_upstream_schedule_report_dir). A timernek nem kell se root, se token, se
sudo-jelszó: az ellenőrzés minden playje localhoston, become nélkül fut, és a role
ezt a futtató fán telepítés ELŐTT megméri.
cd ansible
ansible-playbook -i inventory/<környezet>.ini -e isg_env=<környezet> \
playbooks/upstream-schedule.yml
journalctl --user -u isg-upstream-<környezet>.service # a futások
Mikor megy levél, és kinek. Ha legalább egy komponens behind, a futás a
Markdown-táblát elküldi az isg_cfg_upstream_notify_to címeire, a telepítés
meglévő SMTP-útján (isg_cfg_smtp_host, isg_cfg_smtp_port, isg_cfg_smtp_from).
Ha semmi nem behind, nincs levél, és a napló ezt egy sorban kimondja; ugyanígy
üres címzett-listánál. Az SMTP-hiba a futást pirossá teszi, a hosztot és a portot
megnevezve — egy csendben el nem ment levél pont az, ami ellen a havi ellenőrzés
van. A küldő sima SMTP-t beszél, TLS és hitelesítés nélkül; egy valódi relét az
üzemeltető ad.
Mi a teendő egy behind-dal. Ne frissíts egy komponenst azon a napon, amikor
a levele megjön. Gyűjtsd a behind-sorokat egy kötegbe, és a köteget együtt
frissítsd: minden pint írj át az új tag index-digestjére, futtass verzióriportot
előtte és utána (fent), és az ezen az oldalon álló komponensenkénti árakból nézd
meg, mi kér egy újraindításnál többet.
A tűzfal az SMTP-úton. A címtár-hoszton az SMTP-port alapból csak a
brókereknek nyílik (isg_directory_firewall_client_sources); a levél most a
vezérlőről is jön, ezért a címe az isg_directory_firewall_smtp_extra_sources-ba
kerül. E nélkül a tűzfal a vezérlőt elutasítja (mérve: „No route to host"), és a
futás pirosra vált, a hosztot és a portot megnevezve.