Créer des images Docker dans Kubernetes
Vitalis Ogbonna
3 mai 2022
0 minutes de lectureHéberger une plateforme CI/CD sur Kubernetes est de plus en plus courant chez les ingénieurs. Cette approche fait gagner du temps grâce à l’automatisation, garantit des déploiements cohérents et facilite la supervision et la gestion des microservices. Toutefois, la création d’images de conteneurs dans des clusters Kubernetes comporte des difficultés techniques qui nécessitent des solutions de contournement.
Dans cet article, nous allons explorer différentes façons de créer des images Docker dans un cluster Kubernetes pour les processus CI/CD. Nous aborderons également les avantages et les inconvénients de ces méthodes.
Outils de création d’images Docker dans Kubernetes
Si vous avez déjà créé une image de conteneur, vous avez probablement exécuté une commande comme docker build. Puis, lorsque vous avez voulu automatiser ce processus, vous avez peut-être configuré vos outils CI/CD pour utiliser également docker build. Cette méthode fonctionne avec les serveurs CI simples, mais vous voudrez peut-être à terme déployer une plateforme CI basée sur Kubernetes.
Le problème, c’est que le daemon Docker n’est pas librement accessible depuis le cluster Kubernetes. Nous devons donc utiliser d’autres solutions, tout en veillant à ne pas compromettre l’intégrité de notre application ni notre infrastructure.
Plusieurs outils sont disponibles :
Buildah est spécialisé dans la création d’images Open Container Initiative (OCI). Ses commandes reproduisent toutes les instructions d’un Dockerfile. Il permet de créer des images avec ou sans Dockerfile, sans nécessiter de privilèges root.
img est un outil autonome, sans daemon et sans privilèges, qui crée des images de conteneurs compatibles avec Dockerfile et OCI. Il gère efficacement le cache et peut exécuter plusieurs étapes de build en parallèle, car il utilise en interne le solveur DAG de BuildKit pour créer les images.
kaniko crée des images de conteneurs à partir d’un Dockerfile, dans un conteneur ou un cluster Kubernetes. kaniko ne dépend pas d’un daemon Docker et exécute chaque instruction du Dockerfile entièrement dans l’espace utilisateur.
Docker in Docker est une méthode qui permet d’exécuter Docker dans Docker. Elle crée des conteneurs Docker dans des clusters Kubernetes en montant le fichier
/var/run/docker.socken tant que volume dans un conteneur Docker.Sysbox Enterprise Edition (Sysbox-EE) de Nestybox permet aux conteneurs sans privilèges d’exécuter des charges de travail telles que Docker, systemd et Kubernetes comme des machines virtuelles.
BuildKit CLI crée des images OCI et Docker, mono-architecture ou multi-architecture, dans des clusters Kubernetes. Il remplace la commande docker build par kubectl build pour créer des images dans les clusters Kubernetes.
Jib pour les conteneurs Java crée des images de conteneurs sans Dockerfile ni installation de Docker. Des plugins Jib sont disponibles pour Maven et Gradle. Jib est également disponible sous forme de bibliothèque Java.
KO est un outil rapide et simple de création d’images de conteneurs pour les applications Go. Il crée des images en exécutant efficacement go build sur votre machine locale, sans nécessiter l’installation de Docker.
Examinons deux méthodes courantes pour créer des images Docker dans un cluster Kubernetes : Docker in Docker et kaniko.
Docker in Docker
La méthode Docker in Docker (DIND) est couramment utilisée dans les pipelines CI/CD, où les images sont créées et envoyées après la réussite d’un build de code. Cette méthode sert également à intégrer Jenkins aux pipelines de déploiement, par exemple pendant les tests dans des environnements sandbox.
L’approche DIND peut sembler pratique et simple. Toutefois, l’ancien employé de Docker et contributeur de DIND Jérôme Petazzoni soutient que Docker a créé cette approche pour accélérer les processus internes et évoque des problèmes de sécurité pour déconseiller son utilisation en production.
À l’origine, Docker a conçu les conteneurs pour qu’ils s’exécutent en mode privilégié avec l’approche DIND. Le daemon Docker s’exécute en tant que root ; le conteneur s’exécute donc en tant que root sur l’hôte. Toute personne ayant accès au socket Docker dispose d’un accès root, ce qui lui permet d’exécuter n’importe quel logiciel, de créer de nouveaux utilisateurs et d’accéder à tout ce qui est connecté au conteneur. Les conteneurs sont ainsi exposés à des attaques susceptibles de se propager dans toute l’architecture.
De plus, depuis que Kubernetes a officiellement supprimé la prise en charge de Dockershim, le montage de docker.sock sur l’hôte risque de ne plus fonctionner à l’avenir, sauf si nous ajoutons Docker à tous les nœuds Kubernetes. AWS propose un outil pratique pour détecter l’utilisation du socket Docker dans les clusters.
La méthode DIND pose également des problèmes de compatibilité avec les pilotes de stockage. De plus, la gestion des caches d’images peut être difficile, car nous devons extraire les images Docker à chaque lancement d’un build.
Pour résoudre ces problèmes, vous pouvez utiliser des outils qui ne nécessitent pas de runtime de conteneur pour créer des images. kaniko, la solution open source de Google pour créer des images Docker dans un cluster Kubernetes, en est un exemple.
kaniko
kaniko crée des images de conteneurs à partir d’un Dockerfile, dans un conteneur ou un cluster Kubernetes. Il ne dépend pas d’un daemon Docker et exécute chaque instruction du Dockerfile entièrement dans l’espace utilisateur. Vous pouvez ainsi créer des images de conteneurs dans des environnements où l’exécution d’un daemon Docker est difficile ou peu sûre, comme dans les clusters Kubernetes standard.
Nous allons illustrer le processus avec kaniko à l’aide d’outils gratuits et accessibles au public. Pour suivre ce tutoriel, vous aurez besoin des éléments suivants :
Docker Desktop installé sur votre PC, avec Kubernetes activé
Un compte Docker Hub valide pour que le pod kaniko puisse s’authentifier et envoyer l’image Docker
Un compte GitHub permettant à kaniko d’accéder au Dockerfile
Nous allons utiliser cet exemple de projet sur GitHub pour illustrer le fonctionnement de kaniko. Clonez-le avec la commande git clone https://github.com/agavitalis/kaniko-kubernetes.git pour suivre les étapes.
Cet exemple de projet comprend deux fichiers et un fichier README.md :
#sample project directory
kaniko-build-demo
dockerfilepod.ymlREADME.md
Le fichier dockerfile contient le code suivant pour les commandes de création de l’image :
Dans le code de configuration de kaniko, l’exécuteur d’images kaniko utilise la dernière version. Nous avons également indiqué l’emplacement de notre Dockerfile et de notre dépôt d’images, ainsi que le nom des identifiants de notre registre d’images dans Kubernetes.
Fonctionnement de kaniko
kaniko fonctionne de manière assez simple. L’image de l’exécuteur kaniko gcr.io/kaniko-project/executor:latest exécute les instructions du Dockerfile pour créer des images. Elle lit le Dockerfile spécifié, extrait l’image de base définie dans l’instruction FROM (ubuntu dans ce cas) dans le système de fichiers du conteneur indiqué, puis envoie les images vers un registre.
Après avoir extrait l’image de base indiquée par la directive FROM, kaniko exécute séparément chaque instruction du Dockerfile et prend un instantané de l’espace utilisateur après chaque exécution. À chaque exécution, il ajoute ensuite la couche de l’instantané à la couche de base.
Nous définissons ces paramètres dans le fichier pod.yml :
context: emplacement du Dockerfile. Dans notre cas, le Dockerfile se trouve à la racine du dépôt. Utilisez les variablesGIT_USERNAMEetGIT_PASSWORD(jeton d’API) pour vous authentifier auprès de dépôts Git privés.destination: remplacez <dockerhub-username> par votre nom d’utilisateur afin que kaniko puisse envoyer l’image vers le registre Docker Hub.docker-file: chemin d’accès au Dockerfile, relatif au contexte.
Maintenant que nous comprenons le fonctionnement de kaniko, créons un Secret Kubernetes. Nous l’utiliserons ensuite pour créer et déployer une image.
Créer un Secret Kubernetes Docker Hub
Nous devons créer un Secret Kubernetes pour que kaniko puisse accéder à Docker Hub. Pour cela, nous avons besoin des informations suivantes :
docker-server: serveur du registre Docker qui hébergera vos images. Si vous utilisez Docker Hub, cette valeur doit êtrehttps://index.docker.io/v1/.docker-username: nom d’utilisateur de votre registre Docker.docker-password: mot de passe de votre registre Docker.docker-email: adresse e-mail configurée dans votre registre Docker.
Exécutez les commandes suivantes en remplaçant chaque variable par la valeur appropriée :
La commande ci-dessus monte ce Secret dans le pod kaniko pour faciliter l’authentification lors de l’envoi de l’image créée vers un registre Docker. Vous devriez recevoir un message de confirmation semblable à celui-ci :

Déployer un pod kaniko pour créer une image Docker
Lançons maintenant le build en créant le pod dans notre cluster Kubernetes. Déployez le pod à l’aide de la commande suivante :

Cette commande lance le processus de création de l’image, puis l’envoie vers le registre Docker spécifié.
Vous pouvez répertorier les pods disponibles dans votre cluster Kubernetes à l’aide de la commande suivante :

Cette commande affiche les pods disponibles, leur état et leur ancienneté. (Notez qu’une erreur peut survenir si kaniko utilise des identifiants incorrects ou envoie l’image vers le mauvais dépôt.)
Si vous le souhaitez, utilisez la commande kubectl delete pod <pod-name> pour supprimer les pods existants.
Pour obtenir des informations détaillées sur le pod que vous venez de déployer, utilisez la commande suivante :

Vous pouvez également consulter le journal de build à l’aide de la commande suivante :

Consultez l’aide-mémoire kubectl pour découvrir d’autres commandes permettant d’explorer et de dépanner votre cluster, ainsi que d’obtenir plus d’informations à son sujet.
Rendez-vous ensuite sur Docker Hub pour vérifier que tout a fonctionné et que vos images ont bien été déployées sur Docker.

Nous avons créé et déployé avec succès notre image Docker depuis un cluster Kubernetes à l’aide de kaniko !
Snyk pour la sécurité des conteneurs
kaniko offre une méthode sécurisée pour créer des images Docker dans des clusters Kubernetes. Il récupère le Dockerfile dans le contexte de build défini, crée l’image et envoie le résultat vers un registre d’images. Son puissant système de cache accélère la création de vos images.
Même si vous n’utilisez pas de méthode non sécurisée pour créer vos images Docker dans Kubernetes, vous pouvez rester exposé aux vulnérabilités de la sécurité Kubernetes. Snyk Container propose une solution fiable de sécurité des conteneurs, qui détecte et corrige les vulnérabilités dans les applications cloud natives. Snyk s’intègre parfaitement à Docker, GitHub, Kubernetes, Jenkins et à d’autres outils pour assurer la sécurité de votre application et de votre infrastructure.
La sécurité des conteneurs, pensée pour les développeurs
Snyk détecte et corrige automatiquement les vulnérabilités dans les images de conteneurs et les workloads Kubernetes.
