L'écosystème Docker : découverte de services et magasins de configuration distribués
Introduction
Les conteneurs offrent une solution élégante pour ceux qui cherchent à concevoir et déployer des applications à grande échelle. Bien que Docker fournisse la technologie de conteneurisation proprement dite, de nombreux autres projets aident à développer les outils nécessaires au démarrage et à la communication appropriés dans l'environnement de déploiement.
L'une des technologies de base sur lesquelles s'appuient de nombreux environnements Docker est la découverte de services. La découverte de service permet à une application ou à un composant de découvrir des informations sur son environnement et ses voisins. Ceci est généralement implémenté en tant que magasin clé-valeur distribué, qui peut également servir d'emplacement plus général pour dicter les détails de configuration. La configuration d'un outil de découverte de service vous permet de séparer votre configuration d'exécution du conteneur réel, ce qui vous permet de réutiliser la même image dans plusieurs environnements.
Dans ce guide, nous discuterons des avantages de la découverte de services dans un environnement Docker en cluster. Nous nous concentrerons principalement sur les concepts généraux, mais fournirons des exemples plus spécifiques le cas échéant.
Découverte de services et magasins de configuration accessibles à l'échelle mondiale
L'idée de base derrière la découverte de service est que toute nouvelle instance d'une application doit être capable d'identifier par programmation les détails de son environnement actuel. Ceci est nécessaire pour que la nouvelle instance puisse se "connecter" à l'environnement d'application existant sans intervention manuelle. Les outils de découverte de service sont généralement implémentés sous la forme d'un registre accessible à l'échelle mondiale qui stocke des informations sur les instances ou les services qui fonctionnent actuellement. La plupart du temps, afin de rendre cette configuration tolérante aux pannes et évolutive, le registre est réparti entre les hôtes disponibles dans l'infrastructure.
Bien que l'objectif principal des plates-formes de découverte de services soit de fournir des détails de connexion pour relier les composants entre eux, elles peuvent être utilisées plus généralement pour stocker tout type de configuration. De nombreux déploiements tirent parti de cette capacité en écrivant leurs données de configuration dans l'outil de découverte. Si les conteneurs sont configurés de sorte qu'ils sachent rechercher ces détails, ils peuvent modifier leur comportement en fonction de ce qu'ils trouvent.
Comment fonctionne la découverte de services ?
Chaque outil de découverte de service fournit une API que les composants peuvent utiliser pour définir ou récupérer des données. Pour cette raison, pour chaque composant, l'adresse de découverte de service doit être soit codée en dur dans l'application/le conteneur lui-même, soit fournie en option lors de l'exécution. En règle générale, le service de découverte est implémenté sous la forme d'un magasin clé-valeur accessible à l'aide de méthodes HTTP standard.
Le fonctionnement d'un portail de découverte de services est que chaque service, lorsqu'il est en ligne, s'enregistre auprès de l'outil de découverte. Il enregistre toutes les informations dont un composant associé pourrait avoir besoin pour consommer le service qu'il fournit. Par exemple, une base de données MySQL peut enregistrer l'adresse IP et le port sur lequel le démon s'exécute, et éventuellement le nom d'utilisateur et les informations d'identification nécessaires pour se connecter.
Lorsqu'un consommateur de ce service se connecte, il peut interroger le registre de découverte de service pour obtenir des informations sur un point de terminaison prédéfini. Il peut alors interagir avec les composants dont il a besoin en fonction des informations qu'il trouve. Un bon exemple de ceci est un équilibreur de charge. Il peut trouver chaque serveur principal dont il a besoin pour alimenter le trafic en interrogeant le portail de découverte de services et en ajustant sa configuration en conséquence.
Cela supprime les détails de configuration des conteneurs eux-mêmes. L'un des avantages de ceci est que cela rend les conteneurs de composants plus flexibles et moins liés à une configuration spécifique. Un autre avantage est qu'il est simple de faire réagir vos composants aux nouvelles instances d'un service connexe, permettant une reconfiguration dynamique.
Quelle est la relation entre le stockage de configuration ?
L'un des principaux avantages d'un système de découverte de services distribué à l'échelle mondiale est qu'il peut stocker tout autre type de données de configuration dont vos composants pourraient avoir besoin lors de l'exécution. Cela signifie que vous pouvez extraire encore plus de configuration du conteneur et dans l'environnement d'exécution plus large.
Généralement, pour que cela fonctionne plus efficacement, vos applications doivent être conçues avec des valeurs par défaut raisonnables qui peuvent être remplacées lors de l'exécution en interrogeant le magasin de configuration. Cela vous permet d'utiliser le magasin de configuration de la même manière que vous utiliseriez les indicateurs de ligne de commande. La différence est qu'en utilisant un magasin accessible dans le monde entier, vous pouvez offrir les mêmes options à chaque instance de votre composant sans travail supplémentaire.
Comment le stockage de configuration aide-t-il la gestion de cluster ?
Une fonction des magasins clé-valeur distribués dans les déploiements Docker qui peut ne pas être apparente au départ est le stockage et la gestion de l'appartenance au cluster. Les magasins de configuration sont l'environnement idéal pour suivre l'adhésion de l'hôte pour le bien des outils de gestion.
Certaines des informations pouvant être stockées sur des hôtes individuels dans un magasin clé-valeur distribué sont :
- Adresses IP hôtes
- Informations de connexion pour les hôtes eux-mêmes
- Métadonnées et étiquettes arbitraires pouvant être ciblées pour les décisions de planification
- Rôle dans le cluster (si vous utilisez un modèle leader/suiveur)
Ces détails ne sont probablement pas quelque chose dont vous devez vous préoccuper lorsque vous utilisez une plate-forme de découverte de services dans des circonstances normales, mais ils fournissent un emplacement pour les outils de gestion pour interroger ou modifier des informations sur le cluster lui-même.
Qu'en est-il de la détection des pannes ?
La détection des pannes peut être mise en œuvre de plusieurs façons. La préoccupation est de savoir si, en cas de défaillance d'un composant, le service de découverte sera mis à jour pour refléter le fait qu'il n'est plus disponible. Ce type d'informations est vital pour minimiser les défaillances des applications ou des services.
De nombreuses plates-formes de découverte de services permettent de définir des valeurs avec un délai d'attente configurable. Le composant peut définir une valeur avec un délai d'attente et envoyer un ping au service de découverte à intervalles réguliers pour réinitialiser le délai d'attente. Si le composant échoue et que le délai d'expiration est atteint, les informations de connexion de cette instance sont supprimées du magasin. La durée du délai d'attente dépend en grande partie de la rapidité avec laquelle l'application doit répondre à une panne de composant.
Cela peut également être accompli en associant un conteneur "helper" bare-bones à chaque composant, dont la seule responsabilité est de vérifier périodiquement la santé du composant et de mettre à jour le registre si le composant tombe en panne. Le problème avec ce type d'architecture est que le conteneur d'assistance pourrait tomber en panne, entraînant des informations incorrectes dans le magasin. Certains systèmes résolvent ce problème en étant capables de définir des bilans de santé dans l'outil de découverte de service. De cette façon, la plate-forme de découverte elle-même peut vérifier périodiquement si les composants enregistrés sont toujours disponibles.
Qu'en est-il de la reconfiguration des services lorsque les détails changent ?
Une amélioration clé du modèle de découverte de service de base est celle de la reconfiguration dynamique. Alors que la découverte de service normale vous permet d'influencer la configuration initiale des composants en vérifiant les informations de découverte au démarrage, la reconfiguration dynamique implique la configuration de vos composants pour qu'ils réagissent aux nouvelles informations dans le magasin de configuration. Par exemple, si vous implémentez un équilibreur de charge, une vérification de l'état des serveurs principaux peut indiquer qu'un membre du pool est en panne. L'instance en cours d'exécution de l'équilibreur de charge doit être informée et doit pouvoir ajuster sa configuration et recharger pour en tenir compte.
Cela peut être mis en œuvre de plusieurs façons. Étant donné que l'exemple d'équilibrage de charge est l'un des principaux cas d'utilisation de cette capacité, il existe un certain nombre de projets qui se concentrent exclusivement sur la reconfiguration d'un équilibreur de charge lorsque des modifications de configuration sont détectées. L'ajustement de la configuration HAProxy est courant en raison de son omniprésence dans l'espace d'équilibrage de charge.
Certains projets sont plus flexibles dans la mesure où ils peuvent être utilisés pour déclencher des modifications dans tout type de logiciel. Ces outils interrogent régulièrement le service de découverte et lorsqu'un changement est détecté, utilisent des systèmes de modèles pour générer des fichiers de configuration qui intègrent les valeurs trouvées au point de terminaison de découverte. Après la génération d'un nouveau fichier de configuration, le service concerné est rechargé.
Ce type de reconfiguration dynamique nécessite plus de planification et de configuration pendant le processus de génération, car tous ces mécanismes doivent exister dans le conteneur du composant. Cela rend le conteneur de composants lui-même responsable de l'ajustement de sa configuration. Déterminer les valeurs nécessaires pour écrire dans le service de découverte et concevoir une structure de données appropriée pour une consommation facile est un autre défi que ce système nécessite, mais les avantages et la flexibilité peuvent être considérables.
Qu'en est-il de la sécurité ?
L'une des préoccupations de nombreuses personnes lorsqu'elles découvrent pour la première fois le stockage de configuration accessible à l'échelle mondiale est, à juste titre, la sécurité. Est-il vraiment acceptable de stocker les informations de connexion dans un emplacement accessible dans le monde entier ?
La réponse à cette question dépend en grande partie de ce que vous choisissez de placer dans le magasin et du nombre de couches de sécurité que vous jugez nécessaires pour protéger vos données. Presque toutes les plates-formes de découverte de services permettent de chiffrer les connexions avec SSL/TLS. Pour certains services, la confidentialité peut ne pas être très importante et placer le service de découverte sur un réseau privé peut s'avérer satisfaisant. Cependant, la plupart des applications bénéficieraient probablement d'une sécurité supplémentaire.
Il existe plusieurs façons de résoudre ce problème, et divers projets proposent leurs propres solutions. La solution d'un projet consiste à continuer à autoriser un accès ouvert à la plate-forme de découverte elle-même, mais à chiffrer les données qui y sont écrites. Le consommateur de l'application doit disposer de la clé associée pour déchiffrer les données qu'il trouve dans le magasin. Les autres parties ne pourront pas accéder aux données non cryptées.
Pour une approche différente, certains outils de découverte de services implémentent des listes de contrôle d'accès afin de diviser l'espace clé en zones distinctes. Ils peuvent ensuite désigner la propriété ou l'accès aux zones en fonction des exigences d'accès définies par un espace clé spécifique. Cela établit un moyen facile de fournir des informations à certaines parties tout en les gardant privées des autres. Chaque composant peut être configuré pour n'avoir accès qu'aux informations dont il a explicitement besoin.
Quels sont certains outils de découverte de services communs ?
Maintenant que nous avons discuté de certaines des fonctionnalités générales des outils de découverte de services et des magasins de clé-valeur distribués à l'échelle mondiale, nous pouvons mentionner quelques-uns des projets liés à ces concepts.
Certains des outils de découverte de service les plus courants sont :
- etcd : cet outil a été créé par les créateurs de CoreOS pour fournir une découverte de service et une configuration globalement distribuée aux conteneurs et aux systèmes hôtes eux-mêmes. Il implémente une API http et dispose d'un client en ligne de commande disponible sur chaque machine hôte.
- consul : cette plate-forme de découverte de services possède de nombreuses fonctionnalités avancées qui la distinguent, notamment les vérifications de l'état configurables, la fonctionnalité ACL, la configuration HAProxy, etc.
- zookeeper : cet exemple est un peu plus ancien que les deux précédents, fournissant une plate-forme plus mature au détriment de certaines fonctionnalités plus récentes.
Voici d'autres projets qui étendent la découverte de services de base :
- crypt : Crypt permet aux composants de protéger les informations qu'ils écrivent à l'aide d'un chiffrement à clé publique. Les composants destinés à lire les données peuvent recevoir la clé de déchiffrement. Toutes les autres parties ne pourront pas lire les données.
- confd : Confd est un projet visant à permettre la reconfiguration dynamique d'applications arbitraires en fonction des modifications apportées au portail de découverte de services. Le système comprend un outil pour surveiller les modifications des points de terminaison pertinents, un système de modèles pour créer de nouveaux fichiers de configuration en fonction des informations recueillies et la possibilité de recharger les applications concernées.
- vulcand : Vulcand sert d'équilibreur de charge pour des groupes de composants. Il est conscient d'etcd et modifie sa configuration en fonction des changements détectés dans le magasin.
- marathon : bien que marathon soit principalement un ordonnanceur (abordé plus tard), il implémente également une capacité de base pour recharger HAProxy lorsque des modifications sont apportées aux services disponibles entre lesquels il doit équilibrer.
- frontrunner : ce projet s'intègre à marathon pour fournir une solution plus robuste pour la mise à jour de HAProxy.
- synapse : ce projet introduit une instance HAProxy intégrée qui peut acheminer le trafic vers les composants.
- nerve : Nerve est utilisé conjointement avec synapse pour fournir des vérifications de l'état des instances de composants individuels. Si le composant devient indisponible, le nerf met à jour la synapse pour mettre le composant hors rotation.
Conclusion
La découverte de services et les magasins de configuration globaux permettent aux conteneurs Docker de s'adapter à leur environnement actuel et de se connecter aux composants existants. Il s'agit d'une condition préalable essentielle pour fournir une évolutivité et un déploiement simples et mains libres en permettant aux composants de suivre et de répondre aux changements au sein de leur environnement.
Dans le prochain guide, nous discuterons des façons dont les conteneurs et les hôtes Docker peuvent communiquer avec des configurations de réseau personnalisées.