Examinons quelques-unes des meilleures pratiques à suivre lors de l’utilisation de conteneurs.
La conteneurisation est largement utilisée par plusieurs organisations pour déployer des applications à l’intérieur d’un conteneur. Ces conteneurs sont populaires parce qu’ils sont très légers. Pour tirer le meilleur parti des conteneurs, vous devez suivre certaines bonnes pratiques lorsque vous travaillez avec eux.
Utilisez une image de base stable
Grâce à Docker, la création d’ images de conteneurs n’a jamais été aussi simple.
Spécifiez votre image de base, ajoutez vos modifications et construisez votre conteneur. Bien que cette méthode soit idéale pour débuter, l’utilisation des images de base par défaut peut conduire à des images volumineuses et pleines de failles de sécurité. Évitez également d’utiliser l’image docker “Latest”, car il y a de fortes chances qu’elle contienne un bogue.
Debian ou Ubuntu sont utilisées comme image de base par la plupart des images Docker. Elles sont très utiles en termes de compatibilité et de facilité d’intégration, mais ces images de base peuvent ajouter des centaines de mégaoctets à votre conteneur.
Par exemple, les applications simples Node.js et Go, “hello world”, pèsent environ 700 mégaoctets. Votre application ne fait probablement que quelques mégaoctets. Tous ces frais généraux supplémentaires sont donc de l’espace perdu et une excellente cachette pour les failles de sécurité et les bogues.
Si votre langage de programmation ou votre pile de programmes n’offre pas d’option pour une petite image de base, vous pouvez construire votre conteneur en utilisant Alpine Linux brut comme point de départ. Cela vous permet également de contrôler totalement ce qui se trouve à l’intérieur de vos conteneurs.
Réduire la taille des images de conteneurs
L’utilisation d’images de base plus petites est probablement le moyen le plus simple de réduire la taille de vos conteneurs.
Il est probable que le langage ou la pile que vous utilisez fournisse une image officielle beaucoup plus petite que l’image par défaut. Prenons l’exemple du conteneur Node.js. Passer de l’image par défaut node:latest à node:14-alpine réduit la taille de notre image de base de près de dix fois.
vs…..
Dans le nouveau fichier Docker, le conteneur démarre avec l’image node:alpine, crée un répertoire pour le code, installe les dépendances avec NPM, et enfin, démarre le serveur Node.js. Avec cette mise à jour, le conteneur résultant est presque dix fois plus petit.
Vous créez un conteneur encore plus léger en utilisant le modèle du constructeur. Avec les langages interprétatifs, le code source est envoyé à un interprète, puis il est exécuté directement. Mais avec un langage compilé, le code source est préalablement transformé en code compilé.
Or, avec les langages de compilation, l’étape de compilation nécessite souvent des outils qui ne sont pas nécessaires pour exécuter le code. Cela signifie que vous pouvez supprimer complètement ces outils du conteneur final. Pour ce faire, vous pouvez utiliser le modèle du constructeur. Le premier conteneur construit le code, puis le code compilé est empaqueté dans le conteneur final sans tous les compilateurs et outils nécessaires à la réalisation du code compilé.
L’utilisation de petites images de base et du modèle de construction sont d’excellents moyens de créer des conteneurs beaucoup plus petits sans beaucoup de travail.
Marquez vos images de conteneurs
Le marquage Docker est un outil exceptionnellement puissant pour nous lorsqu’il s’agit de gérer nos images. Il permet de gérer les différentes versions d’une image Docker. Voici un exemple de construction d’une image Docker avec le nom de tag v1.0.1
docker build -t geekflare/ubuntu:v1.0.1
Deux types de balises sont utilisés : Les balises stables Les balises uniques.
Utilisez les balises stables pour maintenir l’image de base du conteneur. Évitez d’utiliser ces balises pour les conteneurs de déploiement car ces balises recevront des mises à jour fréquemment, ce qui peut entraîner des incohérences dans l’environnement de production.
Utilisez des balises uniques pour les déploiements. En utilisant des balises uniques, vous pouvez facilement faire évoluer votre cluster de production vers de nombreux nœuds. Cela évite les incohérences et les hôtes ne tireront aucune autre version d’image Docker.
De plus, comme bonne pratique, vous devriez verrouiller les balises de l’image déployée en définissant write-enable à false. Cela permet de ne pas supprimer l’image déployée du registre par erreur.
Sécurité des conteneurs
Vous trouverez ci-dessous les points fondamentaux pour vous assurer que le conteneur est sécurisé.
- Vérifiez l’authenticité de tout logiciel que vous installez dans votre conteneur
- Utilisez des images docker signées ou des images avec une somme de contrôle valide.
- Assurez-vous que l’URL utilise HTTPS si vous utilisez un dépôt tiers.
- Incluez les bonnes clés GPG avant d’utiliser votre gestionnaire de paquets pour mettre à jour les paquets
- N’exécutez jamais vos applications en tant que root. Vous devez toujours utiliser la directive user à l’intérieur du fichier docker pour vous assurer que vous abandonnez les privilèges de votre utilisateur.
- N’exécutez pas SSH à l’intérieur de votre conteneur.
- Faites en sorte que le système de fichiers soit en lecture seule.
- Utilisez les espaces de noms pour diviser votre cluster.
Le Center for Internet Security (CIS) a fourni un benchmark Docker pour évaluer la sécurité d’un conteneur Docker. Ils ont fourni un script open-source appelé Docker Bench for Security, que vous pouvez exécuter pour vérifier le niveau de sécurité d’un conteneur Docker.
Une application par conteneur
Les machines virtuelles permettent d’exécuter plusieurs choses en parallèle, mais lorsqu’il s’agit de conteneurs, vous devez exécuter une seule application dans un seul conteneur. Par exemple, si vous exécutez une application MEAN dans un environnement conteneurisé, elle doit avoir un conteneur pour MongoDB, un conteneur pour Express.js, un conteneur pour Angular et un conteneur pour Node.js.
Même les conteneurs peuvent exécuter plusieurs applications en parallèle, mais vous pouvez alors tirer parti du modèle de conteneur. Vous trouverez ci-dessous une représentation correcte et une représentation erronée de l’exécution d’applications dans un conteneur.
Les conteneurs sont conçus pour avoir un cycle de vie similaire à celui de l’application qu’ils exécutent. Lorsque le conteneur démarre, l’application démarre. Lorsqu’un conteneur s’arrête, l’application s’arrête également.
Exécuter des conteneurs sans état
Les conteneurs sont fondamentalement conçus pour être sans état. Dans ce cas, les données persistantes qui contiennent des informations sur l’état du conteneur sont stockées en dehors du conteneur. Les fichiers peuvent être stockés dans un magasin d’objets tel que le stockage en nuage, pour stocker les informations relatives à la session de l’utilisateur, vous pouvez utiliser une base de données à faible latence telle que Redis et vous pouvez également attacher un disque externe pour le stockage au niveau du bloc.
En conservant le stockage à l’extérieur du conteneur, vous pouvez facilement arrêter ou détruire un conteneur sans craindre de perdre des données.
Si vous utilisez des conteneurs sans état, il est très facile de les migrer ou de les faire évoluer en fonction des besoins de l’entreprise.
Conclusion
Si vous construisez un environnement de production Docker, vérifiez comment le sécuriser.