Linux ima mnogo lica: kako raditi na bilo kojoj distribuciji

Linux ima mnogo lica: kako raditi na bilo kojoj distribuciji

Kreiranje sigurnosne aplikacije koja radi na bilo kojoj distribuciji nije lak zadatak. Kako biste osigurali da Veeam Agent za Linux radi na distribucijama od Red Hat 6 i Debian 6, do OpenSUSE 15.1 i Ubuntu 19.04, morate riješiti niz problema, posebno imajući u vidu da softverski proizvod uključuje modul kernela.

Članak je nastao na osnovu materijala iz govora na konferenciji Linux Peter 2019.

Linux nije samo jedan od najpopularnijih operativnih sistema. U suštini, ovo je platforma na osnovu koje možete napraviti nešto jedinstveno, nešto svoje. Zahvaljujući tome, Linux ima mnogo distribucija koje se razlikuju po svom skupu softverskih komponenti. I tu nastaje problem: da bi softverski proizvod funkcionirao na bilo kojoj distribuciji, morate uzeti u obzir karakteristike svake od njih.

Upravljači paketima. .deb vs .rpm

Počnimo s očiglednim problemom distribucije proizvoda u različitim distribucijama.
Najtipičniji način za distribuciju softverskih proizvoda je stavljanje paketa u spremište tako da menadžer paketa ugrađen u sistem može da ga instalira odatle.
Međutim, imamo dva popularna formata paketa: min и Deb. To znači da će svi morati podržati.

U svijetu deb paketa, nivo kompatibilnosti je nevjerovatan. Isti paket se instalira i radi podjednako dobro i na Debian 6 i na Ubuntu 19.04. Standardi za proces izrade paketa i rada s njima, postavljeni u starim Debian distribucijama, ostaju relevantni u novonastalom Linux Mintu i osnovnom OS-u. Stoga je u slučaju Veeam Agenta za Linux dovoljan jedan deb paket za svaku hardversku platformu.

Ali u svijetu rpm paketa, razlike su velike. Prvo, zbog činjenice da postoje dva potpuno nezavisna distributera, Red Hat i SUSE, kojima je kompatibilnost potpuno nepotrebna. Drugo, ovi distributeri imaju distribucijske komplete od njih. podrška i eksperimentalni. Nema potrebe za kompatibilnošću između njih. Ispostavilo se da el6, el7 i el8 imaju svoje pakete. Poseban paket za Fedoru. Paketi za SLES11 i 12 i poseban za openSUSE. Glavni problem su zavisnosti i nazivi paketa.

Problem zavisnosti

Nažalost, isti paketi često završavaju pod različitim imenima u različitim distribucijama. Ispod je djelimična lista zavisnosti od veeam paketa.

Za EL7:
Za 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

Kao rezultat toga, lista zavisnosti je jedinstvena za distribuciju.

Ono što postaje gore je kada se ažurirana verzija počne skrivati ​​pod starim imenom paketa.

Primjer:

Paket je ažuriran u Fedora 24 ncurses od verzije 5 do verzije 6. Naš proizvod je napravljen sa verzijom 5 kako bi se osigurala kompatibilnost sa starijim distribucijama. Da bih koristio staru 5. verziju biblioteke na Fedora 24, morao sam koristiti paket ncurses-compat-libs.

Kao rezultat, postoje dva paketa za Fedoru, sa različitim zavisnostima.

Dalje zanimljivije. Nakon sljedećeg ažuriranja distribucije, paket ncurses-compat-libs s verzijom 5 biblioteke ispada da je nedostupan. Za distributera je skupo prevući stare biblioteke u novu verziju distribucije. Nakon nekog vremena, problem se ponovio u SUSE distribucijama.

Kao rezultat toga, neke distribucije su morale napustiti svoju eksplicitnu ovisnost o ncurses-libs, i popravite proizvod tako da može raditi s bilo kojom verzijom biblioteke.

Inače, u verziji 8 Red Hata više ne postoji meta paket python, koji se odnosio na staro dobro python 2.7. Postoji python2 и python3.

Alternativa paket menadžerima

Problem sa zavisnostima je star i odavno je očigledan. Samo zapamtite pakao zavisnosti.
Kombinirati različite biblioteke i aplikacije tako da sve rade stabilno i ne sukobljavaju se - u stvari, to je zadatak koji svaki distributer Linuxa pokušava riješiti.

Upravitelj paketa pokušava riješiti ovaj problem na potpuno drugačiji način. elegantan od Canonical. Glavna ideja: aplikacija radi u sandboxu izoliranom i zaštićenom od glavnog sistema. Ako aplikacija zahtijeva biblioteke, one se isporučuju sa samom aplikacijom.

Flatpak također vam omogućava pokretanje aplikacija u sandboxu koristeći Linux kontejnere. Koristi se i ideja sandbox-a AppImage.

Ova rješenja vam omogućavaju da kreirate jedan paket za bilo koju distribuciju. U slučaju da Flatpak instalacija i pokretanje aplikacije moguća je i bez znanja administratora.

Glavni problem je što ne mogu sve aplikacije da rade u sandboxu. Nekim ljudima je potreban direktan pristup platformi. Ne govorim ni o modulima kernela, koji su striktno zavisni od kernela i ne uklapaju se u sandbox koncept.

Drugi problem je što distribucije koje su popularne u poslovnom okruženju iz Red Hata i SUSE-a još ne sadrže podršku za Snappy i Flatpak.

U tom smislu, Veeam Agent za Linux nije dostupan snapcraft.io nije uključeno flathub.org.

Da zaključim pitanje o menadžerima paketa, želio bih napomenuti da postoji opcija da se paket menadžeri potpuno napuste kombiniranjem binarnih datoteka i skripte za njihovu instalaciju u jedan paket.

Takav paket vam omogućava da kreirate jedan zajednički paket za različite distribucije i platforme, izvršite interaktivni proces instalacije, provodeći potrebnu prilagodbu. Naišao sam samo na takve pakete za Linux od VMware-a.

Problem ažuriranja

Linux ima mnogo lica: kako raditi na bilo kojoj distribuciji
Čak i ako su svi problemi ovisnosti riješeni, program može raditi drugačije na istoj distribuciji. To je pitanje ažuriranja.

Postoje 3 strategije ažuriranja:

  • Najjednostavniji je da nikada ne ažurirate. Podesio sam server i zaboravio na njega. Zašto ažurirati ako sve radi? Problemi počinju kada prvi put kontaktirate podršku. Kreator distribucije podržava samo ažurirano izdanje.
  • Možete vjerovati distributeru i postaviti automatska ažuriranja. U ovom slučaju, poziv podršci je vjerovatno odmah nakon neuspješnog ažuriranja.
  • Opcija ručnog ažuriranja tek nakon pokretanja na probnoj infrastrukturi je najpouzdanija, ali skupa i dugotrajna. Ne može si to priuštiti svako.

Budući da različiti korisnici koriste različite strategije ažuriranja, potrebno je podržati i najnovije izdanje i sva prethodno objavljena. Ovo komplikuje proces razvoja i testiranja i dodaje glavobolju timu za podršku.

Raznolikost hardverskih platformi

Različite hardverske platforme su problem koji je uglavnom specifičan za izvorni kod. U najmanju ruku, morate prikupiti binarne datoteke za svaku podržanu platformu.

U projektu Veeam Agent za Linux još uvijek ne možemo podržati ništa poput ovog RISC-a.

Neću se detaljnije zadržavati na ovom pitanju. Navešću samo glavne probleme: tipove zavisne od platforme, kao npr size_t, poravnanje strukture i redoslijed bajtova.

Statičko i/ili dinamičko povezivanje

Linux ima mnogo lica: kako raditi na bilo kojoj distribuciji
Ali pitanje je "Kako se povezati s bibliotekama - dinamički ili statički?" vredi diskutovati.

Po pravilu, C/C++ aplikacije pod Linuxom koriste dinamičko povezivanje. Ovo odlično funkcionira ako je aplikacija napravljena posebno za određenu distribuciju.

Ako je zadatak pokriti različite distribucije jednom binarnom datotekom, onda se morate fokusirati na najstariju podržanu distribuciju. Za nas je ovo Red Hat 6. Sadrži gcc 4.4, koji čak ni C++11 standard ne podržava potpuno.

Naš projekat gradimo koristeći gcc 6.3, koji u potpunosti podržava C++14. Naravno, u ovom slučaju, na Red Hatu 6 morate nositi libstdc++ i pojačati biblioteke sa sobom. Najlakši način je da ih statički povežete.

Ali nažalost, ne mogu sve biblioteke biti statički povezane.

Prvo, sistemske biblioteke kao npr libfuse, libblkid potrebno je dinamički povezati kako bi se osigurala njihova kompatibilnost sa kernelom i njegovim modulima.

Drugo, postoji suptilnost s licencama.

GPL licenca vam u osnovi omogućava povezivanje biblioteka samo sa otvorenim kodom. MIT i BSD dozvoljavaju statičko povezivanje i omogućavaju da se biblioteke uključe u projekat. Ali čini se da LGPL nije u suprotnosti sa statičkim povezivanjem, već zahtijeva da se datoteke neophodne za povezivanje dijele.

Općenito, korištenje dinamičkog povezivanja spriječit će vas da ne morate ništa pružati.

Izrada C/C++ aplikacija

Da biste napravili C/C++ aplikacije za različite platforme i distribucije, dovoljno je odabrati ili izgraditi odgovarajuću verziju gcc-a i koristiti unakrsne kompajlere za određene arhitekture i sastaviti cijeli skup biblioteka. Ovaj posao je prilično izvodljiv, ali prilično problematičan. I ne postoji garancija da će odabrani kompajler i biblioteke pružiti funkcionalnu verziju.

Očigledna prednost: infrastruktura je znatno pojednostavljena, budući da se cijeli proces izgradnje može završiti na jednoj mašini. Osim toga, dovoljno je prikupiti jedan set binarnih datoteka za jednu arhitekturu i možete ih pakirati u pakete za različite distribucije. Ovako su napravljeni veeam paketi za Veeam Agent za Linux.

Za razliku od ove opcije, možete jednostavno pripremiti build farmu, odnosno nekoliko mašina za montažu. Svaka takva mašina će obezbediti kompilaciju aplikacije i sastavljanje paketa za određenu distribuciju i specifičnu arhitekturu. U ovom slučaju, kompilacija se vrši pomoću sredstava koje je pripremio distributer. Odnosno, faza pripreme kompajlera i odabira biblioteka je eliminisana. Osim toga, proces izgradnje se može lako paralelizirati.

Postoji, međutim, loša strana ovog pristupa: za svaku distribuciju unutar iste arhitekture, morat ćete prikupiti vlastiti skup binarnih datoteka. Još jedan nedostatak je što je potrebno održavati toliki broj mašina i dodijeliti veliku količinu diskovnog prostora i RAM-a.

Ovako se kompajliraju KMOD paketi modula veeamsnap kernel za Red Hat distribucije.

Otvorite Build Service

Kolege iz SUSE-a su pokušale da implementiraju neku sredinu u vidu posebnog servisa za kompajliranje aplikacija i sklapanje paketa - openbuildservice.

U suštini, to je hipervizor koji kreira virtuelnu mašinu, instalira sve potrebne pakete u nju, kompajlira aplikaciju i gradi paket u ovom izolovanom okruženju, nakon čega se virtuelna mašina pušta.

Linux ima mnogo lica: kako raditi na bilo kojoj distribuciji

Planer implementiran u OpenBuildService će odrediti koliko virtuelnih mašina može pokrenuti za optimalnu brzinu izgradnje paketa. Ugrađeni mehanizam potpisivanja će potpisati pakete i otpremiti ih u ugrađeno spremište. Ugrađeni sistem kontrole verzija će sačuvati historiju promjena i izrada. Sve što ostaje je da jednostavno dodate svoje izvore ovom sistemu. Ne morate čak ni sami postavljati server, možete koristiti otvoreni.

Postoji, međutim, problem: takav kombajn se teško uklapa u postojeću infrastrukturu. Na primjer, kontrola verzija nije potrebna; već imamo vlastite izvorne kodove. Naš mehanizam potpisa je drugačiji: koristimo poseban server. Repozitorijum takođe nije potreban.

Osim toga, podrška za druge distribucije - na primjer, Red Hat - implementirana je prilično loše, što je i razumljivo.

Prednost ovakvog servisa je brza podrška za sljedeću verziju SUSE distribucije. Prije zvanične objave izlaska, paketi potrebni za sklapanje se postavljaju na javno spremište. Nova se pojavljuje na listi dostupnih distribucija na OpenBuildServiceu. Označavamo okvir i dodaje se u plan izgradnje. Tako se dodavanje nove verzije distribucije vrši gotovo jednim klikom.

U našoj infrastrukturi, koristeći OpenBuildService, sastavljen je čitav niz KMP paketa veeamsnap kernel modula za SUSE distribucije.

Zatim bih se želio zadržati na problemima specifičnim za module kernela.

kernel ABI

Linux kernel moduli su se kroz istoriju distribuirali u izvornom obliku. Činjenica je da se kreatori kernela ne opterećuju brigom o podršci stabilnom API-ju za module kernela, a posebno na binarnom nivou, dalje nazvanom kABI.

Da biste napravili modul za vanilla kernel, definitivno su vam potrebna zaglavlja ovog konkretnog kernela, a on će raditi samo na ovom kernelu.

DKMS vam omogućava da automatizujete proces izgradnje modula prilikom ažuriranja kernela. Kao rezultat toga, korisnici Debian spremišta (i njegovi brojni srodnici) koriste module kernela ili iz spremišta distributera ili kompajlirane iz izvora koristeći DKMS.

Međutim, ova situacija ne odgovara posebno segmentu preduzeća. Distributeri vlasničkog koda žele distribuirati proizvod kao kompajlirane binarne datoteke.

Administratori ne žele zadržati razvojne alate na proizvodnim serverima iz sigurnosnih razloga. Enterprise Linux distributeri kao što su Red Hat i SUSE odlučili su da mogu podržati stabilan kABI za svoje korisnike. Rezultat su bili KMOD paketi za Red Hat i KMP paketi za SUSE.

Suština ovog rješenja je prilično jednostavna. Za određenu verziju distribucije, kernel API je zamrznut. Distributer navodi da koristi kernel, na primjer, 3.10, i pravi samo ispravke i poboljšanja koja ne utiču na interfejse kernela, a moduli prikupljeni za prvi kernel mogu se koristiti za sve naredne bez rekompilacije.

Red Hat tvrdi da je kABI kompatibilan za distribuciju tokom čitavog životnog ciklusa. Odnosno, sastavljeni modul za rhel 6.0 (izdanje novembar 2010.) bi takođe trebalo da radi na verziji 6.10 (izdanje juna 2018.). A ovo je skoro 8 godina. Naravno, ovaj zadatak je prilično težak.
Zabilježili smo nekoliko slučajeva gdje je veeamsnap modul prestao raditi zbog problema s kABI kompatibilnošću.

Nakon što se pokazalo da je veeamsnap modul, kompajliran za RHEL 7.0, nekompatibilan sa kernelom iz RHEL 7.5, ali se učitao i garantovano će srušiti server, u potpunosti smo napustili upotrebu kABI kompatibilnosti za RHEL 7.

Trenutno, KMOD paket za RHEL 7 sadrži sklop za svaku verziju izdanja i skriptu koja učitava modul.

SUSE je pažljivije pristupio zadatku kABI kompatibilnosti. Oni pružaju kABI kompatibilnost samo unutar jednog servisnog paketa.

Na primjer, izdanje SLES 12 održano je u septembru 2014. A SLES 12 SP1 je već bio u decembru 2015. godine, odnosno prošlo je nešto više od godinu dana. Iako oba izdanja koriste kernel 3.12, ona su kABI nekompatibilna. Očigledno, održavanje kABI kompatibilnosti samo godinu dana je mnogo lakše. Godišnji ciklus ažuriranja modula kernela ne bi trebao uzrokovati probleme kreatorima modula.

Kao rezultat ove SUSE politike, nismo zabilježili niti jedan problem sa kABI kompatibilnošću u našem veeamsnap modulu. Istina, broj paketa za SUSE je gotovo za red veličine veći.

Zakrpe i backportovi

Iako distributeri pokušavaju osigurati kABI kompatibilnost i stabilnost kernela, oni također pokušavaju poboljšati performanse i eliminirati nedostatke ovog stabilnog kernela.

Istovremeno, pored vlastitog „rada na greškama“, programeri poslovnog Linux kernela prate promjene u vanilla kernelu i prenose ih u svoj „stabilan“.

Ponekad to dovodi do novih greške.

U najnovijem izdanju Red Hat 6, napravljena je greška u jednom od manjih ažuriranja. To je dovelo do činjenice da je veeamsnap modul garantovano srušio sistem kada je snimak objavljen. Upoređujući izvore kernela prije i nakon ažuriranja, otkrili smo da je za to kriv backport. Slična ispravka je napravljena u vanilla kernelu verziji 4.19. Samo što je ova ispravka dobro funkcionisala u vanilla kernelu, ali prilikom prenosa na "stabilnu" 2.6.32, pojavio se problem sa spinlockom.

Naravno, uvek svi imaju greške, ali da li je vredelo prevlačiti kod sa 4.19 na 2.6.32, rizikujući stabilnost?.. Nisam siguran...

Najgore je kada se marketing umiješa u natezanje između “stabilnosti” i “modernizacije”. Odjelu marketinga je potrebno da jezgro ažurirane distribucije s jedne strane bude stabilno, a da u isto vrijeme bude bolje u performansama i ima nove funkcije. To dovodi do čudnih kompromisa.

Kada sam pokušao da napravim modul na kernelu 4.4 iz SLES 12 SP3, bio sam iznenađen kada sam u njemu pronašao funkcionalnost iz vanile 4.8. Po mom mišljenju, blok I/O implementacija 4.4 kernela iz SLES 12 SP3 je sličnija kernelu 4.8 od prethodnog izdanja stabilnog 4.4 kernela iz SLES12 SP2. Ne mogu procijeniti koliki je postotak koda prebačen sa kernela 4.8 na SLES 4.4 za SP3, ali ne mogu ni kernel nazvati istim stabilnim 4.4.

Najneprijatnija stvar u vezi ovoga je da kada pišete modul koji bi jednako dobro radio na različitim kernelima, više se ne možete osloniti na verziju kernela. Takođe morate uzeti u obzir distribuciju. Dobro je što se ponekad možete uključiti u definiciju koja se pojavljuje zajedno s novom funkcionalnošću, ali ova prilika se ne pojavljuje uvijek.

Kao rezultat, kod postaje obrastao čudnim direktivama uslovne kompilacije.

Postoje i zakrpe koje mijenjaju dokumentovani API kernela.
Naišao sam na distribuciju KDE neon 5.16 i bio sam vrlo iznenađen kada je vidio da je lookup_bdev poziv u ovoj verziji kernela promijenio listu ulaznih parametara.

Da bih to spojio, morao sam dodati skriptu makefileu koja provjerava da li funkcija lookup_bdev ima parametar maske.

Potpisivanje modula kernela

No, vratimo se pitanju distribucije paketa.

Jedna od prednosti stabilnog kABI-ja je da moduli kernela mogu biti potpisani kao binarni fajl. U tom slučaju, programer može biti siguran da modul nije slučajno oštećen ili namjerno izmijenjen. Ovo možete provjeriti naredbom modinfo.

Red Hat i SUSE distribucije vam omogućavaju da provjerite potpis modula i učitate ga samo ako je odgovarajući certifikat registriran na sistemu. Certifikat je javni ključ kojim je modul potpisan. Distribuiramo ga kao poseban paket.

Ovdje je problem u tome što certifikati mogu biti ugrađeni u kernel (distributeri ih koriste) ili moraju biti upisani u EFI nepromjenjivu memoriju pomoću uslužnog programa mokutil. Utility mokutil Prilikom instaliranja certifikata, zahtijeva da ponovo pokrenete sistem i, čak i prije učitavanja kernela operativnog sistema, traži od administratora da dozvoli učitavanje novog certifikata.

Dakle, dodavanje certifikata zahtijeva fizički pristup administratora sistemu. Ako se mašina nalazi negdje u oblaku ili jednostavno u udaljenoj serverskoj sobi i pristup je samo preko mreže (na primjer, preko ssh), tada će biti nemoguće dodati certifikat.

EFI na virtuelnim mašinama

Unatoč činjenici da je EFI već dugo podržan od strane gotovo svih proizvođača matičnih ploča, prilikom instaliranja sistema administrator možda neće razmišljati o potrebi za EFI-om, a može biti i onemogućen.

Ne podržavaju svi hipervizori EFI. VMWare vSphere podržava EFI počevši od verzije 5.
Microsoft Hyper-V je takođe dobio EFI podršku počevši od Hyper-V za Windows Server 2012R2.

Međutim, u zadanoj konfiguraciji ova funkcija je onemogućena za Linux mašine, što znači da se certifikat ne može instalirati.

U vSphere 6.5 postavite opciju Secure Boot moguće samo u staroj verziji web sučelja, koji radi preko Flasha. Web UI na HTML-5 je još uvijek daleko iza.

Eksperimentalne distribucije

I na kraju, razmotrimo pitanje eksperimentalnih distribucija i distribucija bez službene podrške. S jedne strane, malo je vjerovatno da će se takve distribucije naći na serverima ozbiljnih organizacija. Ne postoji zvanična podrška za takve distribucije. Stoga ih obezbijedite. Proizvod ne može biti podržan na takvoj distribuciji.

Međutim, takve distribucije postaju pogodna platforma za isprobavanje novih eksperimentalnih rješenja. Na primjer, Fedora, OpenSUSE Tumbleweed ili nestabilne verzije Debiana. Prilično su stabilni. Uvijek imaju nove verzije programa i uvijek novi kernel. Za godinu dana, ova eksperimentalna funkcionalnost može završiti u ažuriranom RHEL-u, SLES-u ili Ubuntu-u.

Dakle, ako nešto ne radi na eksperimentalnoj distribuciji, to je razlog da shvatite problem i riješite ga. Morate biti spremni na činjenicu da će se ova funkcionalnost uskoro pojaviti na proizvodnim serverima korisnika.

Možete proučiti trenutnu listu zvanično podržanih distribucija za verziju 3.0 ovdje. Ali stvarna lista distribucija na kojima naš proizvod može raditi je mnogo šira.

Lično me je zanimao eksperiment sa Elbrus OS-om. Nakon finalizacije veeam paketa, naš proizvod je instaliran i radi. Pisao sam o ovom eksperimentu na Habréu članak.

Pa, podrška za nove distribucije se nastavlja. Čekamo izdavanje verzije 4.0. Beta će se uskoro pojaviti, pa pripazite šta je novo!

izvor: www.habr.com

Dodajte komentar