Best practices voor Kubernetes. Kleine containers maken

Best practices voor Kubernetes. Kleine containers maken

De eerste stap bij het implementeren naar Kubernetes is het plaatsen van uw applicatie in een container. In deze serie bekijken we hoe u een kleine, veilige containerimage kunt maken.
Dankzij Docker is het maken van containerimages nog nooit zo eenvoudig geweest. Geef een basisimage op, voeg uw wijzigingen toe en maak een container.

Best practices voor Kubernetes. Kleine containers maken

Hoewel deze techniek geweldig is om mee aan de slag te gaan, kan het gebruik van standaardbasisimages leiden tot onveilig werken met grote images vol kwetsbaarheden.

Bovendien gebruiken de meeste images in Docker Debian of Ubuntu als basisimage, en hoewel dit uitstekende compatibiliteit en eenvoudige aanpassing biedt (een Docker-bestand heeft slechts twee regels code nodig), kunnen basisimages honderden megabytes aan extra belasting aan uw container toevoegen. Een eenvoudig node.js-bestand voor een Go "hello-world"-applicatie is bijvoorbeeld ongeveer 700 megabytes, terwijl uw daadwerkelijke applicatie slechts een paar megabytes groot is.

Best practices voor Kubernetes. Kleine containers maken

Al deze extra werklast is dus een verspilling van digitale ruimte en een geweldige schuilplaats voor beveiligingsproblemen en bugs. Laten we dus eens kijken naar twee manieren om de grootte van een containerimage te verkleinen.

De eerste is het gebruik van kleine basisafbeeldingen, de tweede is het gebruik van het Builder-patroon. Het gebruik van kleinere basisimages is waarschijnlijk de gemakkelijkste manier om de grootte van uw container te verkleinen. Hoogstwaarschijnlijk levert de taal of stapel die u gebruikt een originele applicatie-image op die veel kleiner is dan de standaardimage. Laten we eens kijken naar onze node.js-container.

Best practices voor Kubernetes. Kleine containers maken

Standaard is in Docker de basisafbeeldingsgrootte van knooppunt: 8 670 MB, en de afbeeldingsgrootte van knooppunt: 8-alpine slechts 65 MB, dat wil zeggen 10 keer kleiner. Door de kleinere Alpine-basisafbeelding te gebruiken, verkleint u de grootte van uw container aanzienlijk. Alpine is een kleine en lichtgewicht Linux-distributie die erg populair is onder Docker-gebruikers omdat deze compatibel is met veel applicaties en tegelijkertijd de containers klein houdt. In tegenstelling tot de standaard Docker "node"-afbeelding verwijdert "node:alpine" een groot aantal servicebestanden en programma's, waardoor alleen de bestanden en programma's overblijven die voldoende zijn om uw applicatie uit te voeren.

Om naar een kleinere basisimage te gaan, updatet u eenvoudigweg het Dockerbestand om met de nieuwe basisimage te gaan werken:

Best practices voor Kubernetes. Kleine containers maken

Nu moet u, in tegenstelling tot de oude onbuild-image, uw code naar de container kopiëren en eventuele afhankelijkheden installeren. In een nieuwe Dockerfile begint de container met een node:alpine-image, maakt vervolgens een map voor de code, installeert afhankelijkheden met behulp van de NPM-pakketbeheerder en voert ten slotte server.js uit.

Best practices voor Kubernetes. Kleine containers maken

Deze upgrade resulteert in een container die 10 keer kleiner is. Als uw programmeertaal of stack geen basisfunctionaliteit voor beeldreductie heeft, gebruik dan Alpine Linux. Het biedt ook de mogelijkheid om de inhoud van de container volledig te beheren. Het gebruik van kleine basisimages is een geweldige manier om snel kleine containers te maken. Maar een nog grotere reductie kan worden bereikt met behulp van het Builder-patroon.

Best practices voor Kubernetes. Kleine containers maken

In geïnterpreteerde talen wordt de broncode eerst aan de tolk doorgegeven en vervolgens direct uitgevoerd. In gecompileerde talen wordt de broncode eerst omgezet in gecompileerde code. Bij het compileren worden echter vaak tools gebruikt die niet echt nodig zijn om de code uit te voeren. Dit betekent dat u deze gereedschappen volledig uit de uiteindelijke container kunt verwijderen. Hiervoor kunt u Builder Pattern gebruiken.

Best practices voor Kubernetes. Kleine containers maken

De code wordt in de eerste container gemaakt en gecompileerd. De gecompileerde code wordt vervolgens verpakt in een definitieve container zonder de compilers en tools die nodig zijn om die code te compileren. Laten we een Go-applicatie door dit proces laten lopen. Eerst gaan we van de onbuild-image naar Alpine Linux.

Best practices voor Kubernetes. Kleine containers maken

In het nieuwe Dockerfile begint de container met een golang:alpine-afbeelding. Vervolgens wordt er een directory voor de code gemaakt, wordt deze naar de broncode gekopieerd, wordt die broncode opgebouwd en wordt de applicatie uitgevoerd. Deze container is veel kleiner dan de onbuild-container, maar bevat nog steeds de compiler en andere Go-tools die we niet echt nodig hebben. Laten we dus gewoon het gecompileerde programma uitpakken en in zijn eigen container plaatsen.

Best practices voor Kubernetes. Kleine containers maken

Mogelijk valt je iets vreemds op in dit Docker-bestand: het bevat twee FROM-regels. Het eerste gedeelte van vier regels ziet er precies hetzelfde uit als het vorige Docker-bestand, behalve dat het het sleutelwoord AS gebruikt om deze fase een naam te geven. De volgende sectie heeft een nieuwe FROM-regel om een ​​nieuwe afbeelding te starten, waarbij we in plaats van de golang:alpine-afbeelding Raw alpine als basisafbeelding zullen gebruiken.

Raw Alpine Linux heeft geen geïnstalleerde SSL-certificaten, waardoor de meeste API-aanroepen via HTTPS mislukken, dus laten we enkele root-CA-certificaten installeren.

Nu komt het leuke gedeelte: om de gecompileerde code van de eerste container naar de tweede te kopiëren, kunt u eenvoudigweg de opdracht COPY gebruiken die zich op regel 5 van de tweede sectie bevindt. Er wordt slechts één toepassingsbestand gekopieerd en dit heeft geen invloed op de Go-hulpprogramma's. Het nieuwe Docker-bestand met meerdere fasen zal een containerimage bevatten die slechts 12 megabytes groot is, vergeleken met de originele containerimage die 700 megabytes was, wat een groot verschil is!
Het gebruik van kleine basisimages en Builder Pattern zijn dus geweldige manieren om zonder veel werk veel kleinere containers te maken.
Het is mogelijk dat er, afhankelijk van de applicatiestack, aanvullende manieren zijn om de afbeeldings- en containergrootte te verkleinen, maar hebben kleine containers echt een meetbaar voordeel? Laten we eens kijken naar twee gebieden waarop kleine containers uiterst effectief zijn: prestaties en beveiliging.

Om de prestatieverbetering te evalueren, moet u rekening houden met de duur van het proces van het maken van een container, het invoegen ervan in het register (push) en het vervolgens ophalen ervan (pull). Je ziet dat een kleinere container een duidelijk voordeel heeft ten opzichte van een grotere container.

Best practices voor Kubernetes. Kleine containers maken

Docker zal de lagen in de cache opslaan, zodat daaropvolgende builds erg snel zullen zijn. Veel CI-systemen die worden gebruikt om containers te bouwen en te testen, slaan echter geen lagen op in de cache, waardoor er aanzienlijke tijdsbesparingen optreden. Zoals u kunt zien, bedraagt ​​de tijd voor het bouwen van een grote container, afhankelijk van de kracht van uw machine, 34 tot 54 seconden, en bij gebruik van een container wordt deze verkort met behulp van het Builder-patroon - van 23 tot 28 seconden. Voor dit soort activiteiten zal de productiviteitsstijging 40-50% bedragen. Denk er dus eens over na hoe vaak u uw code bouwt en test.

Nadat de container is gebouwd, moet u de image (push container image) naar het containerregister pushen, zodat u deze vervolgens in uw Kubernetes-cluster kunt gebruiken. Ik raad aan om Google Container Registry te gebruiken.

Best practices voor Kubernetes. Kleine containers maken

Met Google Container Registry (GCR) betaalt u alleen voor ruwe opslag en netwerken, en zijn er geen extra kosten voor containerbeheer. Het is privé, veilig en zeer snel. GCR gebruikt veel trucs om de pull-operatie te versnellen. Zoals u kunt zien, duurt het invoegen van een Docker Container Image-container met go:onbuild 15 tot 48 seconden, afhankelijk van de computerprestaties, en dezelfde bewerking met een kleinere container duurt 14 tot 16 seconden, en voor minder productieve machines het voordeel in bedrijfssnelheid neemt drie keer toe. Voor grotere machines is de tijd ongeveer hetzelfde, omdat GCR een globale cache gebruikt voor een gedeelde database met afbeeldingen, wat betekent dat u ze helemaal niet hoeft te laden. Bij een computer met een laag vermogen is de CPU de bottleneck, dus het voordeel van het gebruik van kleine containers is hier veel groter.

Als u GCR gebruikt, raad ik u ten zeerste aan Google Container Builder (GCB) te gebruiken als onderdeel van uw bouwsysteem.

Best practices voor Kubernetes. Kleine containers maken

Zoals u kunt zien, kunt u met het gebruik ervan veel betere resultaten behalen bij het verkorten van de duur van de Build+Push-bewerking dan zelfs een productieve machine - in dit geval wordt het proces van het bouwen en verzenden van containers naar de host bijna tweemaal versneld . Bovendien krijgt u elke dag 2 gratis bouwminuten, waarmee u in de meeste gevallen aan uw containerbouwbehoeften kunt voldoen.

Vervolgens komt de belangrijkste prestatiestatistiek: de snelheid van het ophalen of downloaden van Pull-containers. En als de tijd die aan een push-operatie wordt besteed niet veel uitmaakt, heeft de lengte van het pull-proces een serieuze impact op de algehele systeemprestaties. Stel dat u een cluster van drie knooppunten hebt en dat er één uitvalt. Als u een beheersysteem zoals Google Kubernetes Engine gebruikt, wordt het dode knooppunt automatisch vervangen door een nieuw knooppunt. Dit nieuwe knooppunt zal echter volledig leeg zijn en u zult al uw containers erin moeten slepen voordat het begint te werken. Als de pull-bewerking lang genoeg duurt, zal uw cluster de hele tijd met lagere prestaties draaien.

Er zijn veel gevallen waarin dit kan gebeuren: het toevoegen van een nieuw knooppunt aan een cluster, het upgraden van knooppunten of zelfs het overschakelen naar een nieuwe container voor implementatie. Het minimaliseren van de trekextractietijd wordt dus een sleutelfactor. Het valt niet te ontkennen dat een kleine container veel sneller downloadt dan een grote. Als u meerdere containers in een Kubernetes-cluster draait, kan de tijdsbesparing aanzienlijk zijn.

Best practices voor Kubernetes. Kleine containers maken

Kijk eens naar deze vergelijking: een pull-operatie op kleine containers kost 4-9 keer minder tijd, afhankelijk van het vermogen van de machine, dan dezelfde operatie met go:onbuild. Het gebruik van gedeelde, kleine containerbasisimages versnelt aanzienlijk de tijd en snelheid waarmee nieuwe Kubernetes-nodes kunnen worden geïmplementeerd en online komen.

Laten we eens kijken naar de kwestie van de veiligheid. Kleinere containers worden als veel veiliger beschouwd dan grotere, omdat ze een kleiner aanvalsoppervlak hebben. Is het echt? Een van de handigste functies van Google Container Registry is de mogelijkheid om uw containers automatisch te scannen op kwetsbaarheden. Een paar maanden geleden heb ik zowel onbuild- als multistage-containers gemaakt, dus laten we kijken of daar kwetsbaarheden zijn.

Best practices voor Kubernetes. Kleine containers maken

Het resultaat is verbluffend: slechts 3 middelgrote kwetsbaarheden werden gedetecteerd in een kleine container, en 16 kritieke en 376 andere kwetsbaarheden werden gevonden in een grote container. Als we naar de inhoud van een grote container kijken, kunnen we zien dat de meeste beveiligingsproblemen niets met onze applicatie te maken hebben, maar gerelateerd zijn aan programma's die we niet eens gebruiken. Dus als mensen het hebben over een groot aanvalsoppervlak, bedoelen ze dat ook.

Best practices voor Kubernetes. Kleine containers maken

De conclusie is duidelijk: bouw kleine containers omdat deze echte prestatie- en beveiligingsvoordelen voor uw systeem bieden.

Best practices voor Kubernetes. Organisatie van Kubernetes met naamruimte

Sommige advertenties 🙂

Bedankt dat je bij ons bent gebleven. Vind je onze artikelen leuk? Wil je meer interessante inhoud zien? Steun ons door een bestelling te plaatsen of door vrienden aan te bevelen, cloud VPS voor ontwikkelaars vanaf $ 4.99, een unieke analoog van servers op instapniveau, die door ons voor u is uitgevonden: De hele waarheid over VPS (KVM) E5-2697 v3 (6 kernen) 10 GB DDR4 480 GB SSD 1 Gbps vanaf $ 19 of hoe een server te delen? (beschikbaar met RAID1 en RAID10, tot 24 cores en tot 40GB DDR4).

Dell R730xd 2x goedkoper in Equinix Tier IV datacenter in Amsterdam? Alleen hier 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV vanaf $199 in Nederland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - vanaf $99! Lees over Hoe infrastructuur corp te bouwen. klasse met het gebruik van Dell R730xd E5-2650 v4-servers ter waarde van 9000 euro voor een cent?

Bron: www.habr.com

Voeg een reactie