Hei!
Jeg vil egentlig gå rett til temaet, men det er bedre å fortelle litt om historien min:
Entry
Jeg er en programmerer med erfaring i utvikling av frontend-applikasjoner med én side, Scala/Java og NodeJS på serveren.
I ganske lang tid (i et par år nå, helt sikkert) mente jeg at Docker var himmelsk og et skikkelig kult verktøy, og absolutt alle utviklere burde kunne bruke det. Og av dette følger det at alle utviklere burde ha Docker på sin lokale maskin. Hva med min mening, se gjennom de ledige stillingene som er utlyst på samme sted. Annenhver nevner Docker, og hvis du kjenner det, vil det være ditt konkurransefortrinn 😉
På veien møtte jeg mange mennesker med ulike holdninger til Docker og økosystemet. Noen sa at det var en praktisk ting som garanterte kryssplattform. Andre forsto ikke hvorfor de skulle kjøre i containere og hvilken profitt de ville få ut av det, og andre brydde seg ikke i det hele tatt og gadd ikke (de bare skrev kode og dro hjem – jeg misunner dem, forresten :) )
Årsaker til bruk
Hvorfor brukte jeg docker? Sannsynligvis av følgende grunner:
- databaseoppstart, 99 % av applikasjonene bruker dem
- kjører nginx for frontend-distribusjon og backend-proxy
- Du kan pakke applikasjonen inn i et docker-image, slik at applikasjonen min vil fungere overalt der det er docker, distribusjonsproblemet er løst med en gang.
- tjenesteoppdagelse rett ut av boksen, du kan lage mikrotjenester, hver container (koblet til det felles nettverket) kan enkelt nå en annen via alias, veldig praktisk
- Det er gøy å lage en beholder og «leke» med den.
Det jeg alltid IKKE liker med Docker:
- For at applikasjonen min skal fungere, trenger jeg docker på serveren. Hvorfor trenger jeg dette hvis applikasjonene mine fungerer på jre eller nodejs, og miljøet for dem allerede er på serveren?
- Hvis jeg vil kjøre mitt (private) lokalt bygde image på en ekstern server, trenger jeg mitt eget docker-repository, jeg må ha et register som kjører et sted, og jeg må også konfigurere https, fordi docker cli bare fungerer over https. Å faen ... det finnes selvfølgelig alternativer for å lagre imaget lokalt via
docker saveog bare dumpe bildet via scp... Men det er mye arbeid. Og det ser også ut som en "jukseløsning" inntil du har ditt eget repository. docker-composeDen er bare nødvendig for å kjøre containere. Det er alt. Den kan ikke gjøre noe annet.Docker-composehar en rekke versjoner av filene sine, sin egen syntaks. Uansett hvor deklarativ den er, vil jeg ikke lese dokumentasjonen deres. Jeg trenger den ikke noe annet sted.- Når de jobber i et team, skriver de fleste Dockerfile veldig skjevt, forstår ikke hvordan det er mellomlagret, legger til alt som trengs og ikke trengs i bildet, arver fra bilder som ikke er i dockerhub eller et privat arkiv, lager noen
docker-composefiler med databaser, og ingenting vedvarer. Samtidig erklærer utviklerne stolt at Docker er kult, alt fungerer lokalt for dem, og HR skriver viktig i den ledige stillingen: «Vi bruker Docker, og vi trenger en kandidat med slik arbeidserfaring». - stadig hjemsøkt av tanker om å heve alt og alle 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 dukker umiddelbart opp, leverandørene gidder ikke å støtte produktene sine i Docker, hvorfor er det slik, kanskje de vet noe?
- Det er alltid et spørsmål om containerdatapersistens. Og så tenker man, bør jeg bare montere vertskatalogen eller opprette et dockervolum eller lage en datacontainer som nå er
deprecatedHvis jeg monterer en katalog, må jeg sørge for at uid og gid til brukeren i containeren samsvarer med ID-en til brukeren som startet containeren, ellers vil filene som opprettes av containeren bli opprettet med roteierrettigheter. Hvis jeg brukervolumeså vil dataene ganske enkelt bli opprettet på et eller annet sted/usr/*og det vil være den samme historien med uid og gid som i det første tilfellet. Hvis du kjører en tredjepartskomponent, må du lese dokumentasjonen og se etter et svar på spørsmålet: "og i hvilke containerkataloger skriver komponenten filer?"
Jeg har alltid mislikt å måtte bruke for mye tid på å fikle med Docker. i den innledende fasenJeg fant ut hvordan jeg skulle starte containere, hvilke bilder jeg skulle starte fra, og lagde Makefiles som inneholdt aliaser for lange docker-kommandoer. Jeg hatet docker-compose fordi jeg ikke ville lære et annet verktøy fra docker-økosystemet. Og docker-compose up det gjorde meg nervøs, spesielt hvis vi møttes der build strukturer, ikke forhåndsbygde bilder. Alt jeg egentlig ville var å lage et produkt effektivt og raskt. Men jeg klarte ikke helt å finne ut hvordan jeg skulle bruke Docker.
Bli kjent med Ansible
Nylig (for 3 måneder siden) jobbet jeg med et DevOps-team, hvor nesten alle medlemmene hadde en negativ holdning til Docker. Av følgende grunner:
- docker redigerer iptables (selv om du kan deaktivere det i daemon.json)
- Docker har feil, og vi kjører den ikke i produksjon.
- Hvis docker-daemonen krasjer, krasjer alle containere med infrastruktur deretter
- det er ikke behov for docker
- Hvorfor Docker hvis det finnes Ansible og virtuelle maskiner?
I samme jobb ble jeg også kjent med et annet verktøy – Ansible. Jeg hadde hørt om det før, men hadde aldri prøvd å skrive mine egne strategier. Og nå har jeg begynt å skrive mine egne oppgaver, og visjonen min har endret seg fullstendig! Fordi jeg innså: Ansible har moduler for å kjøre de samme docker-containerne, image-bygg, nettverk osv., og containere kan kjøres ikke bare lokalt, men også på eksterne servere! Jeg var overlykkelig – jeg fant et NORMAL-verktøy og kastet Makefile- og docker-compose-filene mine, og erstattet dem med yaml-oppgaver. Koden ble redusert ved å bruke konstruksjoner som loop, whenOsv
Docker for å kjøre tredjepartskomponenter som db
Nylig ble jeg kjent med SSH-tunneler. Det viste seg at det er veldig enkelt å "viderekoble" en ekstern serverport 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 jeg eller min kollega trenger en database (eller en annen tredjepartskomponent), kan vi ganske enkelt starte en server med denne komponenten og slå den av når serveren ikke trengs. Portviderekobling gir samme effekt som en database som kjører i en docker-container.
Denne kommandoen videresender min lokale port til en ekstern server med postgresql:
ssh -L 9000:localhost:5432 bruker@eksempel.com
Å bruke en ekstern server løser problemet med teamutvikling. Flere utviklere kan bruke en slik server samtidig, de trenger ikke å kunne konfigurere PostgreSQL, forstå Docker og andre sofistikerte funksjoner. På en ekstern server kan du installere den samme databasen i selve Docker, hvis det er vanskelig å installere en bestemt versjon. Alt utviklerne trenger er å gi SSH-tilgang!
Jeg leste nylig at SSH-tunneler er en begrenset funksjonalitet i et vanlig VPN! Du kan bare sette opp OpenVPN eller andre VPN-implementeringer, konfigurere infrastrukturen og gi den til utviklere. Det 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å hvilke formål jeg ville trenge en ekstern server som gcloud, jeg tror jeg fant dem.
Som en virtuell maskin på den lokale plattformen kan du bruke den samme Alpine-distribusjonen, som brukes aktivt i docker-containere. Eller andre lette distribusjoner for å få maskinen til å starte opp raskere.
Konklusjon: du kan og bør kjøre database og andre infrastruktur-godbiter på eksterne servere eller i VirtualBox. Jeg trenger ikke Docker til disse formålene.
Litt om docker-bilder og distribusjon
Jeg har allerede skrevet der jeg ville formidle at bruk av docker-bilder ikke gir noen garanti. Docker-bilder er bare nødvendige for å opprette en docker-container. Hvis du er sydd på et docker-bilde, så er du sydd på ved hjelp av docker-containere, og du vil bare være med dem.
Har du noen gang sett programvareutviklere portere produktene sine bare i et docker-image?
Resultatet av de fleste produkter er binære filer for en bestemt plattform. De legges ganske enkelt til i docker-imaget som arves fra den ønskede plattformen. Har du noen gang lurt på hvorfor det er så mange lignende bilder i dockerhub? Hvis du for eksempel skriver inn nginx, vil du se 100500 XNUMX bilder fra forskjellige personer. Disse personene utviklet ikke nginx selv, de la ganske enkelt til den offisielle nginx i docker-imaget sitt og krydret det med konfigurasjonene sine for å gjøre det enkelt å lansere containere.
Generelt sett kan du ganske enkelt lagre den i tgz. Hvis noen trenger å kjøre den i docker, kan de legge til tgz i Dockerfile, arve fra det nødvendige miljøet og lage ekstra godbiter som ikke endrer selve applikasjonen i tgz. Den som lager docker-imaget, vet hva denne tgz er og hva den trenger for å fungere. Slik bruker jeg docker.
Konklusjon: Jeg trenger ikke et Docker-register, jeg bruker litt S3 eller bare en fillagringsplass som Google Drive/Dropbox.
Docker i CI
Alle selskapene jeg har jobbet for ligner på hverandre. De er vanligvis produktbaserte. Det vil si at de har én applikasjon, én teknologistabel (vel, kanskje et par eller tre programmeringsspråk).
Disse selskapene bruker Docker på serverne sine der CI-prosessen startes. Spørsmålet er – hvorfor trenger du å bygge prosjekter i en Docker-container på serverne dine? Hvorfor ikke bare forberede miljøet for byggingen, for eksempel skrive en Ansible-playbook som installerer de nødvendige versjonene av nodejs, php, jdk, kopierer ssh-nøkler osv. til serveren der byggingen skal finne sted?
Nå forstår jeg at dette er å skyte seg selv i foten, for Docker gir ingen profitt med sin isolasjon. Problemene med CI i Docker som jeg møtte på:
- trenger igjen docker-image for bygging. trenger å søke etter image eller skrive din egen dockerfil.
- 90 % av at du må videresende noen SSH-nøkler, hemmelige data som du ikke vil skrive til docker-imaget.
- Containeren opprettes og dør, alle mellomlagringsplasser går tapt sammen med den. Den neste byggingen vil laste ned alle prosjektavhengigheter på nytt, og dette er langtekkelig og ineffektivt, og tid er penger.
Utviklere bygger ikke prosjekter i docker-containere (jeg var en gang en slik fan, men jeg synes synd på meg selv før xD). I Java finnes det et alternativ for å ha flere versjoner og endre dem med én kommando til den som trengs nå. I NodeJS er det det samme, det finnes nvm.
Utgang
Jeg synes Docker er et veldig kraftig og fleksibelt verktøy, og det er ulempen (høres rart ut, ja). Med hjelpen blir bedrifter lett «hekta» på det, bruker det der det er nødvendig og unødvendig. Utviklere lanserer containerne sine, deler av miljøet sitt, og så flyter alt jevnt inn i CI, produksjon. DevOps-teamet skriver en slags sykler for å lansere disse containerne.
Bruk docker bare på den aller siste trinn i arbeidsflyten din, ikke dra det inn i prosjektet i begynnelsen. Det vil ikke løse forretningsproblemene dine. Det vil bare flytte problemene til ET ANNET nivå og tilby sine egne løsninger, du vil gjøre dobbelt arbeid.
Når det er behov for dockerJeg kom til den konklusjonen at Docker er veldig god til å optimalisere den innstilte prosessen, men ikke til å bygge grunnleggende funksjonalitet.
Hvis du fortsatt bestemmer deg for å bruke docker, så:
- vær ekstremt forsiktig
- Ikke tving utviklere til å bruke docker
- lokaliser bruken på ett sted, ikke spred den på tvers av alle Dockefile- og docker-compose-repositorier
PS:
- Jeg kom nylig over og de sier at det fungerer veldig bra med Ansible og lar deg forene prosessen med å bygge bilder (inkludert docker-bilder)
Takk for at du leste til slutten, jeg ønsker deg transparente beslutninger i dine saker og produktive arbeidsdager!
Kilde: www.habr.com
