Er Docker et leketøy eller ikke? Eller er det fortsatt sant?

Hei!

Jeg ønsker virkelig å komme rett til temaet, men det ville være mer riktig å fortelle litt om historien min:

Entry

Jeg er en programmerer med erfaring i å utvikle frontend enkeltsideapplikasjoner, scala/java og nodejs på serveren.

I ganske lang tid (definitivt et par eller tre år) var jeg av den oppfatning at Docker er manna fra himmelen og generelt sett et veldig kult verktøy og absolutt alle utviklere burde kunne bruke det. Og av dette følger det at hver utvikler bør ha Docker installert på sin lokale maskin. Hva med min mening, se gjennom de ledige stillingene som er lagt ut på samme hh. Hver andre inneholder en omtale av docker, og hvis du eier den, vil dette være ditt konkurransefortrinn 😉

På min vei møtte jeg mange mennesker, med deres forskjellige holdninger til Docker og dets økosystem. Noen sa at dette er en praktisk ting som garanterer funksjonalitet på tvers av plattformer. De andre forsto ikke hvorfor de skulle kjøre i containere og hvilken fortjeneste som ville komme fra det, den tredje brydde seg ikke i det hele tatt og brydde seg ikke (de skrev bare koden og dro hjem - jeg misunner dem, av måte :)

Årsaker til bruk

Hvorfor brukte jeg docker? Sannsynligvis av følgende grunner:

  • database lansering, 99% av applikasjonene bruker dem
  • lanserer nginx for frontend-distribusjon og proxying til backend
  • du kan pakke applikasjonen i et docker-bilde, på denne måten vil applikasjonen min fungere hvor enn docker finnes, distribusjonsproblemet løses umiddelbart
  • tjenesteoppdagelse ut av esken, du kan lage mikrotjenester, hver beholder (koblet til et felles nettverk) kan enkelt nå en annen via et alias, veldig praktisk
  • Det er morsomt å lage en beholder og "leke" i den.

Det jeg alltid IKKE liker med docker:

  • For at applikasjonen min skal fungere, trenger jeg selve Docker på serveren. Hvorfor trenger jeg dette hvis programmene mine kjører på jre eller nodejs og miljøet for dem allerede er på serveren?
  • hvis jeg vil kjøre mitt (private) lokalt bygde bilde på en ekstern server, så trenger jeg mitt eget docker-lager, jeg trenger at registeret fungerer et sted og jeg må også konfigurere https, fordi docker cli bare fungerer over https. Å fy... det finnes selvfølgelig alternativer for å lagre bildet lokalt via docker save og bare send bildet via scp... Men det er mange kroppsbevegelser. Og dessuten ser det ut som en "krykke"-løsning til ditt eget depot dukker opp
  • docker-compose. Det er kun nødvendig for å kjøre containere. Det er alt. Han kan ikke gjøre noe annet. Docker-compose har en haug med versjoner av filene sine, sin egen syntaks. Uansett hvor deklarativt det er, vil jeg ikke lese dokumentasjonen deres. Jeg trenger det ikke noe annet sted.
  • når de jobber i et team, skriver de fleste en Dockerfil veldig skjevt, forstår ikke hvordan den er bufret, legger til alt de trenger og ikke trenger til bildet, arver fra bilder som ikke er i Dockerhub eller et privat depot, lager noen docker-compose filer med databaser og ingenting vedvarer. Samtidig erklærer utviklerne stolt at Docker er kult, alt fungerer lokalt for dem, og HR skriver viktig i stillingen: "Vi bruker Docker og vi trenger en kandidat med slik arbeidserfaring."
  • Jeg er konstant hjemsøkt av tanker om å heve alt i Docker: postgresql, kafka, redis. Det er synd at ikke alt fungerer i containere, ikke alt er lett å konfigurere og kjøre. Dette støttes av tredjepartsutviklere, og ikke av leverandørene selv. Og forresten, spørsmålet oppstår umiddelbart: leverandører bekymrer seg ikke for å opprettholde produktene sine i Docker, hvorfor er dette, kanskje de vet noe?
  • Spørsmålet oppstår alltid om beholderdataenes persistens. og så tenker du, skal jeg bare montere vertskatalogen eller lage et docker-volum eller lage en databeholder som er nå deprecated? Hvis jeg monterer en katalog, må jeg sørge for at uid og gid til brukeren i containeren samsvarer med IDen til brukeren som startet containeren, ellers vil filene som er opprettet av containeren bli opprettet med rotrettigheter. Hvis jeg bruker volume da vil dataene ganske enkelt bli opprettet i noen /usr/* og det blir samme historie med uid og gid som i det første tilfellet. Hvis du starter en tredjepartskomponent, må du lese dokumentasjonen og se etter svaret på spørsmålet: "i hvilke beholderkataloger skriver komponenten filer?"

Jeg har alltid ikke likt det faktum at jeg måtte tukle med Docker for lenge på det innledende stadiet: Jeg fant ut hvordan jeg skulle starte containere, hvilke bilder jeg skulle starte fra, laget Make-filer som inneholdt aliaser til lange Docker-kommandoer. Jeg hatet docker-compose fordi jeg ikke ønsket å lære et annet verktøy i docker-økosystemet. OG docker-compose up Det plaget meg, spesielt hvis de fortsatt møttes der build konstruksjoner, i stedet for allerede sammensatte bilder. Alt jeg egentlig ønsket var å lage et produkt effektivt og raskt. Men jeg kunne ikke finne ut hvordan jeg bruker docker.

Vi introduserer Ansible

Nylig (for tre måneder siden) jobbet jeg med et DevOps-team, hvor nesten alle medlemmer hadde en negativ holdning til Docker. Av grunner:

  • docker-regler iptables (selv om du kan deaktivere det i daemon.json)
  • docker er buggy og vi vil ikke kjøre den i produksjon
  • hvis docker-demonen krasjer, krasjer alle containere med infrastruktur tilsvarende
  • ikke behov for docker
  • hvorfor docker hvis det er Ansible og virtuelle maskiner

I samme jobb ble jeg kjent med et annet verktøy - Ansible. Jeg hørte om det en gang, men jeg prøvde ikke å skrive mine egne lekebøker. Og nå begynte jeg å skrive oppgavene mine og da endret synet mitt seg totalt! Fordi jeg innså: Ansible har moduler for å kjøre de samme docker-beholderne, bildebyggene, nettverkene osv., og containere kan kjøres ikke bare lokalt, men også på eksterne servere! Min glede visste ingen grenser - jeg fant et NORMALT verktøy og kastet Makefile- og docker-compose-filene mine, de ble erstattet med yaml-oppgaver. Koden ble redusert ved å bruke konstruksjoner som loop, whenOsv

Docker for å kjøre tredjepartskomponenter som databaser

Jeg ble nylig kjent med ssh-tunneler. Det viste seg at det er veldig enkelt å "videre" porten til en ekstern server til en lokal port. Den eksterne serveren kan enten være en maskin i skyen eller en virtuell maskin som kjører i VirtualBox. Hvis min kollega eller jeg trenger en database (eller en annen tredjepartskomponent), kan vi ganske enkelt starte serveren med denne komponenten og slå den av når serveren ikke er nødvendig. Portvideresending gir samme effekt som en database som kjører i en docker-container.

Denne kommandoen videresender min lokale port til en ekstern server som kjører postgresql:

ssh -L 9000:localhost:5432 [e-postbeskyttet]

Bruk av en ekstern server løser problemet med teamutvikling. En slik server kan brukes av flere utviklere samtidig, de trenger ikke å kunne konfigurere postgresql, forstå Docker og andre forviklinger. På en ekstern server kan du installere den samme databasen i selve Docker, hvis det er vanskelig å installere en spesifikk versjon. Alt utviklere trenger er å gi ssh-tilgang!

Jeg leste nylig at SSH-tunneler er en begrenset funksjonalitet til en vanlig VPN! Du kan ganske enkelt installere OpenVPN eller andre VPN-implementeringer, sette opp infrastrukturen og gi den til utviklere for bruk. Dette er så kult!

Heldigvis gir AWS, GoogleCloud og andre deg et års gratis bruk, så bruk dem! De er billige hvis du slår dem av når de ikke er i bruk. Jeg har alltid lurt på hvorfor jeg skulle trenge en ekstern server som gcloud, det ser ut til at jeg fant dem.

Som en lokal virtuell maskin kan du bruke den samme Alpine, som brukes aktivt i docker-containere. Vel, eller noen andre lette distribusjoner for å få maskinen til å starte opp raskere.

Bunnlinjen: du kan og bør kjøre databaser og andre infrastrukturgoder på eksterne servere eller i virtualbox. Jeg trenger ikke docker for disse formålene.

Litt om docker-bilder og distribusjon

Jeg har allerede skrevet artikkel der jeg ønsket å formidle at bruk av docker-bilder ikke gir noen garanti. Docker-bilder er bare nødvendig for å lage en docker-beholder. Hvis du oppgraderer til et docker-bilde, oppgraderer du til å bruke docker-containere, og du vil bare bruke dem.

Har du sett noe sted hvor programvareutviklere porterer produktene sine kun i et docker-bilde?
Resultatet av de fleste produkter er binære filer for en bestemt plattform; de legges ganske enkelt til docker-bildet, som arves fra ønsket plattform. Har du noen gang lurt på hvorfor det er så mange lignende bilder på dockerhub? Skriv inn nginx for eksempel, du vil se 100500 XNUMX bilder fra forskjellige personer. Disse menneskene utviklet ikke nginx selv, de la rett og slett til offisiell nginx til docker-bildet sitt og krydret det med sine egne konfigurasjoner for å gjøre det lettere å lansere containere.

Generelt kan du ganske enkelt lagre den i tgz, hvis noen trenger å kjøre den i docker, så la dem legge til tgz i Dockerfilen, arve fra ønsket miljø og lage flere buns som ikke endrer selve applikasjonen i tgz. Alle som vil lage et docker-bilde vil vite hva tgz er og hva han trenger for å fungere. Dette er hvordan jeg bruker docker her

Bunnlinjen: Jeg trenger ikke docker-register, jeg vil bruke en slags S3 eller bare fillagring som google drive/dropbox

Docker i CI

Alle selskapene jeg har jobbet for er like. De er vanligvis dagligvare. Det vil si at de har én applikasjon, én teknologistabel (vel, kanskje et par eller tre programmeringsspråk).

Disse selskapene bruker docker på sine servere der CI-prosessen kjører. Spørsmål: Hvorfor trenger du å bygge prosjekter i en docker-container på serverne dine? Hvorfor ikke bare forberede et miljø for byggingen, for eksempel skrive en Ansible-spillebok som vil installere de nødvendige versjonene av nodejs, php, jdk, kopiere ssh-nøkler osv. til serveren der byggingen skal foregå?

Nå forstår jeg at dette skyter meg selv i foten, for docker bringer ikke noe overskudd med sin isolasjon. Problemer jeg møtte med CI i docker:

  • igjen trenger du et docker-bilde for å bygge. du må se etter et bilde eller skrive din egen dockerfil.
  • 90 % at du trenger for å videresende noen ssh-nøkler, hemmelige data som du ikke vil skrive til docker-bildet.
  • beholderen er opprettet og dør, alle cacher går tapt sammen med den. neste build vil laste ned alle prosjektavhengighetene på nytt, noe som er tidkrevende og ineffektivt, og tid er penger.

Utviklere bygger ikke prosjekter i docker-containere (jeg var en gang en så fan, egentlig synes jeg synd på meg selv tidligere xD). I java er det mulig å ha flere versjoner og endre dem med én kommando til den du trenger nå. Det er det samme i nodejs, det er nvm.

Utgang

Jeg tror at docker er et veldig kraftig og fleksibelt verktøy, dette er ulempen (høres rart ut, ja). Med dens hjelp kan bedrifter lett bli hektet på den og bruke den der det trengs og ikke er nødvendig. Utviklere lanserer containerne sine, noen av miljøene deres, så flyter det hele jevnt inn i CI og produksjon. DevOps-teamet skriver en slags kode for å kjøre disse beholderne.

Bruk kun docker på den nyligste trinn i arbeidsflyten din, ikke dra den inn i prosjektet i begynnelsen. Det løser ikke forretningsproblemene dine. Han vil bare flytte problemene til ET ANNET nivå og tilby sine egne løsninger, du vil gjøre dobbeltarbeid.

Når docker er nødvendig: Jeg kom til den konklusjonen at docker er veldig flinke til å optimalisere en gitt prosess, men ikke til å bygge grunnleggende funksjonalitet

Hvis du fortsatt bestemmer deg for å bruke docker, gjør du følgende:

  • vær ekstremt forsiktig
  • ikke tving utviklere til å bruke docker
  • lokaliser bruken på ett sted, ikke spre den over alle Dockefile og docker-compose repositories

PS:

Takk for at du leste, jeg ønsker deg gjennomsiktige beslutninger i dine saker og produktive arbeidsdager!

Kilde: www.habr.com

Legg til en kommentar