Kubernetes bedste praksis. Oprettelse af små containere

Kubernetes bedste praksis. Oprettelse af små containere

Det første trin i implementeringen til Kubernetes er at placere din applikation i en container. I denne serie vil vi se på, hvordan du kan skabe et lille, sikkert containerbillede.
Takket være Docker har det aldrig været nemmere at oprette containerbilleder. Angiv et basisbillede, tilføj dine ændringer, og opret en beholder.

Kubernetes bedste praksis. Oprettelse af små containere

Selvom denne teknik er fantastisk til at komme i gang, kan brug af standardbasebilleder føre til usikkert arbejde med store billeder fulde af sårbarheder.

Derudover bruger de fleste billeder i Docker Debian eller Ubuntu til basisbilledet, og selvom dette giver fremragende kompatibilitet og nem tilpasning (en Docker-fil tager kun to linjer kode), kan basisbilleder tilføje hundredvis af megabyte ekstra belastning til din container. For eksempel er en simpel node.js-fil til en Go "hello-world"-applikation omkring 700 megabyte, mens din faktiske applikation kun er et par megabyte stor.

Kubernetes bedste praksis. Oprettelse af små containere

Så al denne ekstra arbejdsbyrde er spild af digital plads og et godt gemmested for sikkerhedssårbarheder og fejl. Så lad os se på to måder at reducere størrelsen på et containerbillede på.

Den første er brugen af ​​små basisbilleder, den anden er brugen af ​​Builder Pattern. Brug af mindre basisbilleder er sandsynligvis den nemmeste måde at reducere størrelsen på din beholder. Det sprog eller stak, du bruger, giver sandsynligvis et originalt programbillede, der er meget mindre end standardbilledet. Lad os tage et kig på vores node.js container.

Kubernetes bedste praksis. Oprettelse af små containere

Som standard i Docker er node:8-basebilledstørrelsen 670 MB, og noden: 8-alpine billedstørrelse er kun 65 MB, det vil sige 10 gange mindre. Ved at bruge det mindre Alpine basebillede vil du reducere størrelsen på din beholder betydeligt. Alpine er en lille og let Linux-distribution, der er meget populær blandt Docker-brugere, fordi den er kompatibel med mange applikationer, mens den holder beholderne små. I modsætning til standard Docker "node"-billedet, fjerner "node:alpine" en masse servicefiler og programmer og efterlader kun dem, der er tilstrækkelige til at køre din applikation.

For at flytte til et mindre basisbillede skal du blot opdatere Dockerfilen for at begynde at arbejde med det nye basisbillede:

Kubernetes bedste praksis. Oprettelse af små containere

Nu, i modsætning til det gamle onbuild-billede, skal du kopiere din kode ind i containeren og installere eventuelle afhængigheder. I en ny Dockerfile starter containeren med et node:alpine-billede, opretter derefter en mappe til koden, installerer afhængigheder ved hjælp af NPM-pakkehåndteringen og kører til sidst server.js.

Kubernetes bedste praksis. Oprettelse af små containere

Denne opgradering resulterer i en container, der er 10 gange mindre i størrelse. Hvis dit programmeringssprog eller din stak ikke har grundlæggende billedreduktionsfunktionalitet, skal du bruge Alpine Linux. Det vil også give mulighed for fuldt ud at styre indholdet af beholderen. Brug af små basisbilleder er en fantastisk måde til hurtigt at skabe små beholdere. Men endnu større reduktion kan opnås ved at bruge Builder-mønsteret.

Kubernetes bedste praksis. Oprettelse af små containere

På tolkede sprog sendes kildekoden først til tolken og udføres derefter direkte. På kompilerede sprog konverteres kildekoden først til kompileret kode. Men kompilering bruger ofte værktøjer, der faktisk ikke er nødvendige for at køre koden. Det betyder, at du helt kan fjerne disse værktøjer fra den endelige beholder. Du kan bruge Builder Pattern til dette.

Kubernetes bedste praksis. Oprettelse af små containere

Koden oprettes i den første container og kompileres. Den kompilerede kode pakkes derefter i en endelig beholder uden de kompilatorer og værktøjer, der er nødvendige for at kompilere denne kode. Lad os køre en Go-applikation gennem denne proces. Først går vi fra onbuild-billedet til Alpine Linux.

Kubernetes bedste praksis. Oprettelse af små containere

I den nye Dockerfile starter containeren med et golang:alpine billede. Den opretter derefter en mappe til koden, kopierer den ind i kildekoden, bygger den kildekode og kører applikationen. Denne container er meget mindre end den indbyggede container, men den indeholder stadig compileren og andre Go-værktøjer, som vi egentlig ikke har brug for. Så lad os bare udpakke det kompilerede program og lægge det i sin egen beholder.

Kubernetes bedste praksis. Oprettelse af små containere

Du kan måske bemærke noget mærkeligt i denne Docker-fil: den indeholder to FROM-linjer. Den første 4 linjers sektion ser nøjagtig ud som den forrige Dockerfile, bortset fra at den bruger AS-nøgleordet til at navngive denne fase. Næste afsnit har en ny FROM-linje for at starte et nyt billede, hvor vi i stedet for golang:alpine-billedet vil bruge Raw alpine som basisbillede.

Raw Alpine Linux har ingen SSL-certifikater installeret, hvilket vil få de fleste API-kald over HTTPS til at mislykkes, så lad os installere nogle rod-CA-certifikater.

Nu kommer den sjove del: for at kopiere den kompilerede kode fra den første container til den anden, kan du blot bruge COPY-kommandoen placeret på linje 5 i den anden sektion. Det vil kun kopiere én applikationsfil og vil ikke påvirke Go hjælpeværktøjer. Den nye flertrins Docker-fil vil indeholde et containerbillede, der kun er 12 megabyte i størrelse, sammenlignet med det originale containerbillede, der var på 700 megabyte, hvilket er en stor forskel!
Så brug af små basisbilleder og Builder Pattern er gode måder at skabe meget mindre beholdere på uden en masse arbejde.
Det er muligt, at der afhængigt af applikationsstakken er yderligere måder at reducere billede og containerstørrelse på, men har små containere virkelig en målbar fordel? Lad os se på to områder, hvor små containere er ekstremt effektive – ydeevne og sikkerhed.

For at evaluere ydeevneforøgelsen skal du overveje varigheden af ​​processen med at oprette en container, indsætte den i registreringsdatabasen (push) og derefter hente den derfra (pull). Du kan se, at en mindre container har en klar fordel i forhold til en større container.

Kubernetes bedste praksis. Oprettelse af små containere

Docker vil cache lagene, så efterfølgende builds vil være meget hurtige. Men mange CI-systemer, der bruges til at bygge og teste containere, cacherer ikke lag, så der er betydelige tidsbesparelser. Som du kan se, er tiden til at bygge en stor container, afhængigt af din maskines kraft, fra 34 til 54 sekunder, og når du bruger en container reduceret ved hjælp af Builder-mønsteret - fra 23 til 28 sekunder. For operationer af denne art vil produktivitetsstigningen være 40-50%. Så tænk bare på, hvor mange gange du bygger og tester din kode.

Når containeren er bygget, skal du skubbe dens image (push container image) ind i containerregistret, så du derefter kan bruge den i din Kubernetes-klynge. Jeg anbefaler at bruge Google Container Registry.

Kubernetes bedste praksis. Oprettelse af små containere

Med Google Container Registry (GCR) betaler du kun for rå opbevaring og netværk, og der er ingen ekstra containeradministrationsgebyrer. Det er privat, sikkert og meget hurtigt. GCR bruger mange tricks til at fremskynde pull-operationen. Som du kan se, vil det tage fra 15 til 48 sekunder at indsætte en Docker Container Image-container ved hjælp af go:onbuild, afhængigt af computerens ydeevne, og den samme handling med en mindre container vil tage fra 14 til 16 sekunder, og for mindre produktive maskiner fordelen i driftshastighed øges med 3 gange. For større maskiner er tiden omtrent den samme, da GCR bruger en global cache til en delt database med billeder, hvilket betyder, at du slet ikke behøver at indlæse dem. I en lavstrømscomputer er CPU'en flaskehalsen, så fordelen ved at bruge små beholdere er meget større her.

Hvis du bruger GCR, anbefaler jeg stærkt at bruge Google Container Builder (GCB) som en del af dit byggesystem.

Kubernetes bedste praksis. Oprettelse af små containere

Som du kan se, giver dens brug dig mulighed for at opnå meget bedre resultater med at reducere varigheden af ​​Build+Push-operationen end selv en produktiv maskine - i dette tilfælde accelereres processen med at bygge og sende containere til værten med næsten 2 gange . Derudover får du 120 gratis byggeminutter hver dag, hvilket dækker dine behov for containerbygning i de fleste tilfælde.

Dernæst kommer den vigtigste præstationsmåling – hastigheden for at hente eller downloade Pull-beholdere. Og hvis du ikke bekymrer dig meget om den tid, der bruges på en push-operation, så har længden af ​​pull-processen en alvorlig indflydelse på den samlede systemydelse. Lad os sige, at du har en klynge med tre noder, og en af ​​dem fejler. Hvis du bruger et administrationssystem såsom Google Kubernetes Engine, vil det automatisk erstatte den døde node med en ny. Denne nye node vil dog være helt tom, og du bliver nødt til at trække alle dine containere ind i den, for at den begynder at virke. Hvis pull-operationen tager lang nok tid, vil din klynge køre med lavere ydeevne hele tiden.

Der er mange tilfælde, hvor dette kan ske: tilføjelse af en ny node til en klynge, opgradering af noder eller endda skift til en ny container til implementering. Minimering af trækudtrækningstiden bliver således en nøglefaktor. Det er ubestrideligt, at en lille container downloades meget hurtigere end en stor. Hvis du kører flere containere i en Kubernetes-klynge, kan tidsbesparelsen være betydelig.

Kubernetes bedste praksis. Oprettelse af små containere

Tag et kig på denne sammenligning: en trækoperation på små containere tager 4-9 gange kortere tid, afhængigt af maskinens effekt, end den samme operation med go:onbuild. Brug af delte, små containerbasebilleder fremskynder markant den tid og hastighed, hvormed nye Kubernetes-noder kan implementeres og komme online.

Lad os se på spørgsmålet om sikkerhed. Mindre containere anses for at være meget mere sikre end større, fordi de har en mindre angrebsflade. Er det virkelig? En af de mest nyttige funktioner i Google Container Registry er muligheden for automatisk at scanne dine containere for sårbarheder. For et par måneder siden oprettede jeg både onbuild og multi-stage containere, så lad os se, om der er nogle sårbarheder der.

Kubernetes bedste praksis. Oprettelse af små containere

Resultatet er forbløffende: Kun 3 mellemstore sårbarheder blev opdaget i en lille container, og 16 kritiske og 376 andre sårbarheder blev fundet i en stor container. Hvis vi ser på indholdet af en stor container, kan vi se, at de fleste sikkerhedsproblemer ikke har noget med vores applikation at gøre, men er relateret til programmer, som vi ikke engang bruger. Så når folk taler om en stor angrebsflade, er det det, de mener.

Kubernetes bedste praksis. Oprettelse af små containere

Takeaway er klar: Byg små containere, fordi de giver reelle ydeevne og sikkerhedsfordele til dit system.

Kubernetes bedste praksis. Kubernetes-organisation med navneområde

Nogle annoncer 🙂

Tak fordi du blev hos os. Kan du lide vores artikler? Vil du se mere interessant indhold? Støt os ved at afgive en ordre eller anbefale til venner, cloud VPS for udviklere fra $4.99, en unik analog af entry-level servere, som blev opfundet af os til dig: Hele sandheden om VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps fra $19 eller hvordan deler man en server? (tilgængelig med RAID1 og RAID10, op til 24 kerner og op til 40 GB DDR4).

Dell R730xd 2 gange billigere i Equinix Tier IV datacenter i Amsterdam? Kun her 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV fra $199 i Holland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - fra $99! Læse om Hvordan man bygger infrastruktur corp. klasse med brug af Dell R730xd E5-2650 v4-servere til en værdi af 9000 euro for en krone?

Kilde: www.habr.com

Tilføj en kommentar