Comment conteneuriser une application héritée

0
61
Shutterstock.com/Sergey Novikov

Conteneurisation a transformé la façon dont les nouvelles applications sont développées et déployées. Cependant, de nombreuses organisations conservent un catalogue d'anciens systèmes qui nécessitent une approche différente. Cette déconnexion entre le nouveau et l'ancien ne doit pas être perpétuée : vous pouvez également regrouper les anciens systèmes sous forme de conteneurs, ce qui facilite leur évolution avec des méthodes de développement plus modernes.

Dans cet article, nous allons examiner un processus que vous pouvez utiliser pour commencer à conteneuriser l' & #8220;héritage & #8221; Logiciel. Bien qu'il n'y ait pas deux produits identiques, et le terme “héritage” ; est subjectif, nous nous concentrerons sur les étapes largement applicables pour empaqueter des systèmes étroitement couplés actuellement liés à des environnements individuels.

1. Identifier les systèmes candidats

Il vaut la peine de préparer d'abord un inventaire des systèmes qui vous permet d'identifier les bons candidats pour la conteneurisation. Dans certains cas, vous pouvez conclure qu'une application particulière ne peut tout simplement pas être conteneurisée. Cela se produit généralement lorsqu'il a des exigences matérielles profondément ancrées ou s'appuie sur des fonctionnalités de noyau et des langages de programmation obsolètes.

Les meilleurs candidats sont les systèmes fréquemment utilisés qui bénéficieront immédiatement d'un développement futur accéléré. Recherchez des applications qui sont déjà assez autonomes si vous êtes complètement nouveau dans la conteneurisation. La sélection d'un système bien utilisé mais non critique vous donnera une marge de manœuvre en cas de problème tout en vous permettant de reconnaître les avantages d'une migration réussie.

2 . Composants du système

Vous pouvez conteneuriser votre système candidat en écrivant un Dockerfile, y compris toutes les dépendances de l'application, et en l'appelant un jour. Bien qu'il s'agisse d'un moyen valable d'intégrer rapidement un système dans un conteneur, cela ne devrait pas être l'objectif final de vos efforts. Un conteneur monolithique entraînera de longues versions, des tailles d'image énormes et une mauvaise évolutivité.

Au lieu de cela, vous devriez rechercher des opportunités pour diviser chacun de vos systèmes en composants individuels. Ces composants doivent se retrouver dans leurs propres conteneurs, évitant qu'une seule pièce ne devienne trop grande. Vous pourrez mettre à l'échelle les composants individuellement en créant des répliques supplémentaires de conteneurs à ressources limitées.

Cette étape est également importante pour établir une modularité globale et encourager l'adoption de nouveaux conteneurs. Au fur et à mesure que vous séparez plusieurs systèmes en leurs composants, vous commencez à trouver des chevauchements qui vous permettent de réutiliser les images de conteneur que vous avez déjà créées. Vous remarquerez qu'il devient progressivement plus facile de continuer à conteneuriser.

Décider où diviser les composants ne devrait pas être trop éprouvant. Commencez par identifier où le système s'appuie sur des services qui sont déjà externes à son code source. Les connexions aux bases de données, les files d'attente de messages, les serveurs de messagerie, les proxys et les passerelles doivent tous être indépendants du composant qu'ils augmentent. Vous les séparerez dans leurs propres conteneurs qui se trouvent à côté de l'instance exécutant votre code.

Il est également utile de rechercher des opportunités de refactoriser ce qui reste. Votre service a-t-il trop de responsabilités qui pourraient être réparties en unités fonctionnelles distinctes ? Vous pouvez avoir une API de profil utilisateur qui accepte les téléchargements de photos ; le service qui redimensionne ces photos pourrait être un bon candidat pour fonctionner de manière autonome dans son propre conteneur.

3. Préparez vos composants

Après avoir séparé les composants, vous devez les préparer à fonctionner dans un environnement conteneurisé. Les conteneurs présentent plusieurs différences essentielles par rapport aux machines virtuelles traditionnelles. Le stockage persistant, la configuration et les liens entre les composants sont les trois éléments les plus importants à prendre en compte dès le départ.

Stockage persistant

Les conteneurs sont des environnements éphémères. Les modifications du système de fichiers sont perdues lorsque vos conteneurs s'arrêtent. Vous êtes responsable de la gestion des données persistantes de votre application à l'aide des mécanismes fournis par votre environnement d'exécution de conteneur.

Dans le cas de Docker, les volumes sont utilisés pour conserver les données en dehors de vos instances de conteneur. Les volumes sont montés sur des chemins spécifiques dans les conteneurs. Pour éviter d'avoir à monter des dizaines de volumes, il est préférable de concentrer les données de votre application dans quelques répertoires de niveau supérieur. Le montage de volumes à ces emplacements garantira la persistance des fichiers stockés par votre application.

Il est important d'auditer les interactions du système de fichiers de votre application pour comprendre les volumes dont vous avez besoin et les problèmes que vous rencontrerez. Ne pas prêter attention à cette étape peut s'avérer coûteux si des données que vous supposez persistantes sont perdues à chaque redémarrage d'un conteneur.

Gestion de la configuration

De nombreuses applications héritées sont configurées à l'aide de fichiers de configuration statiques. Ceux-ci peuvent être dans un format dédié, tel que XML, JSON ou INI, ou codés à l'aide du langage de programmation du système.

Les conteneurs sont normalement configurés par des variables d'environnement externes. Les variables sont définies lors de la création des conteneurs, à l'aide de mécanismes tels que l'indicateur -e de Docker avec docker run. Ils sont injectés dans l'environnement du conteneur en cours d'exécution.

L'utilisation de ce système garantit que vous pouvez compter sur votre chaîne d'outils de conteneur pour définir et modifier les paramètres de configuration. Vous devrez peut-être d'abord refactoriser votre application pour prendre en charge la lecture des paramètres à partir des variables d'environnement. Une façon courante de faciliter la transition consiste à placer un petit script à l'intérieur du point d'entrée du conteneur. Cela peut énumérer les variables d'environnement lors de la création du conteneur et les écrire dans un fichier de configuration pour votre application.

La conteneurisation fait également penser à la mise en réseau interservices. Les services ne sont généralement pas exposés les uns aux autres, sauf par configuration explicite. Vous pouvez configurer une liaison automatique dans Docker en joignant plusieurs conteneurs au même réseau Docker. Cela offre une fonction de découverte de service qui permet aux conteneurs de se contacter par leur nom.

D'autres technologies de conteneurisation utilisent différentes approches de mise en réseau et de découverte de services. Après avoir séparé vos systèmes en composants individuels, vous devez les relier à l'aide des fonctionnalités offertes par votre environnement d'exécution. La nature des déploiements conteneurisés signifie qu'il y a souvent plus de complexité que la mise en réseau entre des machines virtuelles ou des hôtes physiques. Le trafic doit être acheminé et la charge équilibrée entre tous vos réplicas de conteneur et leurs dépendances, vous devez donc reconnaître ces exigences dès le début.

4. Écrivez vos fichiers Docker

Une fois que vous avez planifié votre architecture, vous pouvez commencer le travail physique associé à la conteneurisation. La première étape consiste à écrire des Dockerfiles pour les composants de votre application. Ceux-ci définissent la séquence de commandes et d'actions qui créent un système de fichiers contenant tout ce dont le composant a besoin pour s'exécuter.

Les Dockerfiles commencent par une image de base appropriée référencée par une instruction FROM. Il s'agit généralement d'un système d'exploitation (ubuntu:20.04, alpine:3) ou d'un environnement de langage de programmation pré-construit (php:8, node:16). Vous pouvez choisir l'image qui correspond le mieux à l'environnement existant de votre application. Commencer à partir d'un système de fichiers vide est possible mais généralement pas nécessaire, sauf si vous avez besoin d'un contrôle extrêmement granulaire.

Le contenu supplémentaire est superposé sur l'image de base par des instructions telles que COPY et RUN. Ceux-ci vous permettent de copier des fichiers depuis votre hôte et d'exécuter des commandes sur le système de fichiers temporaire de la construction. Une fois que vous avez écrit votre Dockerfile, vous pouvez le construire avec le docker build -t my-image:latest . commande.

5. Configurer l'orchestration

En supposant que vous ayez divisé votre système en composants, vous vous retrouverez avec une image de conteneur pour chaque élément. Vous avez maintenant besoin d'un moyen d'afficher tous les conteneurs simultanément afin de pouvoir démarrer facilement une instance d'application fonctionnelle.

Les grandes installations de production utilisent couramment Kubernetes à cette fin. Il s'agit d'un système d'orchestration dédié qui ajoute ses propres concepts de niveau supérieur pour créer des déploiements conteneurisés répliqués. Les petits systèmes et environnements de développement sont souvent bien servis par Docker Compose, un outil qui s'appuie sur des fichiers YAML plus simples pour démarrer une “pile” de plusieurs conteneurs :

version : "3" app : image : my-web-app:latest ports : – 80:80 database : image : mysql:8.0 ports : – 3306:3306

Un fichier docker-compose.yml vous permet de démarrer tous ses services à l'aide du docker- compose binaire :

docker-compose up -d

La mise en place d'une certaine forme d'orchestration rend votre flotte de conteneurs plus gérable et facilite la mise à l'échelle via la réplication. Kubernetes et Docker Compose sont capables de démarrer plusieurs instances de vos services, une capacité qui ne peut pas être obtenue avec des applications héritées formées de composants étroitement couplés.

6. Après le déménagement : surveiller et développer votre flotte de conteneurs

La conteneurisation ne se termine pas avec le démarrage d'une instance de votre application. Pour tirer le meilleur parti de la technologie, vous devez surveiller correctement vos conteneurs afin de rester informé des erreurs et de l'utilisation des ressources.

Les grands systèmes sont mieux servis par une plate-forme d'observabilité dédiée qui peut agréger les journaux et les métriques de l'ensemble de votre flotte. Vous utilisez peut-être déjà une solution similaire avec vos déploiements d'applications héritées, mais c'est encore plus important pour les conteneurs. Une bonne observabilité vous permettra de retracer les problèmes jusqu'à l'instance de conteneur dont ils sont issus, en faisant apparaître les informations importantes lorsque vous avez des centaines ou des milliers de répliques.

Pour continuer à développer votre flotte, doublez la documentation et la standardisation. Nous avons déjà vu comment la division des systèmes en composants facilite la réutilisation future. Cependant, cela ne fonctionne efficacement que si vous avez documenté ce que vous avez et comment chaque pièce s'emboîte. Prendre le temps d'écrire sur votre système et le processus que vous avez suivi permettra de rationaliser les travaux futurs. Cela aidera également les nouveaux membres de l'équipe à comprendre les décisions que vous avez prises.

Est-ce que ça vaut le coup ?

La conteneurisation est utile lorsque vous sentez que le développement d'un système est freiné par ses processus actuels. Pouvoir le déployer en tant qu'ensemble de conteneurs simplifie l'expérience de développement et vous offre plus de polyvalence dans le déploiement. Vous pouvez désormais lancer le service partout où un environnement d'exécution de conteneur est disponible, qu'il s'agisse d'une instance sur votre ordinateur portable ou de 1 000 sur un fournisseur de cloud public.

L'utilisation intégrale des conteneurs facilite l'exploitation de la puissance du cloud, la consolidation de vos déploiements et la réduction des coûts d'infrastructure sur site. Cependant, ces gains apparents peuvent être contrebalancés par la nécessité de recycler les ingénieurs, d'embaucher de nouveaux talents spécialisés et d'entretenir vos conteneurs au fil du temps.

La décision de conteneuriser un système hérité doit tenir compte de la valeur de ce système pour votre entreprise, du temps actuellement consacré à sa maintenance et de la réduction probable résultant de l'utilisation de conteneurs. Il se peut qu'il soit préférable de ne pas toucher aux services de faible priorité si les processus qui leur sont associés ne causent pas de problèmes immédiats.

Il convient de reconnaître que toutes les applications héritées n'auront pas besoin ou ne seront pas capables d'utiliser tous les avantages vantés de la conteneurisation. L'adoption est un spectre, allant de l'exécution du système dans un seul conteneur monolithique à la pleine composante, à l'orchestration et à l'intégration avec des suites d'observabilité. Ce dernier modèle est la cible idéale pour les applications critiques pour l'entreprise que les ingénieurs font évoluer chaque jour ; à l'inverse, le premier peut être adéquat pour les services rarement touchés où le principal obstacle est le temps passé à provisionner de nouveaux environnements de développement basés sur des machines virtuelles.

Conclusion

La migration d'applications héritées vers des flux de travail conteneurisés peut sembler difficile à première vue. Diviser le processus en étapes distinctes aide généralement à définir où vous en êtes et où vous voulez être. Dans cet article, nous avons examiné six étapes granulaires que vous pouvez utiliser pour aborder la conteneurisation des systèmes existants. Nous avons également discuté de certaines des considérations que vous devez prendre en compte lorsque vous décidez de continuer.

D'un point de vue conceptuel, la conteneurisation d'une application héritée est un peu différente de l'utilisation d'une nouvelle. Vous appliquez les mêmes principes de création de composants, de services liés et de configuration que ceux injectés depuis l'environnement extérieur. La plupart des systèmes sont relativement simples à conteneuriser vus sous cet angle. Se concentrer sur ces aspects vous aidera à découpler vos applications, à créer des composants évolutifs et à concevoir une méthodologie de conteneurisation efficace.

LIRE LA SUITE

  • › Jusqu'où peut aller une voiture électrique avec une seule charge ?
  • › Combien coûte la recharge d'une batterie ?
  • &rsaquo ; Ces gadgets bannissent les moustiques
  • &rsaquo ; 4 façons dont vous endommagez la batterie de votre ordinateur portable
  • › Examen de PrivadoVPN : perturber le marché ?
  • &rsaquo ; "Atari était très, très dur" Nolan Bushnell sur Atari, 50 ans plus tard