Les images Docker peuvent également être construites dans werf en utilisant le Dockerfile habituel

Mieux vaut tard que jamais. Ou comment nous avons failli commettre une grave erreur, ne pas avoir le support des Dockerfiles ordinaires pour créer des images d'application.



Nous parlerons de werf , un utilitaire GitOps qui s'intègre à n'importe quel système CI / CD et fournit un contrôle sur l'ensemble du cycle de vie de l'application, vous permettant de:

  • Recueillir et publier des images
  • Déployer des applications dans Kubernetes
  • Supprimez les images inutilisées à l'aide de politiques spéciales.

La philosophie du projet est d'assembler des outils de bas niveau en un seul système unifié qui donne aux ingénieurs DevOps le contrôle des applications. Dans la mesure du possible, les utilitaires existants (tels que Helm et Docker) doivent être impliqués. S'il n'y a pas de solution à un problème, nous pouvons créer et maintenir tout ce qui est nécessaire pour cela.

Contexte: votre collectionneur d'images


C'est ce qui s'est passé avec le collecteur d'images dans werf: nous n'avions pas le Dockerfile habituel. Si vous plongez rapidement dans l'historique du projet, ce problème s'est manifesté dans les premières versions de werf (alors encore appelé dapp ).

En créant un outil pour créer des applications dans des images Docker, nous avons rapidement réalisé que le Dockerfile n'était pas adapté à certaines tâches très spécifiques:

  1. La nécessité de créer de petites applications Web typiques selon le schéma standard suivant:
    • Installer les dépendances d'application à l'échelle du système
    • installer un ensemble de bibliothèques de dépendances d'applications,
    • collecter des actifs
    • et surtout, mettez à jour le code de l'image rapidement et efficacement.
  2. Lorsque des modifications sont apportées aux fichiers de projet, le générateur doit rapidement créer une nouvelle couche en appliquant un correctif aux fichiers modifiés.
  3. Si certains fichiers ont changé, il est nécessaire de reconstruire l'étape dépendante appropriée.

Aujourd'hui, dans notre collectionneur, il existe de nombreuses autres possibilités, mais les désirs et les envies initiaux étaient ceux-là.

En général, sans réfléchir à deux fois, nous nous sommes armés du langage de programmation utilisé (voir ci-dessous) et avons pris la route - implémentez notre propre DSL ! Correspondant aux tâches, il était destiné à décrire le processus d'assemblage par étapes et à déterminer les dépendances de ces étapes sur les fichiers. Et complété par son propre collectionneur , qui a fait de la DSL le but ultime - une image assemblée. Au début, DSL était en Ruby, et comme nous sommes passés à Golang , la configuration de notre collectionneur a commencé à être décrite dans le fichier YAML.


Ancienne config pour dapp sur Ruby


Configuration actuelle pour werf sur YAML

Le mécanisme du collecteur a également changé au fil du temps. Tout d'abord, nous avons simplement généré un Dockerfile temporaire temporaire à partir de notre configuration à la volée, puis nous avons commencé à exécuter des instructions d'assemblage dans des conteneurs temporaires et à les valider.

NB : Pour le moment, notre collecteur, qui fonctionne avec sa configuration (en YAML) et s'appelle le collecteur Stapel, est déjà devenu un outil assez puissant. Sa description détaillée mérite des articles séparés, et les principaux détails peuvent être trouvés dans la documentation .

Prise de conscience des problèmes


Mais nous avons réalisé, et pas immédiatement, que nous avons fait une erreur: nous n'avons pas ajouté la possibilité de collecter des images via le Dockerfile standard et de les intégrer dans la même infrastructure pour la gestion intégrée des applications (c'est-à-dire collecter des images, les déployer et les nettoyer). Comment pourriez-vous créer un outil de déploiement dans Kubernetes et ne pas implémenter le support Dockerfile, c'est-à-dire une façon standard de décrire les images pour la plupart des projets? ..

Au lieu de répondre à une telle question, nous proposons une solution. Que faire si vous avez déjà un Dockerfile (ou un ensemble de Dockerfiles) et que vous souhaitez utiliser werf?

NB : Au fait, pourquoi voudriez-vous même utiliser werf? Les principales caractéristiques sont les suivantes:

  • cycle complet de gestion des applications, y compris le nettoyage des images;
  • la possibilité de contrôler l'assemblage de plusieurs images à partir d'une seule configuration;
  • Processus de déploiement de cartes compatible avec Helm amélioré.

Une liste plus complète d'entre eux se trouve sur la page du projet .

Donc, si auparavant nous suggérons de réécrire Dockerfile dans notre configuration, maintenant nous serons heureux de dire: "Laissez werf construire vos Dockerfiles!"

Comment utiliser?


L'implémentation complète de cette fonctionnalité est apparue dans la version werf v1.0.3-beta.1 . Le principe général est simple: l'utilisateur spécifie le chemin d'accès au Dockerfile existant dans la configuration werf, puis exécute la commande werf build ... et c'est tout - werf va collecter l'image. Prenons un exemple abstrait.

Dockerfile suivant à la racine du projet:

 FROM ubuntu:18.04 RUN echo Building ... 

Et déclarez werf.yaml qui utilise ce Dockerfile :

 configVersion: 1 project: dockerfile-example --- image: ~ dockerfile: ./Dockerfile 

C’est tout! Il reste à exécuter werf build :



De plus, vous pouvez déclarer le werf.yaml suivant pour créer plusieurs images à partir de différents Dockerfiles à la fois:

 configVersion: 1 project: dockerfile-example --- image: backend dockerfile: ./dockerfiles/Dockerfile-backend --- image: frontend dockerfile: ./dockerfiles/Dockerfile-frontend 

Enfin, il prend également en charge le transfert de paramètres de construction supplémentaires - tels que --build-arg et --add-host - via la configuration werf. Une description complète de la configuration de l'image Dockerfile est disponible sur la page de documentation .

Comment ça marche?


Pendant le processus de génération, le cache de couche locale standard dans les fonctions Docker. Cependant, il est important de noter que werf intègre également la configuration Dockerfile dans son infrastructure . Qu'est-ce que cela signifie?

  1. Chaque image collectée à partir du Dockerfile se compose d'une étape appelée dockerfile (pour en savoir plus sur les étapes de werf, vous pouvez lire ici ).
  2. Pour l'étape, dockerfile werf calcule la signature, qui dépend du contenu de la configuration Dockerfile. Lorsque la configuration de Dockerfile est modifiée, la signature de l'étape dockerfile et werf lance la reconstruction de cette étape avec la nouvelle configuration Dockerfile. Si la signature ne change pas, alors werf prend l'image dans le cache (plus de détails sur l'utilisation des signatures dans werf ont été décrits dans ce rapport ) .
  3. De plus, les images collectées peuvent être publiées werf publish commande werf publish (ou werf build-and-publish ) et utilisées pour le déploiement dans Kubernetes. Les images publiées dans le Docker Registry seront nettoyées avec des nettoyants werf standard, c'est-à-dire il nettoiera automatiquement les anciennes images (plus anciennes que N jours), les images associées à des branches Git inexistantes et d'autres politiques.

Vous pouvez en savoir plus sur les points décrits ici dans la documentation:


Remarques et précautions


1. L'URL externe dans ADD n'est pas prise en charge


L'utilisation d'une URL externe dans la directive ADD n'est actuellement pas prise en charge. Werf n'initiera pas la reconstruction lorsqu'une ressource passe à l'URL spécifiée. Bientôt, il est prévu d'ajouter cette fonctionnalité.

2. Vous ne pouvez pas ajouter .git à une image


De manière générale, l'ajout d'un répertoire .git à une image est une mauvaise pratique vicieuse , et voici pourquoi:

  1. Si .git reste dans l'image finale, cela viole les principes de l' application à 12 facteurs : étant donné que l'image finale doit être associée à une validation, il ne devrait pas être possible d'effectuer une git checkout une validation arbitraire.
  2. .git augmente la taille de l'image (le référentiel peut être volumineux en raison du fait que des fichiers volumineux y ont été ajoutés puis supprimés). La taille de l'arbre de travail, associée uniquement à une validation spécifique, ne dépendra pas de l'historique des opérations dans Git. Dans le même temps, l'ajout et la suppression de .git de l'image finale ne fonctionneront pas: l'image obtiendra toujours un calque supplémentaire - c'est ainsi que Docker fonctionne.
  3. Docker peut lancer une reconstruction inutile, même si le même commit est en cours de création, mais à partir d'arborescences de travail différentes. Par exemple, GitLab crée des répertoires clonés séparés dans /home/gitlab-runner/builds/HASH/[0-N]/yourproject lorsque l'assemblage parallèle est activé. La reconstruction supplémentaire sera due au fait que le répertoire .git diffère dans différentes versions clonées du même référentiel, même si le même commit est collecté.

Le dernier point a une conséquence lors de l'utilisation de werf. Werf requiert que le cache collecté soit présent lorsque certaines commandes sont exécutées (par exemple, werf deploy ). Pendant le fonctionnement de ces commandes, werf calcule les signatures d'étape pour les images spécifiées dans werf.yaml , et elles doivent être dans le cache d'assembly - sinon l'équipe ne pourra pas continuer à travailler. Si la signature de l'étape dépend du contenu de .git , nous obtenons alors un cache qui est instable aux changements dans les fichiers non pertinents, et werf ne pourra pas pardonner un tel oubli (voir la documentation pour plus de détails).

En général, l' ajout de certains fichiers nécessaires via l'instruction ADD augmente dans tous les cas l'efficacité et la fiabilité du Dockerfile écrit, et améliore également la stabilité du cache compilé par ce Dockerfile contre les modifications non pertinentes de Git.

Résumé


Notre façon initiale d'écrire notre propre compilateur pour certains besoins était difficile, honnête et simple: au lieu d'utiliser des béquilles en plus du Dockerfile standard, nous avons écrit notre propre solution avec une syntaxe personnalisée. Et cela a donné ses avantages: le constructeur de Stapel fait parfaitement face à sa tâche.

Cependant, dans le processus d'écriture de notre propre collectionneur, nous avons négligé le support des Dockerfiles existants. Maintenant, cette faille a été corrigée et à l'avenir, nous prévoyons de développer la prise en charge de Dockerfile avec notre collecteur Stapel personnalisé pour l'assemblage distribué et l'assemblage à l'aide de Kubernetes (c'est-à-dire l'assemblage sur des coureurs à l'intérieur de Kubernetes, comme cela se fait à Kaniko).

Donc, si vous aviez soudainement quelques Dockerfiles traîner ... essayez werf !

PS Liste de documentation connexe



Lisez également sur notre blog: " werf est notre outil CI / CD à Kubernetes (revue et rapport vidéo) ."

Source: https://habr.com/ru/post/fr463613/


All Articles