V DevOps jsou jedním z nejtěžších problémů ti, kteří aktivně blokují vlastní vyšetřování. Ve sporu o mistrovský titul jsou druhým nejhorším druhem problémů ty, které se vyskytují občas. Tento článek je dobrodružným příběhem z doby, kdy se Podmanův upstream systém Continuous Integration/Continuous Deployment (CI/CD) setkal s oběma současně.
Perfektní bouře
Kdysi dávno, testovací automatizace Podman začala přerůstat přes kalhoty „velkého chlapce“. K tomu došlo před lety, kdy byly prakticky všechny systémy CI/CD založeny na kontejnerech. Podman, jakožto nástroj pro správu (a ladění) kontejnerů (a podů), nelze plně uplatnit v kontejneru. Možná ještě horší je, že většina služeb automatizace komodit podporovala pouze Ubuntu. To se rychle stalo absolutním neúspěchem, protože Podman potřeboval běžet na virtuálních strojích (VM). Potřeboval také běžet proti více distribucím, včetně upstream distribuce Red Hatu, Fedora.
Díky zkušenostem s pracovními postupy CI/CD naroubovanými pod nastavení cloud-sdk + SSH (a/nebo Ansible) pro cloudový přístup se zdá, že zvýšená složitost vždy způsobuje problémy. Pak jsem jednoho dne narazil na Cirrus-CI. Cirrus-CI je automatizační nástroj zaměřený na Git, který dokáže organizovat kontejnery a virtuální počítače pomocí velkého množství poskytovatelů cloudu. Umožnil týmu Podman platit a spravovat cloudovou službu nezávisle na její orchestraci. Mohli bychom si ponechat plnou kontrolu nad VM a daty protokolů, přičemž orchestraci bude spravovat pouze Cirrus-CI.
Celkový pracovní postup vypadá asi takto:
- Vývojář odešle navrhované změny kódu upstream do úložiště Git společnosti Podman.
- Cirrus-CI si toho všimne, přečte konfigurační soubor a poté spustí potřebné virtuální počítače v našem cloudu.
- Nativní cloudové metadatové služby spravují provádění skriptů a přihlašování zpět do Cirrus-CI.
- Cirrus-CI odstraňuje virtuální počítače a poskytuje vývojářům zpětnou vazbu o úspěšném/neúspěšném provedení.
- Provedou se změny a cyklus se opakuje, dokud není kód přijat.
Po celá léta tento pracovní postup fungoval téměř bezchybně, přičemž většina problémů se soustředila na testy a skripty – chyby, které tým Podman snadno zvládne. Problémy v rámci Cirrus-CI, internetu a/nebo našeho cloudového poskytovatele jen zřídka vedou k osiřelým (neodstraněním) virtuálních počítačů. Jinak byl podpůrný personál v Cirrus Labs fantastický, velmi přístupný, s prvotřídní odezvou a zodpovědností.
Potom jednoho dne v říjnu 2020, po otočení sady čerstvě aktualizovaných obrazů virtuálních počítačů (tj. obraz disku zkopírovaný pro každou novou instanci virtuálního počítače), začaly zdánlivě náhodné úlohy selhávat. Počáteční zkoumání výstupu skriptu neposkytlo žádné informace. Doslova veškerý výstup by se náhle zastavil, aniž by se daly rozeznat jiné poruchy. Jak se očekávalo, Cirrus-CI pilně vyčistí VM a předloží výsledné selhání zpět vývojáři, aby zjistil. Po opětovném provedení neúspěšné úlohy by často uspěla bez incidentů.
Tato situace trvala několik týdnů bez problémů – s výpadky infrastruktury v našem cloudu, GitHubu nebo Cirrusu. Tento problém byl poněkud vzácný, možná jen hrstka selhání za den ze stovek úspěšných zakázek. Hledání závad bylo obtížné a věčné opakování úloh nemohlo být dlouhodobým řešením. Kromě pravidelných zpráv o incidentech od mého týmu jsem nedokázal rozeznat žádný vzor selhání na vysoké úrovni. Vzhledem k tomu, že nové obrazy virtuálních počítačů přinášely značné výhody, náklady na vrácení zpět by byly také vysoké.
Pro téměř jakýkoli systémový problém, jako je tento, je nalezení vzorců chování klíčovým prvkem pro úspěšné řešení problémů. Vzhledem k tomu, že spolehlivý pracovní úspěch je požadovaný stav, bylo mít alespoň nějakou představu nebo náznak, tvrdým požadavkem. Bohužel v tomto případě byla naše schopnost pozorovat vzory extrémně omezena náhodnými selháními a vysoce žádoucí funkcí:Vyčištění nepoužívaných cloudových virtuálních počítačů, které plýtvají skutečnými penězi.
Jednoduché, opakované ruční provádění testu problém vůbec nereprodukovalo. Chování neovlivnilo ani použití většího množství CPU a paměťových zdrojů. Strávil jsem dny přemýšlením a brainstormingem o možnostech, jak shromáždit další data spojená s chybami. Nakonec mě napadlo, že potřebuji způsob, jak selektivně přerušit čištění virtuálních počítačů, ale pouze v případech, kdy se testy nepodařilo dokončit.
[ Také by se vám mohlo líbit: Od sysadmina po DevOps ]
Jinými slovy, potřeboval jsem nějakým způsobem spojit úspěšné dokončení testu (ne pouze projít/nevyhovovat) s povolením provedení čištění. Tehdy jsem si vzpomněl na malé zaškrtávací políčko, které jsem kdysi viděl, když jsem se probíral webovým rozhraním našeho cloudu:Ochrana proti smazání . Když je tento příznak nastaven, Cirrus-CI si bude hlasitě stěžovat, protože je blokován v odebrání virtuálního počítače, ale jinak nechá věci nerušené.
Potřeboval jsem instrumentovat náš pracovní postup, aby samy virtuální počítače mohly nastavit a zrušit nastavení vlastního příznaku ochrany proti odstranění. Něco jako toto:
- VM sám o sobě umožňuje ochranu proti smazání.
- Spusťte testy.
- VM deaktivuje vlastní ochranu proti vymazání.
- Cirrus-CI vyčistí nebo nedokáže vyčistit virtuální počítač a zapáchá po něm.
Tímto způsobem po dokončení testů Cirrus-CI s radostí odebere VM jako obvykle. Pokud by však k problému došlo, testy by nebyly dokončeny a Cirrus-CI by narazil na (stále) povolenou ochranu proti odstranění. Naštěstí bylo možné tento pracovní postup realizovat pomocí jednoduchých možností příkazového řádku do obslužného programu pro správu cloudu, který jsem mohl nainstalovat na virtuální počítače.
S touto instrumentací pracovního postupu jsem potřeboval pouze opakovaně spouštět testovací matici a čekat, až se objeví osiřelé virtuální počítače. Osudy se na mě toho dne usmívaly, protože problém se téměř okamžitě reprodukoval. Spustil jsem to však ještě několikrát, takže bych měl ke kontrole více než několik osiřelých virtuálních počítačů.
To je nečekaně, když se situace stala ještě zajímavější:nemohl jsem SSH do osiřelých virtuálních počítačů. Ve skutečnosti by ani nereagovali na ping zevnitř nebo zvenčí našeho cloudu. U jednoho virtuálního počítače jsem provedl tvrdý reset a po spuštění jsem zkontroloval systémové protokoly. Nic nebylo. zip. Nada. Ani jediná stopa kromě toho, co jsme již věděli:Testy se prostě přestaly provádět, byly mrtvé, spolu se zbytkem systému.
Protože už to byl můj šťastný den, rozhodl jsem se to prosadit a znovu jsem se pustil do webového rozhraní mého cloudu. Nakonec jsem našel další neuvěřitelně praktické malé nastavení:Protokol výstupu sériové konzoly . Toto byla v podstatě přímá, nízkoúrovňová komunikační linka přímo do jádra. Pokud by se stalo něco tak hrozného, že by došlo k úplnému zablokování systému, jádro by jistě křičelo ze svého virtuálního sériového portu. Bingo, Yahtzee a huzzah!
[ 1203.905090] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 1203.912275] #PF: supervisor read access in kernel mode
[ 1203.917588] #PF: error_code(0x0000) - not-present page
[ 1203.922881] PGD 8000000124e2d067 P4D 8000000124e2d067 PUD 138d5e067 PMD 0
[ 1203.929939] Oops: 0000 [#1] SMP PTI
...blah...blah...blah
[ 1204.052766] Call Trace:
[ 1204.055440] bfq_idle_extract+0x52/0xb0
[ 1204.059468] bfq_put_idle_entity+0x12/0x60
[ 1204.063722] bfq_bfqq_served+0xb0/0x190
[ 1204.067718] bfq_dispatch_request+0x2c2/0x1070
Proč, ahoj, starý příteli! Byl to skutečně velmi šťastný den!
Tohle byla jaderná panika, kterou jsem viděl před rokem a neúnavně jsem na tom měsíce pracoval s upstream jaderným inženýrstvím. Byla to chyba v úložném subsystému jádra zodpovědného za zlepšení efektivity a zaručení zápisu cenných 0 a 1 na disk. V tomto případě jádro namísto poškozeného úložiště vyvolalo bílou vlajku a zastavilo vše mrtvé v jeho stopách.
Tím, že jsem dříve řešil téměř stejný problém, jsem si již byl vědom jednořádkového řešení. Nebylo třeba znovu protahovat můj tým měsíci ladění. Mohl bych jednoduše nahlásit opakování a s jistotou nasadit náhradní řešení s vědomím, že to 100% vyřeší problém:
echo mq-deadline > /sys/block/sda/queue/scheduler
Nyní nedoporučuji spouštět tento příkaz chtě nechtě na každém systému Linux, který vlastníte. V tomto konkrétním případě jsem z minulé zkušenosti věděl, že je zcela bezpečné vyměnit algoritmus vyrovnávací paměti (nazývaný také I/O Elevator). Žádný vývojář Podman by si ani nevšimnul změny ve výsledcích testování.
[ Začínáte s kontejnery? Podívejte se na tento bezplatný kurz. Nasazení kontejnerových aplikací:technický přehled. ]
Sbalit
Pokud byste se vy nebo někdo z vašich blízkých někdy setkali s vlastní jadernou panikou, doporučuji se podívat na tento nedávný článek na toto téma. Jinak je hlavní závěr toto:Při odstraňování problémů naslepo je řešení aspektů příčiny a zatemňování naprosto zásadní. Druhým je práce s daty, aby byl problém lépe reprodukovatelný. Budete mít velmi těžké dělat to druhé bez pomoci prvního.