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

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

Vytvorenie zálohovacej aplikácie, ktorá funguje na akejkoľvek distribúcii, nie je ľahká úloha. Ak chcete zabezpečiť, aby Veeam Agent pre Linux fungoval na distribúciách od Red Hat 6 a Debian 6 až po OpenSUSE 15.1 a Ubuntu 19.04, musíte vyriešiť celý rad problémov, najmä ak vezmeme do úvahy, že softvérový produkt obsahuje modul jadra.

Článok vznikol na základe materiálov z prejavu na konferencii Linux Peter 2019.

Linux nie je len jedným z najpopulárnejších operačných systémov. V podstate ide o platformu, na základe ktorej môžete vytvoriť niečo jedinečné, niečo vlastné. Vďaka tomu má Linux mnoho distribúcií, ktoré sa líšia v súbore softvérových komponentov. A tu vzniká problém: na to, aby softvérový produkt fungoval v akejkoľvek distribúcii, musíte brať do úvahy vlastnosti každej z nich.

Správcovia balíkov. .deb vs. .rpm

Začnime zrejmým problémom distribúcie produktu cez rôzne distribúcie.
Najtypickejším spôsobom distribúcie softvérových produktov je umiestniť balík do úložiska, aby ho odtiaľ mohol nainštalovať správca balíkov zabudovaný v systéme.
Máme však dva populárne formáty balíkov: rpm и deb. To znamená, že každý bude musieť podporiť.

Vo svete deb balíkov je úroveň kompatibility úžasná. Rovnaký balík sa inštaluje a funguje rovnako dobre na Debiane 6 a Ubuntu 19.04. Štandardy pre proces vytvárania balíkov a prácu s nimi, stanovené v starých distribúciách Debianu, zostávajú relevantné v novom Linux Mint a základnom OS. Preto v prípade Veeam Agent pre Linux stačí jeden deb balík pre každú hardvérovú platformu.

Ale vo svete rpm balíkov sú rozdiely veľké. Jednak kvôli tomu, že existujú dvaja úplne nezávislí distribútori, Red Hat a SUSE, pre ktorých je kompatibilita úplne zbytočná. Po druhé, títo distribútori majú distribučné súpravy od nich. podporné a experimentálne. Ani medzi nimi nie je potrebná kompatibilita. Ukázalo sa, že el6, el7 a el8 majú svoje vlastné balíčky. Samostatný balík pre Fedoru. Balíky pre SLES11 a 12 a samostatný pre openSUSE. Hlavným problémom sú závislosti a názvy balíkov.

Problém závislosti

Bohužiaľ, rovnaké balíčky často končia pod rôznymi názvami v rôznych distribúciách. Nižšie je uvedený čiastočný zoznam závislostí balíkov veeam.

Pre EL7:
Pre SLES 12:

  • libblkid
  • libgcc
  • libstdc++
  • ncurses-libs
  • poistka-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 aktualizovaná verzia začne skrývať pod starým názvom balíka.

Príklad:

Balík bol aktualizovaný vo Fedore 24 nkurzy od verzie 5 po verziu 6. Náš produkt bol zostavený s verziou 5, aby bola zaistená kompatibilita so staršími distribúciami. Aby som mohol použiť starú 5. verziu knižnice na Fedore 24, musel som použiť balík ncurses-compat-libs.

Výsledkom sú dva balíčky pre Fedoru s rôznymi závislosťami.

Ďalej zaujímavejšie. Po ďalšej aktualizácii distribúcie balík ncurses-compat-libs s verziou 5 knižnice sa ukáže, že nie je k dispozícii. Pre distribútora je drahé pretiahnuť staré knižnice do novej verzie distribúcie. Po určitom čase sa problém zopakoval v distribúciách SUSE.

Výsledkom bolo, že niektoré distribúcie museli opustiť svoju explicitnú závislosť ncurses-libsa opravte produkt tak, aby fungoval s akoukoľvek verziou knižnice.

Mimochodom, vo verzii 8 Red Hat už nie je meta balík krajta, ktorý odkazoval na staré dobré python 2.7, Tam je python2 и krajta3.

Alternatíva k správcom balíkov

Problém so závislosťami je starý a dlho zrejmý. Len si spomeňte na Dependency hell.
Skombinovať rôzne knižnice a aplikácie tak, aby všetky fungovali stabilne a nekolidovali – to je v skutočnosti úloha, ktorú sa snaží vyriešiť každý distribútor Linuxu.

Správca balíkov sa snaží tento problém vyriešiť úplne iným spôsobom. kúsavý od spoločnosti Canonical. Hlavná myšlienka: aplikácia beží v izolovanom priestore izolovanom od hlavného systému. Ak aplikácia vyžaduje knižnice, sú dodávané so samotnou aplikáciou.

Flatpak tiež umožňuje spúšťať aplikácie v karanténe pomocou Linuxových kontajnerov. Používa sa aj myšlienka pieskoviska AppImage.

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

Hlavným problémom je, že nie všetky aplikácie môžu bežať v karanténe. Niektorí ľudia potrebujú priamy prístup k platforme. O moduloch jadra, ktoré sú striktne závislé od jadra a nezapadajú do konceptu sandboxu, ani nehovorím.

Druhým problémom je, že distribúcie populárne v podnikovom prostredí od Red Hat a SUSE zatiaľ neobsahujú podporu pre Snappy a Flatpak.

V tomto ohľade Veeam Agent pre Linux nie je k dispozícii snapcraft.io nie zapnuté flathub.org.

Na záver otázky o správcoch balíkov by som rád poznamenal, že existuje možnosť úplne opustiť správcov balíkov spojením binárnych súborov a skriptu na ich inštaláciu do jedného balíka.

Takýto balík vám umožňuje vytvoriť jeden spoločný balík pre rôzne distribúcie a platformy, vykonať interaktívny inštalačný proces a vykonať potrebné prispôsobenie. S takýmito balíkmi pre Linux som sa stretol len od VMware.

Problém s aktualizáciou

Linux má mnoho tvárí: ako pracovať na akejkoľvek distribúcii
Aj keď sú všetky problémy so závislosťami vyriešené, program môže v rovnakej distribúcii bežať odlišne. Je to otázka aktualizácií.

Existujú 3 stratégie aktualizácie:

  • Najjednoduchšie je nikdy neaktualizovať. Nastavil som server a zabudol som na to. Prečo aktualizovať, ak všetko funguje? Problémy začínajú pri prvom kontaktovaní podpory. Tvorca distribúcie podporuje iba aktualizované vydanie.
  • Distribútorovi môžete dôverovať a nastaviť automatické aktualizácie. V tomto prípade je volanie podpory pravdepodobne ihneď po neúspešnej aktualizácii.
  • Možnosť manuálnej aktualizácie až po spustení na testovacej infraštruktúre je najspoľahlivejšia, ale drahá a časovo náročná. 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 predtým vydané. To komplikuje proces vývoja aj testovania a pridáva podpornému tímu bolesti hlavy.

Rôzne hardvérové ​​platformy

Rôzne hardvérové ​​platformy predstavujú problém, ktorý je do značnej miery špecifický pre natívny kód. Minimálne musíte zbierať binárne súbory pre každú podporovanú platformu.

V projekte Veeam Agent for Linux stále nemôžeme podporovať nič podobné ako tento RISC.

Nebudem sa touto problematikou podrobne zaoberať. Načrtnem len hlavné problémy: platformovo závislé typy, ako napr size_t, zarovnanie štruktúry a poradie bajtov.

Statické a/alebo dynamické prepojenie

Linux má mnoho tvárí: ako pracovať na akejkoľvek distribúcii
Otázka však znie: „Ako sa prepojiť s knižnicami – dynamicky alebo staticky? stojí za diskusiu.

Aplikácie C/C++ pod Linuxom spravidla používajú dynamické prepojenie. Funguje to skvele, ak je aplikácia vytvorená špeciálne pre konkrétnu distribúciu.

Ak je úlohou pokryť rôzne distribúcie jedným binárnym súborom, potom sa musíte zamerať na najstaršiu podporovanú distribúciu. Pre nás je to Red Hat 6. Obsahuje gcc 4.4, ktorý ani štandard C++11 nepodporuje plne.

Náš projekt staviame pomocou gcc 6.3, ktorý plne podporuje C++14. Prirodzene, v tomto prípade na Red Hat 6 musíte mať so sebou knižnice libstdc++ a boost. Najjednoduchšie je na ne odkazovať staticky.

Ale bohužiaľ, nie všetky knižnice môžu byť prepojené staticky.

Jednak systémové knižnice ako napr libfuse, libblkid je potrebné dynamicky prepájať, aby bola zabezpečená ich kompatibilita s jadrom a jeho modulmi.

Po druhé, je tu jemnosť s licenciami.

Licencia GPL v podstate umožňuje prepojiť knižnice iba s opensource kódom. MIT a BSD umožňujú statické prepojenie a umožňujú začlenenie knižníc do projektu. Ale zdá sa, že LGPL nie je v rozpore so statickým prepojením, ale vyžaduje, aby boli súbory potrebné na prepojenie zdieľané.

Vo všeobecnosti vám používanie dynamického prepojenia zabráni nutnosti poskytovať čokoľvek.

Vytváranie aplikácií C/C++

Na zostavenie C/C++ aplikácií pre rôzne platformy a distribúcie stačí vybrať alebo zostaviť vhodnú verziu gcc a použiť krížové kompilátory pre konkrétne architektúry a zostaviť celú sadu knižníc. Táto práca je celkom uskutočniteľná, ale dosť problematická. A neexistuje žiadna záruka, že vybraný kompilátor a knižnice poskytnú funkčnú verziu.

Zjavná výhoda: infraštruktúra je výrazne zjednodušená, pretože celý proces zostavovania je možné dokončiť na jednom stroji. Navyše stačí nazbierať jednu sadu binárok pre jednu architektúru a môžete ich zabaliť do balíkov pre rôzne distribúcie. Takto sa vytvárajú balíčky veeam pre Veeam Agent pre Linux.

Na rozdiel od tejto možnosti môžete jednoducho pripraviť zostavu farmy, to znamená niekoľko strojov na montáž. Každý takýto stroj zabezpečí kompiláciu aplikácií a zostavenie balíkov pre konkrétnu distribúciu a špecifickú architektúru. V tomto prípade sa kompilácia vykonáva pomocou prostriedkov pripravených distribútorom. To znamená, že fáza prípravy kompilátora a výberu knižníc odpadá. Okrem toho je možné proces zostavovania jednoducho paralelizovať.

Tento prístup má však aj nevýhodu: pre každú distribúciu v rámci rovnakej architektúry budete musieť zhromaždiť vlastnú sadu binárnych súborov. Ďalšou nevýhodou je, že je potrebné udržiavať taký veľký počet strojov a alokovať veľké množstvo miesta na disku a RAM.

Takto sa kompilujú balíčky KMOD modulu jadra veeamsnap pre distribúcie Red Hat.

Otvorte službu Build Service

Kolegovia zo SUSE sa pokúsili implementovať strednú cestu v podobe špeciálnej služby na zostavovanie aplikácií a zostavovanie balíkov - openbuildservice.

V podstate ide o hypervízor, ktorý vytvorí virtuálny stroj, nainštaluje do neho všetky potrebné balíčky, skompiluje aplikáciu a zostaví balíček v tomto izolovanom prostredí, po čom sa virtuálny stroj uvoľní.

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

Plánovač implementovaný v OpenBuildService určí, koľko virtuálnych strojov môže spustiť pre optimálnu rýchlosť vytvárania balíkov. Vstavaný mechanizmus podpisovania podpíše balíčky a nahrá ich do vstavaného úložiska. Zabudovaný systém správy verzií uloží históriu zmien a zostavení. Zostáva len jednoducho pridať svoje zdroje do tohto systému. Server si nemusíte ani nastavovať sami, môžete použiť otvorený.

Je tu však problém: takýto kombajn je ťažké začleniť do existujúcej infraštruktúry. Napríklad nie je potrebná kontrola verzií, na zdrojové kódy už máme vlastné. Náš podpisový mechanizmus je iný: používame špeciálny server. Úložisko tiež nie je potrebné.

Navyše podpora iných distribúcií – napríklad Red Hat – je implementovaná dosť zle, čo je pochopiteľné.

Výhodou takejto služby je rýchla podpora ďalšej verzie distribúcie SUSE. Pred oficiálnym oznámením vydania sú balíčky potrebné na zostavenie zverejnené na verejnom úložisku. V zozname dostupných distribúcií na OpenBuildService sa objaví nová. Začiarkneme políčko a pridá sa do plánu stavby. Pridanie novej verzie distribúcie teda prebieha takmer jedným kliknutím.

V našej infraštruktúre je pomocou OpenBuildService zostavená celá škála balíkov KMP modulu jadra veeamsnap pre distribúcie SUSE.

Ďalej by som sa chcel venovať problémom špecifickým pre moduly jadra.

jadro ABI

Moduly jadra Linuxu boli historicky distribuované v zdrojovej forme. Faktom je, že tvorcovia jadra sa nezaťažujú starosťou o podporu stabilného API pre moduly jadra, a to najmä na binárnej úrovni, ďalej označovanej ako kABI.

Na zostavenie modulu pre vanilkové jadro určite potrebujete hlavičky tohto konkrétneho jadra a bude fungovať len na tomto jadre.

DKMS vám umožňuje automatizovať proces vytvárania modulov pri aktualizácii jadra. Výsledkom je, že používatelia úložiska Debian (a jeho mnohí príbuzní) používajú moduly jadra buď z úložiska distribútora, alebo kompilované zo zdroja pomocou DKMS.

Táto situácia však nevyhovuje najmä segmentu Enterprise. Distribútori proprietárneho kódu chcú distribuovať produkt ako kompilované binárne súbory.

Správcovia nechcú ponechať vývojové nástroje na produkčných serveroch z bezpečnostných dôvodov. Enterprise Linux distribútori ako Red Hat a SUSE sa rozhodli, že by mohli podporovať stabilné kABI pre svojich používateľov. Výsledkom boli balíčky KMOD pre Red Hat a balíčky KMP pre SUSE.

Podstata tohto riešenia je celkom jednoduchá. Pre konkrétnu verziu distribúcie je rozhranie API jadra zmrazené. Distribútor uvádza, že používa jadro, napríklad 3.10, a robí len opravy a vylepšenia, ktoré neovplyvňujú rozhrania jadra, a moduly zozbierané pre úplne prvé jadro je možné použiť pre všetky nasledujúce bez rekompilácie.

Red Hat tvrdí, že distribúcia je kompatibilná s kABI počas celého životného cyklu. To znamená, že zostavený modul pre rhel 6.0 (vydanie v novembri 2010) by mal fungovať aj na verzii 6.10 (vydanie v júni 2018). A to je takmer 8 rokov. Prirodzene, táto úloha je dosť náročná.
Zaznamenali sme niekoľko prípadov, kedy modul veeamsnap prestal fungovať kvôli problémom s kompatibilitou kABI.

Keď sa modul veeamsnap, skompilovaný pre RHEL 7.0, ukázal ako nekompatibilný s jadrom z RHEL 7.5, ale načítal sa a bolo zaručené, že zrúti server, úplne sme upustili od používania kompatibility kABI pre RHEL 7.

V súčasnosti balík KMOD pre RHEL 7 obsahuje zostavu pre každú verziu vydania a skript, ktorý načíta modul.

SUSE pristupovalo k úlohe kompatibility kABI opatrnejšie. Poskytujú kompatibilitu kABI iba v rámci jedného balíka Service Pack.

Napríklad vydanie SLES 12 sa uskutočnilo v septembri 2014. A SLES 12 SP1 už bolo v decembri 2015, to znamená, že uplynulo niečo viac ako rok. Aj keď obe vydania používajú jadro 3.12, sú nekompatibilné s kABI. Je zrejmé, že udržiavanie kompatibility s kABI len jeden rok je oveľa jednoduchšie. Ročný cyklus aktualizácie modulov jadra by tvorcom modulov nemal spôsobovať problémy.

V dôsledku tejto politiky SUSE sme nezaznamenali jediný problém s kompatibilitou kABI v našom module veeamsnap. Je pravda, že počet balíkov pre SUSE je takmer o rád väčší.

Opravy a zadné porty

Hoci sa distribútori snažia zabezpečiť kompatibilitu kABI a stabilitu jadra, snažia sa tiež zlepšiť výkon a odstrániť chyby tohto stabilného jadra.

Vývojári podnikového linuxového jadra zároveň okrem vlastnej „práce na chybách“ monitorujú zmeny v jadre vanilla a prenášajú ich do svojho „stabilného“.

Niekedy to vedie k novým chyby.

V najnovšom vydaní Red Hat 6 sa stala chyba v jednej z menších aktualizácií. Viedlo to k tomu, že modul veeamsnap zaručene zrúti systém pri uvoľnení snímky. Po porovnaní zdrojov jadra pred a po aktualizácii sme zistili, že na vine je backport. Podobná oprava bola vykonaná vo verzii vanilkového jadra 4.19. Je to tak, že táto oprava fungovala dobre vo vanilkovom jadre, ale pri jej prenose do „stabilnej“ verzie 2.6.32 nastal problém so spinlockom.

Samozrejme, každý má vždy chyby, ale stálo za to pretiahnuť kód z 4.19 na 2.6.32, riskovať stabilitu?.. Nie som si istý...

Najhoršie je, keď sa marketing zapojí do ťahaníc medzi „stabilitou“ a „modernizáciou“. Marketingové oddelenie potrebuje, aby jadro aktualizovanej distribúcie bolo na jednej strane stabilné a zároveň výkonovo lepšie a malo nové funkcie. To vedie k zvláštnym kompromisom.

Keď som sa pokúsil postaviť modul na jadre 4.4 zo SLES 12 SP3, prekvapilo ma, že som v ňom našiel funkčnosť z vanilky 4.8. Podľa môjho názoru je bloková I/O implementácia jadra 4.4 zo SLES 12 SP3 viac podobná jadru 4.8 ako predchádzajúce vydanie stabilného jadra 4.4 zo SLES12 SP2. Nemôžem posúdiť, koľko percent kódu bolo prenesených z jadra 4.8 do SLES 4.4 pre SP3, ale nemôžem ani nazvať jadro rovnako stabilné 4.4.

Najnepríjemnejšie na tom je, že pri písaní modulu, ktorý by fungoval rovnako dobre na rôznych jadrách, sa už nemôžete spoliehať na verziu jadra. Musíte tiež vziať do úvahy distribúciu. Je dobré, že sa niekedy môžete zapojiť do definície, ktorá sa objaví spolu s novou funkcionalitou, ale táto príležitosť sa nie vždy objaví.

Výsledkom je, že kód zarastá podivnými direktívami podmienenej kompilácie.

Existujú aj záplaty, ktoré menia zdokumentované kernel API.
Narazil som na distribúciu KDE neón 5.16 a bol veľmi prekvapený, že volanie lookup_bdev v tejto verzii jadra zmenilo zoznam vstupných parametrov.

Aby som to dal dokopy, musel som do makefile pridať skript, ktorý kontroluje, či funkcia lookup_bdev má parameter mask.

Podpisovanie modulov jadra

Vráťme sa však k problematike distribúcie balíkov.

Jednou z výhod stabilného kABI je, že moduly jadra môžu byť podpísané ako binárny súbor. V tomto prípade si môže byť vývojár istý, že modul nebol náhodne poškodený alebo úmyselne upravený. Môžete to skontrolovať pomocou príkazu modinfo.

Distribúcie Red Hat a SUSE vám umožňujú skontrolovať podpis modulu a načítať ho iba vtedy, ak je v systéme zaregistrovaný príslušný certifikát. Certifikát je verejný kľúč, ktorým je modul podpísaný. Distribuujeme ako samostatný balík.

Problém je v tom, že certifikáty môžu byť zabudované do jadra (používajú ich distribútori) alebo musia byť zapísané do energeticky nezávislej pamäte EFI pomocou pomôcky mokutil. Utility 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 vyzve administrátora, aby povolil načítanie nového certifikátu.

Pridanie certifikátu teda vyžaduje fyzický administrátorský prístup do systému. Ak je stroj umiestnený niekde v cloude alebo jednoducho vo vzdialenej serverovni a prístup je len cez sieť (napríklad cez ssh), potom nebude možné pridať certifikát.

EFI na virtuálnych strojoch

Napriek tomu, že EFI už dlho podporujú takmer všetci výrobcovia základných dosiek, pri inštalácii systému nemusí administrátor myslieť na potrebu EFI a môže byť zakázaný.

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.

V predvolenej konfigurácii je však táto funkcia pre počítače so systémom Linux zakázaná, čo znamená, že certifikát nie je možné nainštalovať.

Vo vSphere 6.5 nastavte túto možnosť Secure Boot možné len v starej verzii webového rozhrania, ktoré beží cez Flash. Webové používateľské rozhranie na HTML-5 je stále ďaleko.

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 je nepravdepodobné, že by sa takéto distribúcie našli na serveroch serióznych organizácií. Pre takéto distribúcie neexistuje žiadna oficiálna podpora. Preto ich poskytnite. Produkt nemôže byť podporovaný v takejto distribúcii.

Takéto distribúcie sa však stávajú vhodnou platformou na skúšanie nových experimentálnych riešení. Napríklad Fedora, OpenSUSE Tumbleweed alebo Unstable verzie Debianu. Sú celkom stabilné. Vždy majú nové verzie programov a vždy nové jadro. O rok môže táto experimentálna funkcionalita skončiť v aktualizovanom RHEL, SLES alebo Ubuntu.

Takže ak niečo nefunguje na experimentálnej distribúcii, je to dôvod na to, aby ste problém zistili a vyriešili. Musíte byť pripravení na to, že táto funkcia sa čoskoro objaví na produkčných serveroch používateľov.

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

Osobne ma zaujal experiment s OS Elbrus. Po dokončení balíka veeam bol náš produkt nainštalovaný a funkčný. O tomto experimente som písal na Habré v r článok.

Podpora nových distribúcií pokračuje. Čakáme na vydanie verzie 4.0. Beta sa čoskoro objaví, takže sledujte čo je nové!

Zdroj: hab.com

Pridať komentár