Linux má mnoho tvárí: ako pracovať na akomkoľvek distribúcii

Linux má mnoho tvárí: ako pracovať na akomkoľvek distribúcii

Vytvorenie aplikácie na zálohovanie, ktorá funguje na akomkoľvek distribučnom systéme, nie je jednoduchá úloha. Na zabezpečenie funkcie Veeam Agent for Linux na distribúciách od Red Hat 6 a Debian 6 až po OpenSUSE 15.1 a Ubuntu 19.04 je potrebné vyriešiť množstvo problémov, najmä ak vezmeme do úvahy, že produkt obsahuje modul jadra.

Článok bol vytvorený na základe materiálov z prezentácie na konferencii LinuxPiter 2019.

Linux nie je len jedna z najpopulárnejších operačných systémov. V podstate ide o platformu, na ktorej môžete vytvoriť niečo jedinečné, niečo vlastné. Vďaka tomu existuje množstvo distribúcií Linuxu, ktoré sa líšia sadou programových komponentov. A tu vzniká problém: aby produkt fungoval na akejkoľvek distribúcii, je potrebné zohľadniť špecifiká každej.

Správca balíkov: .deb vs .rpm

Začneme s jasným problémom distribúcie produktu pre rôzne distribúcie.
Najtypickejší spôsob distribúcie softvérových produktov je uloženie balíka do repozitára, aby ho mohol integrovaný správca balíkov systému odtiaľ nainštalovať.
Existujú však dva populárne formáty balíkov: rpm a deb. Znamená to, že budeme musieť podporovať každý.

Vo svete deb-balení je úroveň kompatibility ohromujúca. Ten istý balík sa rovnako dobre inštaluje a funguje ako na Debian 6, tak aj na Ubuntu 19.04. Normy procesu vytvárania balíkov a práce s nimi, zavedené v starších Debian distribúciách, zostávajú relevantné aj v moderných Linux Mint a elementary OS. Preto v prípade Veeam Agent for Linux stačí jeden deb-balik pre každú hardvérovú platformu.

V oblasti rpm-balení sú rozdiely značné. Po prvé, pretože existujú dvaja úplne nezávislí distribútori Red Hat a SUSE, medzi ktorými nie je potrebná žiadna kompatibilita. Po druhé, obaja majú distribúcie s technickou podporou a experimentálne. Medzi nimi tiež nie je potrebná kompatibilita. Máme teda balíky pre el6, el7 a el8. Samostatne balík pre Fedoru. Balíky pre SLES11 a 12 a samostatný balík pre openSUSE. Hlavným problémom sú závislosti a názvy balíkov.

Problém so závislosťami

Bohužiaľ, tie isté balíky sa často nachádzajú pod rôznymi názvami v rôznych distribúciách. Nižšie je neúplný zoznam závislostí balíka veeam.

Pre EL7:
Pre SLES 12:

  • libblkid
  • libgcc
  • libstdc++
  • ncurses-libs
  • fuse-libs
  • file-libs
  • veeamsnap = 3.0.2.1185
  • libblkid1
  • libgcc_s1
  • libstdc++6
  • libmagic1
  • libfuse2
  • veeamsnap-kmp = 3.0.2.1185

V dôsledku toho je zoznam závislostí jedinečný pre distribúciu.

Horšie je, keď sa pod starým menom balíka začne skrývať aktualizovaná verzia.

Príklad:

Vo Fedore 24 sa aktualizoval balík ncurses z verzie 5 na verziu 6. Náš produkt bol zostavený presne s verziou 5, aby sa zabezpečila kompatibilita so starými distribúciami. Aby bolo možné využiť starú verziu 5 knižnice na Fedoru 24, bolo potrebné použiť balík ncurses-compat-libs.

V dôsledku toho pre Fedoru vznikajú dva balíky s rôznymi závislosťami.

Ďalej je to zaujímavejšie. Po ďalšej aktualizácii distribúcie je balík ncurses-compat-libs s verziou 5 knižnice nedostupný. Pre distribútora je nákladné prenášať staré knižnice do novej verzie distribúcie. Po čase sa problém opäť objavil aj v distribúciách SUSE.

V dôsledku toho sa niektoré distribúcie museli vzdať explicitnej závislosti od ncurses-libs, a produkt bolo potrebné opraviť tak, aby mohol fungovať s akoukoľvek verziou knižnice.

Mimochodom, v 8. verzii Red Hat už nie je meta-balík python, ktorý odkazoval na starý dobrý python 2.7. Existuje python2 a python3.

Alternatíva k balíkovým manažérom

Problém so závislosťami je starý a dávno očividný. Spomeňme si len na Dependency hell.
Spojiť rôzne knižnice a aplikácie tak, aby všetky stabilne fungovali a nekolidovali – to je úloha, ktorú sa snaží riešiť každý distribútor Linuxu.

Úplne inak sa snaží tento problém riešiť balíkový manažér Snappy od Canonical. Hlavná myšlienka: aplikácia sa vykonáva v izolovanej a chránenej pieskovici od hlavného systému. Ak aplikácii potrebné knižnice, dodávajú sa spolu s aplikáciou.

Flatpak tiež umožňuje spúšťať aplikácie v pieskovici, pomocou Linux Containers. Myšlienku pieskovice využíva aj AppImage.

Tieto riešenia umožňujú vytvárať jeden balík pre akékoľvek distribúcie. V prípade s Flatpak inštalácia a spustenie aplikácie je možné aj bez vedomia administrátora.

Hlavný problém spočíva v tom, že nie všetky aplikácie môžu fungovať v pieskovici. Niektorým je potrebný priamy prístup k platforme. O modulov jadra, ktoré pevne závisia od jadra a nijako sa nehodia do konceptu pieskovice, ani nehovorím.

Druhý problém – populárne distribúcie v enterprise prostredí od Red Hat a SUSE ešte nepodporujú Snappy a Flatpak.

S ohľadom na to, Veeam Agent for Linux nie je ani na snapcraft.io ani na flathub.org.

Na záver otázky o balíkových manažéroch poznam, že existuje možnosť vzdať sa balíkových manažérov a zlúčiť do jedného balíka binárne súbory a skript na ich inštaláciu.

Taký bundle umožňuje vytvoriť jeden spoločný balík pre rôzne distribúcie a platformy, vykonávať interaktívny proces inštalácie a zabezpečiť potrebnú prispôsobenie. S takými balíkmi pre Linux som sa stretol len od VMware.

Problém s aktualizáciami

Linux má mnoho tvárí: ako pracovať na akomkoľvek distribúcii
Aj keď sú všetky problémy so závislosťami vyriešené, program môže fungovať rôzne na tej istej distribúcii. Ide o aktualizácie.

Existujú 3 stratégie aktualizácie:

  • Najjednoduchšie je nikdy neaktualizovať. Nastavil si server a zabudol. Prečo aktualizácie, ak všetko funguje? Problémy začínajú s prvým telefonátom na technickú podporu. Výrobca distribúcie podporuje len aktualizovanú verziu.
  • Môžeš dôverovať distribútorovi a nastaviť automatické aktualizácie. V tomto prípade je pravdepodobné, že zavoláš na technickú podporu hneď po neúspešnej aktualizácii.
  • Možnosť manuálnej aktualizácie len po jej otestovaní na testovacej infraštruktúre je najistejšia, ale aj najnákladnejšia a najprácnejšia. Nielenže to nie každý zvládne, ale aj nie každý si to môže dovoliť.

Keďže rôzni používatelia používajú rôzne stratégie aktualizácie, je potrebné podporovať najnovšie vydanie aj všetky predchádzajúce. To komplikuje proces vývoja aj testovania a pridáva starosti technickej podpore.

Rôznorodosť hardvérových platforiem

Rôzne hardvérové platformy sú problém, ktorý je do veľkej miery špecifický pre natívny kód. Minimálne je potrebné zostaviť binárne súbory pre každú podporovanú platformu.

V projekte Veeam Agent for Linux sa stále nedokážeme podporiť aspoň niečo RISC-ové.

Podrobne sa tejto otázke nezastavím. Označím len hlavné problémy: platformovo závislé typy ako size_t, zarovnanie štruktúr a byte order.

Statická a/alebo dynamická linkovanie

Linux má mnoho tvárí: ako pracovať na akomkoľvek distribúcii
Otázka „Ako sa linkovať s knižnicami — dynamicky alebo staticky?“ si zaslúži diskusiu.

Zvyčajne aplikácie C/C++ pod Linuxom používajú dynamické prepojenie. To skvele funguje, ak je aplikácia zostavená špeciálne pre konkrétny distribúciu.

Ak je však cieľom pokryť rôzne distribúcie jedným binárnym súborom, je potrebné orientovať sa na najstaršiu podporovanú distribúciu. Pre nás je to Red Hat 6. Obsahuje gcc 4.4, ktorý dokonca nepodporuje štandard C++11. úplne.

Náš projekt zostavujeme pomocou gcc 6.3, ktorý plne podporuje C++14. Pri takom prípade musíme samozrejme so sebou vziať knižnice libstdc++ a boost. Najjednoduchšie je prepojovať sa s nimi staticky.

Bohužiaľ, nie so všetkými knižnicami je možné prepojovať sa staticky.

Po prvé, systémové knižnice, ako sú libfuse, libblkid je potrebné prepojovať dynamicky, aby sme mali istotu, že budú kompatibilné s jadrom a jeho modulmi.

Po druhé, existuje nuance s licenciami.

Licencia GPL v zásade povoľuje prepojenie knižníc len s opensource kódom. MIT a BSD povoľujú statické prepojenie a umožňujú zahrnúť knižnice do projektu. A LGPL sa zdanlivo neprotirečí statickému prepojeniu, ale vyžaduje, aby boli sprístupnené súbory potrebné na prepojenie.

Všeobecne povedané, používanie dynamického prepojenia ochráni pred nutnosťou niečo poskytovať.

Zostavenie aplikácií C/C++

Na zostavenie aplikácií C/C++ pre rôzne platformy a distribúcie stačí vybrať alebo zostaviť gcc vhodnej verzie a využiť krížové kompilátory pre špecifické architektúry, zostaviť celý súbor knižníc. Práca je to realizovateľná, ale dosť náročná. A nie sú žiadne záruky, že zvolený kompilátor a knižnice zabezpečia funkčný variant.

Zrejmou výhodou je: značne sa zjednodušuje infraštruktúra, pretože celý proces zostavenia je možné vykonať na jednom stroji. Okrem toho stačí zostaviť jeden súbor binárnych súborov pre jednu architektúru a môžeme ich zabaliť do balíkov pre rôzne distribúcie. Presne tak sa zbierajú balíky veeam pre Veeam Agent for Linux.

Na rozdiel od tohto prístupu je možné jednoducho pripraviť build farmu, teda niekoľko strojov na zostavovanie. Každý takýto stroj zabezpečí kompiláciu aplikácie a zostavenie balíka pre konkrétny distribučný systém a určitú architektúru. V takom prípade prebieha kompilácia prostredníctvom nástrojov, ktoré pripravil distribútor. Tým sa vynechá etapa prípravy kompilátora a výber knižníc. Okrem toho je proces zostavovania možné ľahko paralelizovať.

Existuje však aj nevýhoda tohto prístupu: pre každý distribučný systém v rámci jednej architektúry bude potrebné zostaviť vlastný súbor binárnych súborov. Ďalšou nevýhodou je, že taký počet strojov je potrebné spravovať, vyžaduje to veľké množstvo diskového priestoru a operačnej pamäte.

Takto sa zostavujú KMOD balíky modulu jadra veeamsnap pre distribučné systémy Red Hat.

Open Build Service

Kolegovia zo SUSE sa pokúsili implementovať akýsi zlatý stred v podobe špeciálnej služby na kompiláciu aplikácií a zostavovanie balíkov — openbuildservice.

V podstate ide o hypervízor, ktorý vytvára virtuálny stroj, inštaluje doň všetky potrebné balíky, vykonáva kompiláciu aplikácie a zostavuje balík v tomto izolovanom prostredí, po čom je takýto virtuálny stroj uvoľnený.

Linux má mnoho tvárí: ako pracovať na akomkoľvek distribúcii

Plánovač implementovaný v OpenBuildService sám určí, koľko virtuálnych strojov môže spustiť pre optimálnu rýchlosť zostavovania balíkov. Vstavaný mechanizmus podpisovania sám podpíše balíky a umiestni ich na vstavaný repozitár. Vstavaný systém verziovania zachová históriu zmien a zostavenia. Zostáva len pridať do tohto systému svoje zdrojové kódy. Dokonca nemusíte sami zriaďovať server, môžete využiť otvorený.

Tu však existuje problém: takýto kombajn sa ťažko integruje do existujúcej infraštruktúry. Napríklad verzionovanie nie je potrebné, už máme vlastný pre zdrojové kódy. Mechanizmus podpisovania sa odlišuje: používa sa špeciálny server. Repozitár tiež nie je potrebný.

Okrem toho je podpora iných distribučných systémov — napríklad Red Hat — realizovaná dosť chabo, čo je úplne pochopiteľné.

Výhodou tejto služby je rýchla podpora novej verzie distribúcie SUSE. Pred oficiálnym oznámením o vydaní sú potrebné balíčky na zostavenie zverejnené na verejnom repozitári. V zozname dostupných distribúcií na OpenBuildService sa objaví nový. Zaškrtneme políčko a ten sa pridá do plánu zostavenia. Takto je pridanie novej verzie distribúcie vykonané takmer jedným kliknutím.

V našej infraštruktúre sa pomocou OpenBuildService zostavuje všetka rozmanitosť KMP balíkov modulu jadra veeamsnap pre distribúcie SUSE.

Ďalej by som sa chcel zamerať na otázky, ktoré sú špecifické práve pre moduly jadra.

kernel ABI

Moduly jadra Linuxu sa historicky distribuovali vo forme zdrojových kódov. Ide o to, že tvorcovia jadra sa nezamýšľajú nad podporou stabilného API pre moduly jadra, nieto ešte na binárnej úrovni, ďalej kABI.

Na zostavenie modulu pre vanilkový jadro sú nevyhnutné hlavičkové súbory práve tohto jadra a bude fungovať iba na tomto jadre.

DKMS umožňuje automatizovať proces zostavovania modulov pri aktualizácii jadra. V dôsledku toho používatelia repozitára Debian (a jeho početných príbuzných) používajú moduly jadra buď z repozitárov distribútora, alebo zostavené zo zdrojov pomocou DKMS.

Avšak takáto situácia nie je veľmi uspokojivá pre segment Enterprise. Distribútori proprietárneho kódu chcú distribuovať produkt vo forme zostavených binárnych súborov.

Správcovia nechcú držať vývojové nástroje na produkčných serveroch z bezpečnostných dôvodov. Distribútori Enterprise Linuxu – ako Red Hat a SUSE – sa rozhodli, že pre svojich používateľov budú schopní podporovať stabilné kABI. V dôsledku toho sa objavili balíky KMOD pre Red Hat a KMP balíky pre SUSE.

Podstata tohto riešenia je veľmi jednoduchá. Pre konkrétnu verziu distribúcie sa API jadra zmrazuje. Distribútor vyhlasuje, že používa práve jadro, napríklad 3.10, a vykonáva iba opravy a vylepšenia, ktoré nijako neovplyvňujú rozhrania jadra, a moduly zostavené pre najstaršie jadro môžu byť použité pre všetky nasledujúce bez potreby recompilácie.

Red Hat uvádzajú, že kABI kompatibilita pre distribúciu zostáva zachovaná počas celého životného cyklu. To znamená, že zostavený modul pre RHEL 6.0 (vydanie v novembri 2010) by mal fungovať aj vo verzii 6.10 (vydanie v júni 2018). A to je takmer 8 rokov. Samozrejme, úloha je dosť zložitá.
Zaznamenali sme niekoľko prípadov, keď kvôli problémom s kABI kompatibilitou modul veeamsnap prestal fungovať.

Po tom, čo sa modul veeamsnap, zostavený pre RHEL 7.0, ukázal ako nekompatibilný s jadrom z RHEL 7.5, ale pritom sa načítaval a zaručene spôsoboval pád servera, sme úplne upustili od používania kABI kompatibility pre RHEL 7.

V súčasnosti KMOD balík pre RHEL 7 obsahuje zostavovanie pre každú verziu vydania a skript, ktorý zabezpečuje načítanie modulu.

SUSE k úlohe kABI kompatibility pristupovali opatrnejšie. Zabezpečujú kABI kompatibilitu len v rámci jedného service pack.

Napríklad vydanie SLES 12 sa uskutočnilo v septembri 2014. A SLES 12 SP1 už v decembri 2015, čiže uplynulo len o niečo viac ako rok. Napriek tomu, že obidve vydania používajú jadro 3.12, sú kABI nekompatibilné. Je zrejmé, že udržiavať kABI kompatibilitu po dobu len jedného roka je výrazne jednoduchšie. Ročný cyklus aktualizácie modulu jadra by nemal spôsobovať problémy tvorcom modulov.

V dôsledku takejto politiky SUSE sme nezaznamenali žiadny problém s kABI kompatibilitou nášho modulu veeamsnap. Pravda, aj počet balíkov pre SUSE je takmer o poriadok väčší.

Opravy a b backporty

Napriek tomu, že distribútori sa snažia zabezpečiť kABI kompatibilitu a stabilitu jadra, snažia sa aj zlepšiť výkon a odstrániť nedostatky tohto stabilného jadra.

Pritom okrem vlastnej „práce na chybách“ vývojári jadra enterprise linux sledujú zmeny vo vanilkovom jadre a prenášajú ich do svojho „stabilného“.

Niekedy to vedie k novým chybám.

V poslednom vydaní Red Hat 6 v jednom z drobných aktualizácií došlo k chybe. Viedla k tomu, že modul veeamsnap zaručene spôsoboval pád systému pri uvoľnení snímky. Porovnaním zdrojových textov jadra pred a po aktualizácii sme zistili, že za všetkým bol backport. Podobná oprava bola vykonaná vo vanilkovom jadre verzie 4.19. Lenže v vanilkovom jadre táto oprava fungovala normálne, zatiaľ čo pri prenose do „stabilného“ 2.6.32 vznikol problém so spin-locking.

Samozrejme, chyby sa vyskytujú u všetkých a vždy, ale stálo za to prenášať kód z 4.19 do 2.6.32, riskujúc stabilitu?.. Nie som si istý...

Najhoršie je, keď sa k ťahaniu lanom „stabilita“„modernizácia“ pridáva marketing. Oddelenie marketingu potrebuje, aby jadro aktualizovaného distribučného balíka bolo stabilné, na jednej strane, a zároveň aby bolo lepšie z hľadiska výkonu a malo nové funkcie. To vedie k zvláštnym kompromisom.

Keď som sa pokúsil zostaviť modul na jadre 4.4 od SLES 12 SP3, prekvapene som zistil, že obsahuje funkčnosť z vanilkového 4.8. Podľa môjho názoru realizácia blokového vstupu/výstupu jadra 4.4 od SLES 12 SP3 sa viac podobá na jadro 4.8 než na predchádzajúce vydanie stabilného 4.4 jadra od SLES12 SP2. Koľko percent kódu bolo prenesených z jadra 4.8 do SLES-ovského 4.4 pre SP3, to posúdiť neberiem, ale nazvať jadro opäť stabilným 4.4 sa mi naozaj nepáči.

Najnepríjemnejšie na tom je, že pri písaní modulu, ktorý by fungoval rovnako dobre na rôznych jadrách, sa už nedá spoľahnúť na verziu jadra. Musí sa tiež zohľadniť distribúcia. Dobre, že niekedy môžeš sa spojiť s define, ktorý sa objaví spolu s novou funkčnosťou, ale táto možnosť sa neobjavuje vždy.

V dôsledku toho kód získa čudné direktívy podmienečnej kompilácie.

Vyskytujú sa aj patche, ktoré menia zdokumentované API jadra.
Narazil som na distribúciu KDE neon 5.16 a bol som veľmi prekvapený, keď som videl, že volanie lookup_bdev v tejto verzii jadra zmenilo poradie vstupných parametrov.

Aby sa to mohlo zostaviť, musel som do makefile pridať skript, ktorý kontroluje, či je parameter mask pri funkcii lookup_bdev.

Podpis modulov jadra

Ale vráťme sa k otázke distribúcie balíkov.

Jednou z výhod stabilného kABI je to, že moduly jadra vo forme binárneho súboru môžu byť podpísané. V tomto prípade si môže byť vývojár istý, že modul nebol náhodne poškodený alebo úmyselne zmenený. Môžeš to skontrolovať príkazom modinfo.

Distribúcie Red Hat a SUSE umožňujú kontrolovať podpis modulu a načítať ho iba vtedy, ak je v systéme registrovaný príslušný certifikát. Certifikát je verejný kľúč, ktorým sa modul podpisuje. Šíri sa vo forme samostatného balíka.

Problém je v tom, že certifikáty môžu byť buď zabudované v jadre (používajú ich distribútori), alebo musia byť zapísané do nevolatilnej pamäte EFI pomocou utilít. mokutil. Nástroj mokutil pri inštalácii certifikátu vyžaduje reštart systému a ešte pred načítaním jadra operačného systému ponúka správcovi povoliť načítanie nového certifikátu.

Tým pádom pridanie certifikátu vyžaduje fyzický prístup správcu k systému. Ak je stroj umiestnený niekde v cloude alebo len na vzdialenom serveri a prístup je iba cez sieť (napríklad cez ssh), nebude možné pridať certifikát.

EFI na virtuálnych strojoch

Napriek tomu, že už dávno EFI podporuje takmer všetci výrobcovia základných dosiek, pri inštalácii systému si správca nemusí uvedomiť potrebu EFI a môže byť vypnuté.

Nie všetky hypervízory podporujú EFI. VMWare vSphere podporuje EFI od verzie 5.
Microsoft Hyper-V tiež získal podporu EFI, počnúc Hyper-V pre Windows Server 2012R2.

Avšak v predvolenej konfigurácii je táto funkcia pre Linux stroje vypnutá, a preto certifikát nie je možné nainštalovať.

Vo vSphere 6.5 je možné nastaviť možnosť Secure Boot iba v staršej verzii webového rozhrania, ktoré funguje cez Flash. Webové rozhranie na HTML-5 zatiaľ zaostáva.

Experimentálne distribúcie

A nakoniec sa pozrime na otázku experimentálnych distribúcií a distribúcií bez oficiálnej podpory. Na jednej strane takéto distribúcie sotva narazíte na serveroch vážnych organizácií. Oficiálnu podporu takéto distribúcie nemajú. Preto tiež nie je možné poskytovať technickú podporu produktu na takýchto distribúciách.

Avšak takéto distribúcie sa stávajú pohodlnou platformou na vyskúšanie nových experimentálnych riešení. Napríklad Fedora, OpenSUSE Tumbleweed alebo Unstable verzie Debiana. Sú pomerne stabilné. Vždy obsahujú nové verzie programov a vždy nové jadro. O rok môže byť táto experimentálna funkcia zahrnutá v aktualizovanom RHEL, SLES alebo Ubuntu.

Takže ak niečo nefunguje na experimentálnej distribúcii — je to dôvod na preskúmanie problému a jeho riešenie. Je potrebné byť pripravený na to, že táto funkcia sa čoskoro objaví na production serveroch používateľov.

Aktuálny zoznam oficiálne podporovaných distribúcií pre verziu 3.0 si môžete prezrieť tu. Avšak skutočný zoznam distribúcií, na ktorých náš produkt dokáže fungovať, je oveľa širší.

Osobne ma zaujímal experiment s OS «Elbrus». Po úprave balíka Veeam sa náš produkt nainštaloval a fungoval. O tomto experimente som písal na Habre v článku.

Podpora nových distribúcií pokračuje. Očakávame príchod verzie 4.0. Beta verzia by sa mala čoskoro objaviť, tak sledujte whats-new!

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster