Linux ima veliko obrazov: kako delati na kateri koli distribuciji

Linux ima veliko obrazov: kako delati na kateri koli distribuciji

Ustvarjanje aplikacije za varnostno kopiranje, ki deluje na kateri koli distribuciji, ni lahka naloga. Če želite zagotoviti, da Veeam Agent za Linux deluje v distribucijah od Red Hat 6 in Debian 6 do OpenSUSE 15.1 in Ubuntu 19.04, morate rešiti vrsto težav, zlasti glede na to, da programski izdelek vključuje modul jedra.

Članek je nastal na podlagi gradiva iz govora na konferenci Linux Peter 2019.

Linux ni samo eden izmed najbolj priljubljenih operacijskih sistemov. V bistvu je to platforma, na podlagi katere lahko narediš nekaj unikatnega, nekaj svojega. Zahvaljujoč temu ima Linux veliko distribucij, ki se razlikujejo po naboru programskih komponent. In tu se pojavi težava: da bi programski izdelek deloval v kateri koli distribuciji, morate upoštevati značilnosti vsake.

Upravljavci paketov. .deb proti .rpm

Začnimo z očitnim problemom distribucije izdelka v različnih distribucijah.
Najbolj tipičen način za distribucijo programskih izdelkov je, da paket postavite v repozitorij, tako da ga lahko upravitelj paketov, ki je vgrajen v sistem, od tam namesti.
Vendar pa imamo dve priljubljeni obliki paketov: rpm и deb. To pomeni, da bodo morali podpirati vsi.

V svetu paketov deb je raven združljivosti neverjetna. Isti paket se namesti in enako dobro deluje v obeh sistemih Debian 6 in Ubuntu 19.04. Standardi za proces gradnje paketov in delo z njimi, določeni v starih distribucijah Debian, ostajajo pomembni v novodobnem Linux Mintu in osnovnem OS. Zato v primeru Veeam Agent za Linux zadostuje en paket deb za vsako platformo strojne opreme.

Toda v svetu paketov rpm so razlike velike. Prvič, zaradi dejstva, da obstajata dva popolnoma neodvisna distributerja, Red Hat in SUSE, za katera je združljivost popolnoma nepotrebna. Drugič, ti distributerji imajo distribucijske komplete od teh. podporno in eksperimentalno. Tudi združljivost med njimi ni potrebna. Izkazalo se je, da imajo el6, el7 in el8 svoje pakete. Ločen paket za Fedoro. Paketi za SLES11 in 12 ter ločen paket za openSUSE. Glavna težava so odvisnosti in imena paketov.

Problem odvisnosti

Na žalost se isti paketi v različnih distribucijah pogosto znajdejo pod različnimi imeni. Spodaj je delni seznam odvisnosti od paketa veeam.

Za EL7:
Za SLES 12:

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

Posledično je seznam odvisnosti edinstven za distribucijo.

Še huje pa je, ko se posodobljena različica začne skrivati ​​pod starim imenom paketa.

Primer:

Paket je bil posodobljen v Fedori 24 ncurses od različice 5 do različice 6. Naš izdelek je bil zgrajen z različico 5, da se zagotovi združljivost s starejšimi distribucijami. Za uporabo stare 5. različice knjižnice v Fedori 24 sem moral uporabiti paket ncurses-compat-libs.

Posledično obstajata dva paketa za Fedoro z različnimi odvisnostmi.

Nadalje bolj zanimivo. Po naslednji posodobitvi distribucije paket ncurses-compat-libs z različico 5 knjižnice se izkaže, da ni na voljo. Za distributerja je drago prenesti stare knjižnice v novo različico distribucije. Čez nekaj časa se je težava ponovila v distribucijah SUSE.

Posledično so morale nekatere distribucije opustiti svojo izrecno odvisnost od ncurses-libsin popravite izdelek, tako da bo lahko deloval s katero koli različico knjižnice.

Mimogrede, v različici 8 Red Hat ni več meta paketa python, ki se je nanašala na dobre stare pyton 2.7. Obstaja python2 и python3.

Alternativa upraviteljem paketov

Težava z odvisnostmi je stara in že dolgo očitna. Spomnite se pekla odvisnosti.
Združiti različne knjižnice in aplikacije, tako da vse delujejo stabilno in niso v nasprotju - pravzaprav je to naloga, ki jo poskuša rešiti vsak distributer Linuxa.

Upravitelj paketov poskuša to težavo rešiti na povsem drugačen način. Snappy od Canonical. Glavna ideja: aplikacija deluje v peskovniku, izoliranem in zaščitenem od glavnega sistema. Če aplikacija zahteva knjižnice, so te priložene sami aplikaciji.

Flatpak omogoča tudi izvajanje aplikacij v peskovniku z uporabo vsebnikov Linux. Uporabljena je tudi ideja peskovnika AppImage.

Te rešitve vam omogočajo, da ustvarite en paket za katero koli distribucijo. V primeru Flatpak namestitev in zagon aplikacije je možen tudi brez vednosti skrbnika.

Glavna težava je, da se vse aplikacije ne morejo izvajati v peskovniku. Nekateri ljudje potrebujejo neposreden dostop do platforme. Sploh ne govorim o modulih jedra, ki so strogo odvisni od jedra in ne sodijo v koncept peskovnika.

Druga težava je, da distribucije Red Hat in SUSE, priljubljene v poslovnem okolju, še ne vsebujejo podpore za Snappy in Flatpak.

V zvezi s tem Veeam Agent za Linux ni na voljo snapcraft.io sploh ne flathub.org.

Za zaključek vprašanja o upraviteljih paketov bi rad omenil, da obstaja možnost, da upravitelje paketov v celoti opustimo tako, da združimo binarne datoteke in skript za njihovo namestitev v en paket.

Tak sveženj vam omogoča, da ustvarite en skupni paket za različne distribucije in platforme, izvedete interaktivni postopek namestitve in izvedete potrebno prilagoditev. Take pakete za Linux sem srečal le pri VMware.

Težava s posodobitvijo

Linux ima veliko obrazov: kako delati na kateri koli distribuciji
Tudi če so vse težave z odvisnostjo odpravljene, se lahko program na isti distribuciji izvaja drugače. Gre za posodobitve.

Obstajajo 3 strategije posodabljanja:

  • Najenostavnejši je, da nikoli ne posodobite. Nastavil sem strežnik in pozabil nanj. Zakaj posodabljati, če vse deluje? Težave se začnejo, ko prvič kontaktirate podporo. Ustvarjalec distribucije podpira samo posodobljeno izdajo.
  • Lahko zaupate distributerju in nastavite samodejne posodobitve. V tem primeru je klic podpore verjetno takoj po neuspešni posodobitvi.
  • Možnost ročnega posodabljanja šele po zagonu na testni infrastrukturi je najbolj zanesljiva, vendar draga in dolgotrajna. Ne more si ga privoščiti vsak.

Ker različni uporabniki uporabljajo različne strategije posodabljanja, je treba podpirati tako zadnjo izdajo kot vse prejšnje izdaje. To otežuje tako razvojni kot testni proces in povzroča preglavice ekipi za podporo.

Raznolikost platform strojne opreme

Različne platforme strojne opreme so problem, ki je v veliki meri specifičen za domačo kodo. Zbrati morate najmanj binarne datoteke za vsako podprto platformo.

V projektu Veeam Agent for Linux še vedno ne moremo podpreti ničesar podobnega temu RISC.

Ne bom se podrobneje ukvarjal s tem vprašanjem. Omenil bom le glavne težave: platformno odvisne vrste, kot npr size_t, poravnavo strukture in vrstni red bajtov.

Statično in/ali dinamično povezovanje

Linux ima veliko obrazov: kako delati na kateri koli distribuciji
Toda vprašanje je "Kako se povezati s knjižnicami - dinamično ali statično?" vredno razprave.

Praviloma aplikacije C/C++ pod Linuxom uporabljajo dinamično povezovanje. To deluje odlično, če je aplikacija izdelana posebej za določeno distribucijo.

Če je naloga pokriti različne distribucije z eno binarno datoteko, se morate osredotočiti na najstarejšo podprto distribucijo. Za nas je to Red Hat 6. Vsebuje gcc 4.4, ki ga ne podpira niti standard C++11 celoti.

Naš projekt gradimo z uporabo gcc 6.3, ki v celoti podpira C++14. Seveda morate v tem primeru v Red Hat 6 s seboj nositi knjižnice libstdc++ in boost. Najlažji način je, da se nanje povežete statično.

Ampak žal, vseh knjižnic ni mogoče statično povezati.

Prvič, sistemske knjižnice, kot je npr libfuse, libblkid potrebno je dinamično povezovanje, da se zagotovi njihova združljivost z jedrom in njegovimi moduli.

Drugič, pri licencah je subtilnost.

Licenca GPL v bistvu omogoča povezovanje knjižnic samo z odprtokodno kodo. MIT in BSD omogočata statično povezovanje in omogočata vključitev knjižnic v projekt. Vendar se zdi, da LGPL ne nasprotuje statičnemu povezovanju, ampak zahteva, da se datoteke, potrebne za povezovanje, delijo.

Na splošno vam uporaba dinamičnega povezovanja prepreči, da bi morali kar koli zagotoviti.

Gradnja aplikacij C/C++

Za izdelavo aplikacij C/C++ za različne platforme in distribucije je dovolj, da izberete ali zgradite ustrezno različico gcc in uporabite navzkrižne prevajalnike za specifične arhitekture ter sestavite celoten nabor knjižnic. To delo je precej izvedljivo, vendar precej težavno. In ni nobenega zagotovila, da bodo izbrani prevajalnik in knjižnice zagotovili delujočo različico.

Očitna prednost: infrastruktura je zelo poenostavljena, saj je celoten proces gradnje mogoče dokončati na enem stroju. Poleg tega je dovolj, da zberete en niz binarnih datotek za eno arhitekturo in jih lahko pakirate v pakete za različne distribucije. Tako so zgrajeni paketi veeam za Veeam Agent za Linux.

V nasprotju s to možnostjo lahko preprosto pripravite gradbeno kmetijo, to je več strojev za montažo. Vsak tak stroj bo zagotovil prevajanje aplikacije in sestavljanje paketa za določeno distribucijo in specifično arhitekturo. V tem primeru se zbiranje izvede s sredstvi, ki jih pripravi distributer. To pomeni, da je odpravljena faza priprave prevajalnika in izbire knjižnic. Poleg tega je mogoče postopek gradnje enostavno vzporediti.

Vendar pa obstaja slaba stran tega pristopa: za vsako distribucijo znotraj iste arhitekture boste morali zbrati svoj nabor binarnih datotek. Druga pomanjkljivost je, da je treba vzdrževati tako veliko število strojev in dodeliti veliko prostora na disku in RAM-a.

Tako so paketi KMOD modula jedra veeamsnap prevedeni za distribucije Red Hat.

Odprite Build Service

Kolegi iz SUSE so poskušali implementirati neko srednjo pot v obliki posebne storitve za prevajanje aplikacij in sestavljanje paketov - openbuildservice.

V bistvu gre za hipervizor, ki ustvari virtualni stroj, vanj namesti vse potrebne pakete, prevede aplikacijo in zgradi paket v tem izoliranem okolju, nato pa se virtualni stroj sprosti.

Linux ima veliko obrazov: kako delati na kateri koli distribuciji

Razporejevalnik, implementiran v OpenBuildService, bo določil, koliko virtualnih strojev lahko zažene za optimalno hitrost gradnje paketov. Vgrajen mehanizem za podpisovanje bo podpisal pakete in jih naložil v vgrajeno skladišče. Vgrajeni sistem za nadzor različic bo shranil zgodovino sprememb in gradenj. Vse kar ostane je, da preprosto dodate svoje vire v ta sistem. Strežnika vam sploh ni treba nastaviti sami, lahko uporabite odprtega.

Obstaja pa težava: tak kombajn je težko vklopiti v obstoječo infrastrukturo. Na primer, nadzor različic ni potreben; že imamo svojo lastno izvorno kodo. Naš mehanizem podpisovanja je drugačen: uporabljamo poseben strežnik. Repozitorij tudi ni potreben.

Poleg tega je podpora za druge distribucije - na primer Red Hat - implementirana precej slabo, kar je razumljivo.

Prednost takšne storitve je hitra podpora za naslednjo različico distribucije SUSE. Pred uradno objavo izdaje so paketi, potrebni za sestavljanje, objavljeni v javnem skladišču. Nova se pojavi na seznamu razpoložljivih distribucij na OpenBuildService. Označimo polje in dodamo ga v načrt gradnje. Tako je dodajanje nove različice distribucije opravljeno s skoraj enim klikom.

V naši infrastrukturi je z uporabo OpenBuildService sestavljena celotna paleta paketov KMP modula jedra veeamsnap za distribucije SUSE.

Nato bi se rad osredotočil na vprašanja, značilna za module jedra.

jedro ABI

Moduli jedra Linuxa so bili v preteklosti distribuirani v izvorni obliki. Dejstvo je, da se ustvarjalci jedra ne obremenjujejo s skrbjo za podporo stabilnega API-ja za module jedra, predvsem pa na binarni ravni, v nadaljevanju kABI.

Če želite zgraditi modul za vanilla jedro, zagotovo potrebujete glave tega posebnega jedra in bo deloval samo na tem jedru.

DKMS vam omogoča avtomatizacijo postopka gradnje modulov pri posodabljanju jedra. Posledično uporabniki repozitorija Debian (in njegovih številnih sorodnikov) uporabljajo module jedra iz distributerjevega repozitorija ali prevedene iz izvorne kode z uporabo DKMS.

Vendar ta situacija ne ustreza posebej segmentu Enterprise. Distributerji lastniške kode želijo izdelek distribuirati kot prevedene binarne datoteke.

Skrbniki ne želijo imeti razvojnih orodij na produkcijskih strežnikih zaradi varnosti. Distributerji Linuxa za podjetja, kot sta Red Hat in SUSE, so se odločili, da lahko podpirajo stabilen kABI za svoje uporabnike. Rezultat so bili paketi KMOD za Red Hat in paketi KMP za SUSE.

Bistvo te rešitve je povsem preprosto. Za določeno različico distribucije je API jedra zamrznjen. Distributer navaja, da uporablja jedro, na primer 3.10, in izvaja le popravke in izboljšave, ki ne vplivajo na vmesnike jedra, module, zbrane za prvo jedro, pa je mogoče uporabiti za vse naslednje brez ponovnega prevajanja.

Red Hat trdi, da je združljivost kABI za distribucijo v celotnem življenjskem ciklu. To pomeni, da bi moral sestavljeni modul za rhel 6.0 (izdaja november 2010) delovati tudi na različici 6.10 (izdaja junij 2018). In to je skoraj 8 let. Seveda je ta naloga precej težka.
Zabeležili smo več primerov, ko je modul veeamsnap prenehal delovati zaradi težav z združljivostjo kABI.

Potem ko se je izkazalo, da modul veeamsnap, preveden za RHEL 7.0, ni združljiv z jedrom iz RHEL 7.5, vendar se je naložil in je bilo zagotovljeno, da bo zrušil strežnik, smo v celoti opustili uporabo združljivosti kABI za RHEL 7.

Trenutno paket KMOD za RHEL 7 vsebuje sklop za vsako različico izdaje in skript, ki naloži modul.

SUSE se je naloge združljivosti kABI lotil bolj previdno. Zagotavljajo združljivost kABI samo znotraj enega servisnega paketa.

Na primer, izdaja SLES 12 je potekala septembra 2014. In SLES 12 SP1 je bil že decembra 2015, torej je minilo nekaj več kot eno leto. Čeprav obe izdaji uporabljata jedro 3.12, nista združljivi s kABI. Očitno je vzdrževanje združljivosti kABI samo eno leto veliko lažje. Letni cikel posodabljanja modulov jedra ne bi smel povzročati težav ustvarjalcem modulov.

Zaradi te politike SUSE nismo zabeležili niti ene težave z združljivostjo kABI v našem modulu veeamsnap. Res je, da je število paketov za SUSE skoraj za red velikosti večje.

Obliži in ozadja

Čeprav se distributerji trudijo zagotoviti združljivost kABI in stabilnost jedra, poskušajo tudi izboljšati delovanje in odpraviti napake tega stabilnega jedra.

Hkrati razvijalci jedra Linuxa za podjetja poleg lastnega »dela na napakah« spremljajo spremembe v vanilla jedru in jih prenašajo v svoje »stabilno«.

Včasih to vodi do novih napake.

V zadnji izdaji Red Hat 6 je prišlo do napake v eni od manjših posodobitev. To je pripeljalo do dejstva, da je modul veeamsnap zagotovo zrušil sistem, ko je bil posnetek objavljen. Po primerjavi izvornih kod jedra pred in po posodobitvi smo ugotovili, da je krivo backport. Podoben popravek je bil izveden v vanilla različici jedra 4.19. Samo ta popravek je v vanilla jedru dobro deloval, pri prenosu v "stabilno" 2.6.32 pa je prišlo do težave s spinlockom.

Seveda imajo vsi vedno napake, toda ali je bilo vredno povleči kodo iz 4.19 v 2.6.32 in tvegati stabilnost?.. Nisem prepričan ...

Najhuje je, ko se v vlečenje vrvi med »stabilnostjo« in »modernizacijo« vmeša marketing. Trženjski oddelek potrebuje, da je jedro posodobljene distribucije po eni strani stabilno, hkrati pa boljše v delovanju in ima nove funkcije. To vodi do čudnih kompromisov.

Ko sem poskušal zgraditi modul na jedru 4.4 iz SLES 12 SP3, sem bil presenečen, ko sem v njem našel funkcionalnost iz različice 4.8. Po mojem mnenju je implementacija blokovnega V/I jedra 4.4 iz SLES 12 SP3 bolj podobna jedru 4.8 kot prejšnja izdaja stabilnega jedra 4.4 iz SLES12 SP2. Ne morem presoditi, kolikšen odstotek kode je bil prenesen iz jedra 4.8 v SLES 4.4 za SP3, vendar jedru ne morem niti reči enako stabilno 4.4.

Najbolj neprijetno pri tem je, da se pri pisanju modula, ki bi enako dobro deloval na različnih jedrih, ne morete več zanesti na različico jedra. Upoštevati je treba tudi distribucijo. Dobro je, da se včasih lahko vključite v definicijo, ki se pojavi skupaj z novo funkcionalnostjo, vendar se ta priložnost ne pojavi vedno.

Posledično postane koda preraščena s čudnimi direktivami pogojnega prevajanja.

Obstajajo tudi popravki, ki spreminjajo dokumentiran API jedra.
Naletel sem na distribucijo KDE neon 5.16 in bil zelo presenečen, ko je videl, da je klic lookup_bdev v tej različici jedra spremenil seznam vhodnih parametrov.

Da bi ga sestavil, sem moral dodati skript v makefile, ki preverja, ali ima funkcija lookup_bdev parameter maske.

Podpisovanje modulov jedra

A vrnimo se k vprašanju paketne distribucije.

Ena od prednosti stabilnega kABI je, da je mogoče module jedra podpisati kot binarno datoteko. V tem primeru je lahko razvijalec prepričan, da modul ni bil po nesreči poškodovan ali namerno spremenjen. To lahko preverite z ukazom modinfo.

Distribucije Red Hat in SUSE vam omogočajo, da preverite podpis modula in ga naložite le, če je ustrezno potrdilo registrirano v sistemu. Certifikat je javni ključ, s katerim je podpisan modul. Distribuiramo ga kot ločen paket.

Težava je v tem, da se lahko potrdila vgradijo v jedro (uporabljajo jih distributerji) ali pa jih je treba zapisati v obstojni pomnilnik EFI s pripomočkom mokutil. Pripomoček mokutil Pri namestitvi certifikata zahteva ponovni zagon sistema in še pred nalaganjem jedra operacijskega sistema pozove skrbnika, da dovoli nalaganje novega certifikata.

Zato je za dodajanje potrdila potreben fizični skrbniški dostop do sistema. Če je naprava nekje v oblaku ali preprosto v oddaljeni strežniški sobi in je dostop samo prek omrežja (na primer prek ssh), potem ne bo mogoče dodati potrdila.

EFI na virtualnih strojih

Kljub dejstvu, da EFI že dolgo podpirajo skoraj vsi proizvajalci matičnih plošč, pri namestitvi sistema skrbnik morda ne razmišlja o potrebi po EFI in je lahko onemogočen.

Vsi hipervizorji ne podpirajo EFI. VMWare vSphere podpira EFI od različice 5.
Microsoft Hyper-V je pridobil tudi podporo za EFI, začenši s Hyper-V za Windows Server 2012R2.

Vendar pa je v privzeti konfiguraciji ta funkcija onemogočena za stroje Linux, kar pomeni, da potrdila ni mogoče namestiti.

V vSphere 6.5 nastavite možnost Secure Boot možno samo v stari različici spletnega vmesnika, ki teče preko Flasha. Spletni uporabniški vmesnik na HTML-5 je še vedno daleč zadaj.

Eksperimentalne porazdelitve

In končno, razmislimo o vprašanju eksperimentalnih distribucij in distribucij brez uradne podpore. Po eni strani je malo verjetno, da bi takšne distribucije našli na strežnikih resnih organizacij. Uradne podpore za takšne distribucije ni. Zato jih zagotovite. Izdelek v takšni distribuciji ne more biti podprt.

Vendar pa takšne distribucije postanejo priročna platforma za preizkušanje novih eksperimentalnih rešitev. Na primer Fedora, OpenSUSE Tumbleweed ali Unstable različice Debiana. So precej stabilni. Vedno imajo nove različice programov in vedno novo jedro. Čez eno leto bo ta eksperimentalna funkcionalnost morda končana v posodobljenem RHEL, SLES ali Ubuntuju.

Torej, če nekaj ne deluje na eksperimentalni distribuciji, je to razlog, da ugotovite težavo in jo rešite. Pripravljeni morate biti na dejstvo, da se bo ta funkcionalnost kmalu pojavila na produkcijskih strežnikih uporabnikov.

Preučite lahko trenutni seznam uradno podprtih distribucij za različico 3.0 tukaj. Toda pravi seznam distribucij, na katerih lahko deluje naš izdelek, je veliko širši.

Osebno me je zanimal poskus z OS Elbrus. Po dokončanju paketa veeam je bil naš izdelek nameščen in deluje. O tem poskusu sem pisal na Habréju leta članek.

No, podpora za nove distribucije se nadaljuje. Čakamo na izdajo različice 4.0. Beta se bo kmalu pojavila, zato bodite pozorni kaj je novega!

Vir: www.habr.com

Dodaj komentar