Kubernetes bästa praxis. Skapa små behållare

Kubernetes bästa praxis. Skapa små behållare

Det första steget för att distribuera till Kubernetes är att placera din applikation i en behållare. I den här serien ska vi titta på hur du kan skapa en liten, säker behållarbild.
Tack vare Docker har det aldrig varit enklare att skapa containerbilder. Ange en basbild, lägg till dina ändringar och skapa en behållare.

Kubernetes bästa praxis. Skapa små behållare

Även om den här tekniken är bra för att komma igång, kan användning av standardbasbilder leda till osäkert arbete med stora bilder fulla av sårbarheter.

Dessutom använder de flesta bilder i Docker Debian eller Ubuntu för basbilden, och även om detta ger utmärkt kompatibilitet och enkel anpassning (en Docker-fil tar bara två rader kod), kan basbilder lägga till hundratals megabyte extra belastning till din behållare. Till exempel är en enkel node.js-fil för en Go "hello-world"-applikation cirka 700 megabyte, medan din faktiska applikation bara är några få megabyte stor.

Kubernetes bästa praxis. Skapa små behållare

Så all denna extra arbetsbelastning är ett slöseri med digitalt utrymme och ett bra gömställe för säkerhetssårbarheter och buggar. Så låt oss titta på två sätt att minska storleken på en behållarbild.

Den första är användningen av små basbilder, den andra är användningen av Builder Pattern. Att använda mindre basbilder är förmodligen det enklaste sättet att minska storleken på din behållare. Med största sannolikhet ger språket eller stacken du använder en originalprogrambild som är mycket mindre än standardbilden. Låt oss ta en titt på vår node.js-behållare.

Kubernetes bästa praxis. Skapa små behållare

Som standard i Docker är nod:8-basbildstorleken 670 MB, och noden: 8-alpin bildstorlek är endast 65 MB, det vill säga 10 gånger mindre. Genom att använda den mindre Alpine basbilden kommer du att minska storleken på din behållare avsevärt. Alpine är en liten och lätt Linux-distribution som är mycket populär bland Docker-användare eftersom den är kompatibel med många applikationer samtidigt som den håller behållarna små. Till skillnad från den vanliga Docker "nod"-bilden tar "node:alpine" bort många tjänstefiler och program, och lämnar bara de som är tillräckliga för att köra din applikation.

För att flytta till en mindre basbild, uppdatera helt enkelt Dockerfilen för att börja arbeta med den nya basbilden:

Kubernetes bästa praxis. Skapa små behållare

Nu, till skillnad från den gamla onbuild-bilden, måste du kopiera din kod till behållaren och installera eventuella beroenden. I en ny Dockerfile börjar behållaren med en node:alpin-bild, skapar sedan en katalog för koden, installerar beroenden med hjälp av NPM-pakethanteraren och kör slutligen server.js.

Kubernetes bästa praxis. Skapa små behållare

Denna uppgradering resulterar i en container som är 10 gånger mindre i storlek. Om ditt programmeringsspråk eller stack inte har grundläggande bildreduceringsfunktion, använd Alpine Linux. Det kommer också att ge möjligheten att helt hantera innehållet i behållaren. Att använda små basbilder är ett bra sätt att snabbt skapa små behållare. Men ännu större minskning kan uppnås med hjälp av Builder Pattern.

Kubernetes bästa praxis. Skapa små behållare

På tolkade språk skickas källkoden först till tolken och exekveras sedan direkt. På kompilerade språk konverteras källkoden först till kompilerad kod. Men kompilering använder ofta verktyg som faktiskt inte behövs för att köra koden. Detta innebär att du helt kan ta bort dessa verktyg från den slutliga behållaren. Du kan använda Builder Pattern för detta.

Kubernetes bästa praxis. Skapa små behållare

Koden skapas i den första behållaren och kompileras. Den kompilerade koden paketeras sedan i en slutlig behållare utan de kompilatorer och verktyg som behövs för att kompilera den koden. Låt oss köra en Go-applikation genom denna process. Först går vi från onbuild-bilden till Alpine Linux.

Kubernetes bästa praxis. Skapa små behållare

I den nya Dockerfilen börjar behållaren med en golang:alpin-bild. Den skapar sedan en katalog för koden, kopierar den till källkoden, bygger den källkoden och kör programmet. Den här behållaren är mycket mindre än den onbuild-behållaren, men den innehåller fortfarande kompilatorn och andra Go-verktyg som vi egentligen inte behöver. Så låt oss bara extrahera det kompilerade programmet och lägga det i sin egen behållare.

Kubernetes bästa praxis. Skapa små behållare

Du kanske märker något konstigt i denna Docker-fil: den innehåller två FROM-rader. Den första sektionen med fyra rader ser exakt likadan ut som den tidigare Dockerfilen förutom att den använder nyckelordet AS för att namnge detta stadium. Nästa avsnitt har en ny FROM-rad för att starta en ny bild, där vi istället för golang:alpin-bilden kommer att använda Raw alpine som basbild.

Raw Alpine Linux har inga SSL-certifikat installerade, vilket gör att de flesta API-anrop över HTTPS misslyckas, så låt oss installera några rot-CA-certifikat.

Nu kommer den roliga delen: för att kopiera den kompilerade koden från den första behållaren till den andra kan du helt enkelt använda kommandot COPY som finns på rad 5 i den andra sektionen. Det kopierar bara en applikationsfil och påverkar inte Go-verktygen. Den nya flerstegs Docker-filen kommer att innehålla en containerbild som bara är 12 megabyte stor, jämfört med den ursprungliga containerbilden som var 700 megabyte, vilket är en stor skillnad!
Så att använda små basbilder och Builder Pattern är bra sätt att skapa mycket mindre behållare utan mycket arbete.
Det är möjligt att det, beroende på applikationsstacken, finns ytterligare sätt att minska bild- och behållarstorlek, men har små behållare verkligen en mätbar fördel? Låt oss titta på två områden där små containrar är extremt effektiva – prestanda och säkerhet.

För att utvärdera prestandaökningen, överväg varaktigheten av processen att skapa en behållare, infoga den i registret (push) och sedan hämta den därifrån (pull). Du kan se att en mindre container har en klar fördel jämfört med en större container.

Kubernetes bästa praxis. Skapa små behållare

Docker kommer att cachelagra lagren så efterföljande konstruktioner kommer att vara mycket snabba. Men många CI-system som används för att bygga och testa containrar cachelagrar inte lager, så det finns betydande tidsbesparingar. Som du kan se är tiden för att bygga en stor behållare, beroende på din maskins kraft, från 34 till 54 sekunder, och när du använder en behållare reduceras med hjälp av Builder-mönstret - från 23 till 28 sekunder. För verksamheter av detta slag blir produktivitetsökningen 40-50 %. Så tänk bara på hur många gånger du bygger och testar din kod.

Efter att behållaren har byggts måste du skjuta in dess bild (push container image) i behållarregistret så att du sedan kan använda den i ditt Kubernetes-kluster. Jag rekommenderar att du använder Google Container Registry.

Kubernetes bästa praxis. Skapa små behållare

Med Google Container Registry (GCR) betalar du bara för rålagring och nätverk, och det tillkommer inga ytterligare avgifter för containerhantering. Det är privat, säkert och väldigt snabbt. GCR använder många knep för att påskynda dragoperationen. Som du kan se tar det från 15 till 48 sekunder att sätta in en Docker Container Image-behållare med go:onbuild, beroende på datorns prestanda, och samma operation med en mindre behållare tar från 14 till 16 sekunder, och för mindre produktiva maskiner fördelen i drifthastighet ökar med 3 gånger. För större maskiner är tiden ungefär densamma, eftersom GCR använder en global cache för en delad databas med bilder, vilket innebär att du inte behöver ladda dem alls. I en lågeffektsdator är CPU:n flaskhalsen, så fördelen med att använda små behållare är mycket större här.

Om du använder GCR rekommenderar jag starkt att du använder Google Container Builder (GCB) som en del av ditt byggsystem.

Kubernetes bästa praxis. Skapa små behållare

Som du kan se låter användningen dig uppnå mycket bättre resultat för att minska varaktigheten av Build+Push-operationen än till och med en produktiv maskin - i det här fallet accelereras processen att bygga och skicka behållare till värden med nästan 2 gånger . Dessutom får du 120 gratis byggminuter varje dag, vilket täcker dina containerbyggnadsbehov i de flesta fall.

Därefter kommer det viktigaste prestandamåttet – hastigheten för att hämta, eller ladda ner, Pull-behållare. Och om du inte bryr dig så mycket om tiden som spenderas på en push-operation, så har längden på pull-processen en allvarlig inverkan på systemets totala prestanda. Låt oss säga att du har ett kluster med tre noder och en av dem misslyckas. Om du använder ett hanteringssystem som Google Kubernetes Engine kommer det automatiskt att ersätta den döda noden med en ny. Den här nya noden kommer dock att vara helt tom och du måste dra alla dina behållare in i den för att den ska börja fungera. Om dragoperationen tar tillräckligt lång tid kommer ditt kluster att köras med lägre prestanda hela tiden.

Det finns många fall där detta kan hända: lägga till en ny nod i ett kluster, uppgradera noder eller till och med byta till en ny behållare för distribution. Således blir minimering av dragextraktionstiden en nyckelfaktor. Det är obestridligt att en liten behållare laddas ner mycket snabbare än en stor. Om du kör flera behållare i ett Kubernetes-kluster kan tidsbesparingarna vara betydande.

Kubernetes bästa praxis. Skapa små behållare

Ta en titt på den här jämförelsen: en dragoperation på små containrar tar 4-9 gånger kortare tid, beroende på maskinens kraft, än samma operation med go:onbuild. Genom att använda delade, små behållarbasbilder snabbar man avsevärt upp tiden och hastigheten med vilken nya Kubernetes-noder kan distribueras och komma online.

Låt oss titta på frågan om säkerhet. Mindre containrar anses vara mycket säkrare än större eftersom de har en mindre attackyta. Är det verkligen? En av de mest användbara funktionerna i Google Container Registry är möjligheten att automatiskt skanna dina behållare efter sårbarheter. För några månader sedan skapade jag både onbuild- och flerstegscontainrar, så låt oss se om det finns några sårbarheter där.

Kubernetes bästa praxis. Skapa små behållare

Resultatet är fantastiskt: endast 3 medelstora sårbarheter upptäcktes i en liten behållare, och 16 kritiska och 376 andra sårbarheter hittades i en stor behållare. Om vi ​​tittar på innehållet i en stor behållare kan vi se att de flesta av säkerhetsproblemen inte har något med vår applikation att göra, utan är relaterade till program som vi inte ens använder. Så när folk pratar om en stor attackyta så är det vad de menar.

Kubernetes bästa praxis. Skapa små behållare

Takeaway är tydlig: bygg små containrar eftersom de ger verkliga prestanda- och säkerhetsfördelar till ditt system.

Kubernetes bästa praxis. Organisation av Kubernetes med namnutrymme

Några annonser 🙂

Tack för att du stannar hos oss. Gillar du våra artiklar? Vill du se mer intressant innehåll? Stöd oss ​​genom att lägga en beställning eller rekommendera till vänner, moln VPS för utvecklare från $4.99, en unik analog av ingångsservrar, som uppfanns av oss för dig: Hela sanningen om VPS (KVM) E5-2697 v3 (6 kärnor) 10GB DDR4 480GB SSD 1Gbps från $19 eller hur delar man en server? (tillgänglig med RAID1 och RAID10, upp till 24 kärnor och upp till 40 GB DDR4).

Dell R730xd 2 gånger billigare i Equinix Tier IV datacenter i Amsterdam? Bara här 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV från $199 i Nederländerna! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - från $99! Läs om Hur man bygger infrastructure corp. klass med användning av Dell R730xd E5-2650 v4-servrar värda 9000 XNUMX euro för en slant?

Källa: will.com

Lägg en kommentar