Vous pouvez désormais créer des images Docker dans werf à l'aide d'un fichier Dockerfile standard

Mieux vaut tard que jamais. Ou comment nous avons presque commis une grave erreur en ne prenant pas en charge les Dockerfiles classiques pour créer des images d'application.

Vous pouvez désormais créer des images Docker dans werf à l'aide d'un fichier Dockerfile standard

Nous parlerons de cour — Utilitaire GitOps qui s'intègre à n'importe quel système CI/CD et assure la gestion de l'ensemble du cycle de vie des applications, permettant :

  • collecter 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 de rassembler des outils de bas niveau dans un seul système unifié qui permet aux ingénieurs DevOps de contrôler les applications. Si possible, les utilitaires existants (comme Helm et Docker) doivent être utilisés. S’il n’existe pas de solution à un problème, nous pouvons créer et soutenir tout ce qui est nécessaire à cet effet.

Contexte : votre propre collecteur d'images

C'est ce qui s'est passé avec le collecteur d'images de werf : le Dockerfile habituel ne nous suffisait pas. Si l'on jette un rapide coup d'œil à l'historique du projet, ce problème apparaissait déjà dans les premières versions de werf (à l'époque encore connu sous le nom de dapp).

En créant un outil permettant de créer des applications dans des images Docker, nous avons rapidement réalisé que Dockerfile ne nous convenait pas pour 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 des 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 dans l'image rapidement et efficacement.
  2. Lorsque des modifications sont apportées aux fichiers du projet, le constructeur doit rapidement créer une nouvelle couche en appliquant un correctif aux fichiers modifiés.
  3. Si certains fichiers ont changé, alors il est nécessaire de reconstruire l'étape dépendante correspondante.

Aujourd'hui, notre collectionneur a bien d'autres possibilités, mais telles étaient ses envies et ses envies initiales.

En général, sans y réfléchir à deux fois, nous nous sommes armés du langage de programmation que nous avons utilisé (voir ci-dessous) et prendre la route pour mettre en œuvre posséder un DSL! Conformément aux objectifs, il était prévu de décrire le processus d'assemblage par étapes et de déterminer les dépendances de ces étapes par rapport aux fichiers. Et je l'ai complété propre collectionneur, qui a fait du DSL l'objectif final : une image assemblée. Au début, le DSL était en Ruby, mais comme transition vers Golang — la configuration de notre collecteur a commencé à être décrite dans un fichier YAML.

Vous pouvez désormais créer des images Docker dans werf à l'aide d'un fichier Dockerfile standard
Ancienne configuration pour dapp dans Ruby

Vous pouvez désormais créer des images Docker dans werf à l'aide d'un fichier Dockerfile standard
Configuration actuelle pour werf sur YAML

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

NB: Pour le moment, notre collecteur, qui fonctionne avec sa propre 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 détails de base peuvent être trouvés dans documentation.

Conscience du problème

Mais nous avons réalisé, et pas immédiatement, que nous avions commis une erreur : nous n'avons pas ajouté la capacité créer des images via Dockerfile standard et intégrez-les dans la même infrastructure de gestion d'applications de bout en bout (c'est-à-dire collecter des images, les déployer et les nettoyer). Comment pourrait-il être possible de créer un outil de déploiement dans Kubernetes et de ne pas implémenter le support de Dockerfile, c'est-à-dire manière standard de décrire les images pour la plupart des projets ?

Au lieu de répondre à cette question, nous proposons une solution. Que se passe-t-il si vous disposez déjà d'un Dockerfile (ou d'un ensemble de Dockerfiles) et que vous souhaitez utiliser werf ?

NB: Au fait, pourquoi voudriez-vous utiliser werf ? Les principales caractéristiques se résument aux suivantes :

  • cycle complet de gestion des applications, y compris le nettoyage des images ;
  • la possibilité de gérer l'assemblage de plusieurs images à la fois à partir d'une seule config ;
  • Processus de déploiement amélioré pour les chartes compatibles Helm.

Une liste plus complète d'entre eux peut être trouvée sur page du projet.

Donc, si plus tôt nous avions proposé de réécrire le Dockerfile dans notre configuration, nous dirons maintenant avec plaisir : « Laissez-nous construire vos Dockerfiles !

Comment l'utiliser?

L'implémentation complète de cette fonctionnalité est apparue dans la version werf v1.0.3-bêta.1. Le principe général est simple : l'utilisateur précise le chemin d'accès à un Dockerfile existant dans la config werf, puis exécute la commande werf build... et c'est tout - Werf assemblera l'image. Regardons un exemple abstrait.

Annonçons le prochain Dockerfile à la racine du projet :

FROM ubuntu:18.04
RUN echo Building ...

Et nous annoncerons werf.yamlqui utilise ceci Dockerfile:

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

Tous! Gauche courir werf build:

Vous pouvez désormais créer des images Docker dans werf à l'aide d'un fichier Dockerfile standard

De plus, vous pouvez déclarer ce qui suit werf.yaml 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 la transmission de paramètres de construction supplémentaires, tels que --build-arg и --add-host - via la configuration werf. Une description complète de la configuration de l'image Dockerfile est disponible sur documentation.

Comment ça marche?

Pendant le processus de construction, le cache standard des couches locales dans Docker fonctionne. Mais ce qui est important, c'est que werf aussi intègre la configuration Dockerfile dans son infrastructure. Qu'est-ce que ça veut dire?

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

Plus de détails sur les points décrits ici peuvent être trouvés dans la documentation :

Notes et précautions

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

Actuellement, il n'est pas pris en charge d'utiliser une URL externe dans une directive ADD. Werf ne lancera pas de reconstruction lorsque la ressource à l'URL spécifiée change. Nous prévoyons d'ajouter cette fonctionnalité prochainement.

2. Vous ne pouvez pas ajouter .git à l'image

De manière générale, ajouter un répertoire .git dans l'image - une mauvaise pratique vicieuse et voici pourquoi :

  1. si .git reste dans l'image finale, cela viole les principes Application 12 facteurs: Puisque l'image finale doit être liée à un seul commit, il ne devrait pas être possible de le faire git checkout validation arbitraire.
  2. .git augmente la taille de l'image (le référentiel peut être volumineux du fait que des fichiers volumineux y ont été ajoutés puis supprimés). La taille d'un arbre de travail associé uniquement à un commit spécifique ne dépendra pas de l'historique des opérations dans Git. Dans ce cas, l'ajout et la suppression ultérieure .git à partir de l'image finale ne fonctionnera pas : l'image acquerra toujours une couche supplémentaire - c'est ainsi que fonctionne Docker.
  3. Docker peut lancer une reconstruction inutile, même si le même commit est en cours de construction, mais à partir d'arbres de travail différents. Par exemple, GitLab crée des répertoires clonés distincts dans /home/gitlab-runner/builds/HASH/[0-N]/yourproject lorsque l'assemblage parallèle est activé. Le remontage supplémentaire sera dû au fait que le répertoire .git est différent dans différentes versions clonées du même référentiel, même si le même commit est construit.

Le dernier point a également des conséquences lors de l'utilisation de werf. Werf nécessite que le cache construit soit présent lors de l'exécution de certaines commandes (par ex. werf deploy). Lorsque ces commandes sont exécutées, werf calcule les signatures d'étape pour les images spécifiées dans werf.yaml, et ils doivent être dans le cache d'assembly - sinon la commande ne pourra pas continuer à fonctionner. Si la signature de scène dépend du contenu .git, nous obtenons alors un cache instable aux modifications apportées aux fichiers non pertinents, et werf ne pourra pas pardonner un tel oubli (pour plus de détails, voir documentation).

En général, ajouter uniquement certains fichiers nécessaires à travers les instructions ADD augmente en tout cas l'efficacité et la fiabilité de l'écrit Dockerfile, et améliore également la stabilité du cache collecté pour cela Dockerfile, aux changements non pertinents dans Git.

Total

Notre chemin initial pour écrire notre propre constructeur pour des besoins spécifiques a été difficile, honnête et simple : au lieu d'utiliser des béquilles au-dessus du Dockerfile standard, nous avons écrit notre solution avec une syntaxe personnalisée. Et cela avait ses avantages : le collecteur Stapel remplit parfaitement sa tâche.

Cependant, lors de l'écriture de notre propre constructeur, nous avons perdu de vue la prise en charge des Dockerfiles existants. Cette faille a maintenant été corrigée et, à l'avenir, nous prévoyons de développer la prise en charge de Dockerfile avec notre générateur Stapel personnalisé pour l'assemblage distribué et pour l'assemblage à l'aide de Kubernetes (c'est-à-dire l'assemblage sur des coureurs à l'intérieur de Kubernetes, comme cela se fait dans kaniko).

Donc, si vous avez soudainement quelques Dockerfiles qui traînent... essayer cour!

PS Liste de la documentation sur le sujet

A lire aussi sur notre blog : «werf - notre outil pour CI/CD dans Kubernetes (aperçu et reportage vidéo)».

Source: habr.com

Ajouter un commentaire