
La premiÚre étape du déploiement dans Kubernetes consiste à placer votre application dans un conteneur. Dans cette série, nous allons examiner comment créer une image de conteneur petite et sécurisée.
Avec Docker, créer des images de conteneurs n'a jamais été aussi simple. Spécifiez une image de base, ajoutez vos modifications et créez le conteneur.

Bien que cette méthode soit idéale pour commencer, utiliser des images de base par défaut peut entraßner des problÚmes de sécurité avec de grandes images remplies de vulnérabilités.
De plus, la plupart des images Docker utilisent Debian ou Ubuntu comme image de base, ce qui offre une excellente compatibilité et une adaptation facile (le fichier Docker ne nécessite que deux lignes de code), mais ces images de base peuvent ajouter des centaines de mégaoctets de surcharge à votre conteneur. Par exemple, un simple fichier d'application node.js Go « hello-world » pÚse environ 700 mégaoctets, alors que la taille réelle de votre application n'est que de quelques mégaoctets.

Ainsi, toute cette surcharge supplémentaire est un gaspillage d'espace numérique et un excellent refuge pour les vulnérabilités et les erreurs de sécurité. Par conséquent, examinons deux façons de réduire la taille de l'image du conteneur.
La premiĂšre consiste Ă utiliser des images de base de petite taille, la seconde Ă appliquer le modĂšle de conception Builder Pattern. L'utilisation d'images de base plus petites est probablement le moyen le plus simple de rĂ©duire la taille de votre conteneur. Il est probable que le langage ou la pile que vous utilisez fournisse une image d'application originale beaucoup plus petite que l'image par dĂ©faut. Jetons un coup d'Ćil Ă notre conteneur node.js.

Par défaut, l'image de base Docker node:8 pÚse 670 Mo, tandis que l'image node:8-alpine ne pÚse que 65 Mo, soit dix fois moins. En utilisant une image de base Alpine plus petite, vous réduisez considérablement la taille de votre conteneur. Alpine est une distribution Linux légÚre et petite, trÚs appréciée des utilisateurs de Docker, car elle est compatible avec de nombreuses applications tout en maintenant la taille des conteneurs à un minimum. Contrairement à l'image Docker standard « node », « node:alpine » supprime de nombreux fichiers et programmes auxiliaires, ne conservant que ceux nécessaires au fonctionnement de votre application.
Pour passer Ă une image de base plus petite, mettez simplement Ă jour le fichier Docker pour commencer Ă travailler avec la nouvelle image de base :

Désormais, contrairement à l'ancienne image onbuild, vous devez copier votre code dans le conteneur et installer toutes les dépendances. Dans le nouveau fichier Docker, le conteneur commence avec l'image node:alpine, crée ensuite un répertoire pour le code, installe les dépendances à l'aide du gestionnaire de paquets NPM et, enfin, exécute server.js.

Cet aggiornamento permet d'obtenir un conteneur de taille dix fois plus petite. Si votre langage de programmation ou votre stack ne présente pas de fonction permettant de réduire l'image de base, utilisez Alpine Linux. Cela vous donnera également la possibilité de gérer complÚtement le contenu du conteneur. Utiliser des images de base de petite taille est un excellent moyen de créer rapidement de petits conteneurs. Mais vous pouvez obtenir une réduction encore plus importante en utilisant le pattern Builder.

Dans les langages interprĂ©tĂ©s, le code source est d'abord passĂ© Ă l'interprĂ©teur, puis exĂ©cutĂ© directement. Dans les langages compilĂ©s, le code source est d'abord transformĂ© en code compilĂ©. Par consĂ©quent, la compilation utilise souvent des outils qui ne sont en rĂ©alitĂ© pas nĂ©cessaires Ă l'exĂ©cution du code. Cela signifie que vous pouvez complĂštement Ă©liminer ces outils du conteneur final. Cela peut ĂȘtre rĂ©alisĂ© en utilisant le pattern Builder.

Le code est généré dans le premier conteneur et est compilé. Ensuite, le code compilé est emballé dans le conteneur final sans les compilateurs et les outils nécessaires pour la compilation de ce code. Passons cet processus à une application Go. Tout d'abord, nous allons passer de l'image onbuild à Alpine Linux.

Dans le nouveau fichier Docker, le conteneur commence par l'image golang:alpine. Ensuite, il crée un répertoire pour le code, y copie le code source, compile celui-ci et exécute l'application. Ce conteneur est beaucoup plus petit que le conteneur onbuild, mais il contient encore le compilateur et d'autres outils Go, qui ne nous sont en réalité pas nécessaires. Par conséquent, extrayons simplement le programme compilé et emballons-le dans notre propre conteneur.

Vous pouvez remarquer quelque chose d'étrange dans ce fichier Docker : il contient deux lignes FROM. La premiÚre section de 4 lignes ressemble exactement à l'ancien fichier Docker, sauf qu'elle utilise le mot clé AS pour nommer cette étape. Dans la section suivante, il y a une nouvelle ligne FROM, permettant de démarrer une nouvelle image, en utilisant Raw alpine comme image de base au lieu de golang:alpine.
Raw Alpine Linux n'a pas de certificats SSL installés, ce qui provoquera l'échec de la plupart des appels API via le protocole HTTPS, donc installons quelques certificats racines CA.
Et maintenant, la partie intéressante : pour copier le code compilé du premier conteneur vers le second, on peut simplement utiliser la commande COPY, située à la 5Úme ligne de la deuxiÚme section. Elle ne copiera qu'un fichier d'application et ne touchera pas aux outils Go. Le nouveau fichier Docker multi-étapes contiendra une image de conteneur d'à peine 12 mégaoctets alors que l'image de conteneur d'origine faisait 700 mégaoctets, ce qui représente une grande différence !
Ainsi, l'utilisation de petites images de base et du modÚle Builder sont d'excellents moyens de créer des conteneurs beaucoup plus petits sans avoir à faire beaucoup de travail.
Il est possible qu'en fonction de la pile de l'application, il existe d'autres façons de rĂ©duire la taille de l'image et du conteneur, mais les petits conteneurs ont-ils vraiment un avantage mesurable ? Examinons deux aspects oĂč les petits conteneurs sont extrĂȘmement efficaces â les performances et la sĂ©curitĂ©.
Pour évaluer l'augmentation des performances, examinons la durée du processus de création d'un conteneur, de son insertion dans un registre (push) et de son extraction ultérieure (pull). Vous pouvez voir qu'un conteneur de plus petite taille a un avantage indéniable par rapport à un conteneur de plus grande taille.

Docker va mettre en cache les couches, donc les constructions suivantes se feront trÚs rapidement. Cependant, dans de nombreux systÚmes CI utilisés pour construire et tester des conteneurs, les couches ne sont pas mises en cache, ce qui représente donc un gain de temps significatif. Comme vous pouvez le voir, le temps de construction d'un conteneur de grande taille, en fonction de la puissance de votre machine, varie de 34 à 54 secondes, tandis qu'avec un conteneur réduit grùce au Builder Pattern, il est compris entre 23 et 28 secondes. Pour ce type d'opérations, le gain de performance sera de 40 à 50 %. Donc, pensez simplement combien de fois vous créez et testez votre code.
Une fois le conteneur construit, vous devez insérer son image (push container image) dans le registre de conteneurs afin de l'utiliser ensuite dans votre cluster Kubernetes. Je recommande d'utiliser le registre de conteneurs de Google.

Avec le Google Container Registry (GCR), vous ne payez que pour le stockage « brut » et le rĂ©seau, et aucun frais supplĂ©mentaire n'est facturĂ© pour la gestion des conteneurs. C'est confidentiel, sĂ©curisĂ© et trĂšs rapide. GCR utilise de nombreuses astuces pour accĂ©lĂ©rer l'opĂ©ration pull. Comme vous pouvez le voir, l'insertion de l'image du conteneur Docker Container Image en utilisant go:onbuild, selon la performance de l'ordinateur, prendra entre 15 et 48 secondes, tandis que la mĂȘme opĂ©ration avec un conteneur de plus petite taille prendra entre 14 et 16 secondes, et pour les machines moins performantes, l'avantage en termes de vitesse augmente de trois fois. Pour les grandes machines, le temps est Ă peu prĂšs le mĂȘme, car GCR utilise un cache global pour la base d'images partagĂ©e, ce qui signifie que vous n'avez pas besoin de les tĂ©lĂ©charger du tout. Dans un ordinateur Ă faible puissance, le CPU est le goulot d'Ă©tranglement, donc l'avantage d'utiliser des conteneurs rĂ©duits est ici beaucoup plus perceptible.
Si vous utilisez GCR, je vous recommande vivement d'appliquer Google Container Builder (GCB) comme partie de votre systĂšme de construction.

Comme vous pouvez le voir, son utilisation permet d'obtenir des rĂ©sultats bien meilleurs dans la rĂ©duction de la durĂ©e de l'opĂ©ration Build+Push, mĂȘme par rapport Ă une machine performante - dans ce cas, le processus de construction et d'envoi de conteneurs vers l'hĂŽte est presque deux fois plus rapide. De plus, vous bĂ©nĂ©ficiez chaque jour de 120 minutes de construction gratuites, ce qui satisfait dans la plupart des cas les besoins en crĂ©ation de conteneurs.
Nous arrivons maintenant Ă la mĂ©trique de performance la plus importante - la vitesse d'extraction, ou de tĂ©lĂ©chargement des conteneurs Pull. Et si le temps passĂ© sur l'opĂ©ration push ne vous prĂ©occupe pas trop, la durĂ©e du processus pull a un impact considĂ©rable sur la performance globale du systĂšme. Supposons que vous ayez un cluster de trois nĆuds et qu'il y ait une panne sur l'un d'entre eux. Si vous utilisez un systĂšme de gestion tel que Google Kubernetes Engine, il remplacera automatiquement le nĆud dĂ©faillant par un nouveau. Cependant, ce nouveau nĆud sera complĂštement vide, et vous devrez y dĂ©placer tous vos conteneurs pour qu'il commence Ă fonctionner. Si l'opĂ©ration pull prend beaucoup de temps, alors durant ce temps, votre cluster fonctionnera avec une performance rĂ©duite.
Il existe de nombreux cas oĂč cela peut se produire : l'ajout d'un nouveau nĆud au cluster, la mise Ă jour des nĆuds ou mĂȘme le passage Ă un nouveau conteneur pour le dĂ©ploiement. Ainsi, minimiser le temps d'extraction pull devient un facteur clĂ©. Il est indĂ©niable qu'un petit conteneur se tĂ©lĂ©charge beaucoup plus rapidement qu'un grand. Si vous utilisez plusieurs conteneurs dans un cluster Kubernetes, l'Ă©conomie de temps peut ĂȘtre trĂšs significative.

Regardez la comparaison suivante : l'opĂ©ration pull avec de petits conteneurs prend de 4 Ă 9 fois moins de temps en fonction de la puissance de la machine, qu'une opĂ©ration similaire utilisant go:onbuild. L'utilisation d'images conteneurs de base de petite taille accĂ©lĂšre considĂ©rablement le temps et la vitesse auxquels de nouveaux nĆuds Kubernetes peuvent ĂȘtre dĂ©ployĂ©s et mis en ligne.
Examinons la question de la sécurité. On considÚre que les conteneurs plus petits sont beaucoup plus sûrs que les grands, car ils ont une surface d'attaque plus réduite. Est-ce vraiment le cas ? L'une des fonctionnalités les plus utiles de Google Container Registry est la possibilité de scanner automatiquement vos conteneurs à la recherche de vulnérabilités. Il y a quelques mois, j'ai créé des conteneurs onbuild et multistades, alors voyons s'il y a des failles à cet égard.

Le rĂ©sultat est impressionnant : seulement 3 vulnĂ©rabilitĂ©s modĂ©rĂ©es ont Ă©tĂ© dĂ©tectĂ©es dans le petit conteneur, contre 16 critiques et 376 autres dans le grand conteneur. En examinant le contenu du grand conteneur, il est Ă©vident que la plupart des problĂšmes de sĂ©curitĂ© n'ont rien Ă voir avec notre application mais sont liĂ©s Ă des programmes que nous n'utilisons mĂȘme pas. C'est donc cela que les gens entendent par grande surface d'attaque.

La conclusion est claire : créez des conteneurs de petite taille, car ils offrent de réels avantages en termes de performance et de sécurité pour votre systÚme.

Un peu de publicitĂ© đ
Merci de rester avec nous. Aimez-vous nos articles ? Voulez-vous voir plus de contenu intĂ©ressant ? Soutenez-nous en passants une commande ou en nous recommandant Ă des amis, , un Ă©quivalent unique des serveurs d'entrĂ©e de gamme, conçu pour vous : (options disponibles avec RAID1 et RAID10, jusqu'Ă 24 cĆurs et jusqu'Ă 40 Go DDR4).
Dell R730xd deux fois moins cher dans le data center Equinix Tier IV Ă Amsterdam ? Uniquement chez nous aux Pays-Bas ! Dell R420 â 2x E5-2430 2.2GHz 6C 128Go DDR3 2x960Go SSD 1Gbps 100To â Ă partir de 99 $ ! Lisez sur
Source : habr.com
