
På et tidspunkt besluttede jeg mig for at skrive en artikel om levering i form af Docker-containere og deb-pakker, men da jeg begyndte, blev jeg af en eller anden grund ført tilbage til de tidlige dage med personlige computere og endda lommeregnere. Så i stedet for tørre sammenligninger mellem Docker og deb, fik jeg disse overvejelser om evolution, som jeg præsenterer for Dem.
Enhver produkt, uanset hvad det er, skal på en eller anden måde nå frem til produktionsserverne, være konfigureret og lanceret. Det er netop det, denne artikel vil omhandle.
Mine overvejelser vil være i en historisk kontekst, "hvad jeg ser - om det synger jeg", hvad jeg så, da jeg først begyndte at skrive kode, og hvad jeg observerer nu, hvad vi selv bruger i øjeblikket, og hvorfor. Artiklen har ikke til hensigt at være en udtømmende undersøgelse, nogle punkter er udeladt, det er mit personlige syn på, hvad der var, og hvad der er nu.
Så, i de gode gamle dage… den tidligste måde at levere på, som jeg oplevede - det var kassetter fra båndoptagere. Jeg havde en BK-0010.01 computer...
Lommeregnerens æra
Nej, der var et endnu tidligere øjeblik, der var også en lommeregner og .
Så da jeg havde , var måden at overføre programmer på et almindeligt papirark med firkanter, hvor programmet var skrevet, som ved behov blev indtastet manuelt i lommeregneren. Vil du spille (ja, ja, selv på denne forhistoriske lommeregner var der spil) - sætter du dig ned og indtaster programmet i lommeregneren. Selvfølgelig forsvandt programmet, når lommeregneren blev slukket. Udover de koder, jeg selv havde skrevet ned på papir, blev programmer publiceret i magasiner som "Radio" og "Ungdomsteknik", samt trykt i bøger fra den tid.
Den næste modifikation var lommeregneren , som allerede havde en slags energi-uafhængig datalagring. Nu var det ikke længere nødvendigt at indtaste spillet eller programmet manuelt; efter at have udført nogle magiske tastetryk blev det indlæst selv.
Størrelsen på det største program i lommeregneren var 105 trin, og den permanente hukommelsesstørrelse i МК-52 var 512 trin.
Forresten, hvis der er fans af disse lommeregnere, der læser denne artikel - under skrivningen af artiklen fandt jeg både en emulator af lommeregneren til Android og programmer til den. Fremad, tilbage i tiden!
En lille afstikker om MK-52 (fra Wikipedia)
MK-52 fløj ind i rummet med skibet "Soyuz TM-7". Den blev påtænkt til brug i beregningen af landingsbane i tilfælde af, at det bordcomputer svigtede.
MK-52 med hukommelsesudvidelsesblok "Elektronika-Astro" blev fra 1988 leveret til skibene i flåden som en del af navigatorens beregningskompleks.
De første personlige computere
Lad os vende tilbage til tiderne . Det er tydeligt, at der også var mere hukommelse, og at det slet ikke var en mulighed at indtaste koden fra papiret (selvom jeg i starten gjorde det, fordi der simpelthen ikke var noget andet medie). Det primære middel til opbevaring og distribution af software blev båndoptagere.
Opbevaring på bånd var typisk i form af en eller to binære filer, alt andet var indeni. Pålideligheden var meget lav, så man måtte have 2-3 kopier af programmet. Indlæsningstiden var heller ikke tilfredsstillende, entusiaster eksperimenterede med forskellige frekvenskodninger for at overvinde disse ulemper. Jeg selv beskæftigede mig ikke professionelt med softwareudvikling på det tidspunkt (bortset fra simple programmer i BASIC), så jeg kan desværre ikke fortælle i detaljer, hvordan alt inden i var ordnet. Det faktum, at computeren kun havde RAM, bestemte stort set enkeltheden i dataopbevaringssystemet.
Fremkomsten af pålidelige og store lagermedier
Senere kom der disketter, hvilket forenklede kopieringsprocessen og øgede pålideligheden.
Men situationen ændrede sig radikalt, kun når der kom tilstrækkeligt store lokale lagre i form af HDD.
Principielt ændrer typen af leverancer sig: der kommer installationsprogrammer, der styrer konfigureringsprocessen af systemet samt oprydning efter sletning, da programmer ikke bare læses ind i hukommelsen, men allerede kopieres til det lokale lager, fra hvilket man også skal kunne rydde op i unødvendige filer ved behov.
Samtidig øges kompleksiteten af det leverede software.
Antallet af filer i leverancen stiger fra enheder til hundreder og tusinder, og der opstår konflikt med versionsbiblioteker og andre glæder, når forskellige programmer bruger de samme data.
I de dage var Linux stadig en ukendt verden for mig; jeg levede i MS DOS og senere Windows, og skrev i Borland Pascal og Delphi, mens jeg lejlighedsvis kiggede i retning af C++. For at levere produkter brugte mange InstallShield. , som meget effektivt løste alle opgaver inden for udrulning og konfiguration af software.
Internettets æra
Kompleksiteten af program.Systemer bliver gradvist mere komplicerede; overgangen fra monolitiske og desktop-applikationer til distribuerede systemer, tynde klienter og mikrotjenester finder sted. Nu er det ikke kun én applikation, der skal konfigureres, men en hel samling, og de skal fungere sammen.
Konceptet har ændret sig fuldstændigt; Internettet kom, og æraen for cloud-tjenester indtraf. På det tidspunkt var det stadig kun i sin spæde fase, som websites, og der var ikke mange, der drømte om tjenester, men det var et vendepunkt i branchen både for udvikling og for levering af applikationer.
Jeg bemærkede, at der på dette tidspunkt skete et generationsskifte blandt udviklere (eller var det kun i mit miljø), og der var en følelse af, at alle de gamle gode leveringsmetoder pludselig blev glemt, og alt blev startet forfra: hele leveringsprocessen blev udført med skripter, og det blev stolt kaldt "Continuous delivery". Faktisk begyndte der en periode med en form for kaos, hvor det gamle blev glemt og ikke brugt, og der simpelthen ikke var noget nyt.
Jeg husker tiderne, da vi i den virksomhed, hvor jeg arbejdede dengang (jeg vil ikke nævne navnet), i stedet for at lave en bygning gennem ant (maven var dengang ikke populær eller eksisterede slet ikke), ganske enkelt samlede jar-filen i IDE'en og roligt committede den til SVN. Udrulningen bestod derfor blot i at hente filen fra SVN og kopiere den via SSH til den rigtige maskine. Så enkelt og rudimentært.
På samme tid blev levering af simple websites på PHP udført på en overordentlig primitiv måde ved blot at kopiere den rettede fil gennem FTP til den målrettede maskine. Nogle gange var det ikke engang nødvendigt; koden blev redigeret direkte på produktionsserveren, og det var en særlig luksus, hvis der var nogen backups.
RPM- og DEB-pakker
På den anden side, med udviklingen af internettet er UNIX-lignende systemer blevet stadig mere populære, især i den periode opdagede jeg RedHat Linux 6, omkring år 2000. Naturligvis var der også visse værktøjer til distribution af software, ifølge Wikipedia blev RPM som den primære paketchef introduceret allerede i 1995 med versionen RedHat Linux 2.0. Og lige siden da er systemet blevet leveret i form af RPM-pakker og eksisterer og udvikler sig ganske succesfuldt.
Debian-familien har taget en lignende vej og implementeret levering i form af deb-pakker, hvilket også ubestridt er tilfældet den dag i dag.
Paketchefer gør det muligt at levere selve softwareprodukterne, konfigurere dem under installationsprocessen, styre afhængighederne mellem forskellige pakker, udføre fjernelse af produkter og rengøre det overflødige under afinstallationen. Det vil sige, at det i høj grad er alt, hvad der er brug for, og netop derfor har de overlevet i flere årtier næsten uden ændringer.
Skyteknologi har tilføjet installation af pakker ikke kun fra fysiske medier, men også fra cloud-repositorier, men principielt er der sket meget lidt ændringer.
Det er værd at bemærke, at der i øjeblikket er visse tendenser til at bevæge sig væk fra deb og over til snap-pakker, men mere om det senere.
Så denne nye generation af cloud-udviklere, som ikke kendte til hverken DEB eller RPM, voksede stille og roligt, fik erfaring, produkterne blev mere komplekse, og der var behov for mere fornuftige leveringsmetoder end FTP, bash-scripts og lignende studenterprojekter.
Og her træder Docker ind på scenen, en slags blanding af virtualisering, ressourceafgrænsning og leveringsmetode. Det er moderne og ungdommeligt nu, men er det nødvendigt for alting? Er det en panacea?
Efter min observation bliver Docker ofte præsenteret ikke som et fornuftigt valg, men blot fordi det, på den ene side, diskuteres i samfundet, og de, der tilbyder det, kun kender det. På den anden side er der stort set ikke nogen tale om de gode, gamle pakkesystemer - de findes stadig og gør deres arbejde stille og ubemærket. I en sådan situation er der ikke meget valg - valget er oplagt - Docker.
Jeg vil forsøge at dele erfaringer om, hvordan vores implementering af Docker gik, og hvad resultatet blev.
Hjemmelavede scripts
Oprindeligt var der bash-scripts, der deployede jar-arkiver på de nødvendige maskiner. Dette proces blev styret af Jenkins. Det fungerede godt, da selve jar-arkivet allerede er et byggeri, der indeholder klasser, ressourcer og endda konfiguration. Hvis man maksimerer indholdet, så er det ikke så svært at pakke det ud med et script.
Men scripts har flere ulemper:
- Scripts skrives ofte i hast og er derfor så primitive, at de kun indeholder det mest optimale scenarie. Dette skyldes, at udvikleren er interesseret i hurtig levering, mens et ordentligt script kræver en betydelig mængde ressourcer.
- Som konsekvens af det foregående punkt indeholder scripts ikke afinstallationsprocedurer.
- Der er ingen etableret opgraderingsprocedure.
- Når der kommer et nyt produkt, skal der skrives et nyt script.
- Der er ingen afhængighedsstøtte.
Selvfølgelig kan man skrive et avanceret script, men som jeg nævnte tidligere, kræver det tid til udvikling, og som bekendt er tid altid en mangelvare.
Dette begrænser tydeligt anvendelsesområdet for denne udviklingsmetode til kun de simpleste systemer. Det er tid til at ændre det.
Docker
I et bestemt øjeblik begyndte nyuddannede mid-levels at komme til os, sprudlende med ideer og drømmende om Docker. Hvad skal der til? Flaget i hånden – lad os gøre det! Der var to forsøg. Begge mislykkedes – lad os sige det sådan, på grund af store ambitioner, men utilstrækkelig faktisk erfaring. Skulle vi tvinge det igennem og færdiggøre det med alle midler? Sandsynligvis ikke – kollektivet skal evolutionært vokse til det rette niveau, før det kan bruge de relevante værktøjer. Desuden, når vi brugte færdige Docker-billeder, stødte vi ofte på problemer med netværket (som måske også var relateret til umodenheden af selve Docker) eller havde svært ved at udvide andres containere.
Hvilke ulemper stødte vi på?
- Netværksproblemer i bridge-tilstand.
- Det er besværligt at se logs i containeren (hvis de ikke er udskilt separat i værtens filsystem).
- Periodisk mærkelig hængning af ElasticSearch inde i containeren, årsagen blev aldrig fundet, det var en officiel container.
- Det er ubelejligt at bruge shell inde i containeren – alt er meget begrænset, og der mangler de sædvanlige værktøjer.
- Storede containere i stor størrelse koster meget at opbevare
- På grund af den store størrelse af containere er det vanskeligt at understøtte flere versioner
- Længere opbygning sammenlignet med andre metoder (scripts eller deb-pakker)
På den anden side, hvad gør Spring-service som jar-arkiv værre at deployere via deb? Er ressourceisolation virkelig nødvendig? Skal vi miste de praktiske værktøjer fra operativsystemet ved at propppe servicen ind i en stærkt begrænset container?
Praksis har vist, at det i virkeligheden ikke er nødvendigt; deb-pakker er tilstrækkelige i 90% af tilfældene.
Hvornår virker den gode, gamle deb ikke, og hvornår har vi faktisk brug for Docker?
For os var det deployment af tjenester i Python. Mange biblioteker, der var nødvendige til maskinlæring og ikke tilgængelige i standardudgaven af operativsystemet (og det, der var der, var ikke de rigtige versioner), hacks med indstillinger, behov for forskellige versioner til forskellige tjenester der kører på det samme værtssystem, førte til, at den eneste fornuftige måde at levere denne kerneblanding på var Docker. Arbejdsbyrden med at bygge Docker-containeren viste sig at være lavere end ideen om at pakke det hele ind i separate deb-pakker med afhængigheder; ærligt talt ville ingen ved det sunde fornuft overhovedet have kastet sig over det.
Det andet aspekt, hvor Docker planlægges brugt, er til deployment af tjenester via blue-green deploy. Men her ønsker man en gradvis stigning i kompleksitet: først opbygges deb-pakker, og så bygges Docker-containeren ud fra dem.
Snap-pakker
Lad os vende tilbage til snap-pakker. De dukkede første gang op officielt i Ubuntu 16.04. I modsætning til de velkendte deb-pakker og rpm-pakker, bærer snap alle afhængigheder i sig. På den ene side undgår dette biblioteks konflikter, men på den anden side medfører det større størrelser på den resulterende pakke. Derudover kan det også påvirke systemets sikkerhed: I tilfælde af snap-levering skal udvikleren, der opretter pakken, selv holde styr på alle ændringer af de inkluderede biblioteker. Samlet set er det ikke så entydigt, og det universelle lykke ved deres brug indtræffer ikke. Men ikke desto mindre er det en rimelig alternativ, ifølge hvilken Docker kun bruges som et emballeringsmiddel og ikke til virtualisering.
Som resultat bruger vi nu en fornuftig kombination af både deb-pakker og Docker-containere, som vi muligvis i enkelte tilfælde vil erstatte med snap-pakker.
Kun registrerede brugere kan deltage i undersøgelsen. , please.
Hvad bruger I til distribution?
Hjemmelavede scripts
Vi kopierer manuelt til FTP.
deb-pakker
rpm-pakker
snap-pakker
Docker-billeder
Virtuelle maskinbilleder
Vi kloner hele HDD'en.
puppet
ansible
Andet
109 brugere har stemt. 32 brugere har afholdt sig.
Kilde: habr.com
