Nous avons été clairs sur nos objectifs de conception lorsque nous avons dévoilé l' architecture de référence des applications modernes NGINX (MARA) lors du Sprint 2.0 en août 2021. Nous voulions créer un exemple d’architecture d’application moderne fonctionnant dans Kubernetes et conçue pour prendre en charge la sécurité, l’évolutivité, la fiabilité, la surveillance et l’introspection. Ce projet devait pouvoir être déployé sur différentes infrastructures avec une approche « plug and play » pour combiner des composants fonctionnels sans efforts d’intégration chronophages.
Au cours des mois qui ont suivi Sprint, nous avons avancé avec notre feuille de route. Comme tout projet, nous avons eu notre part de succès et d’échecs et avons intégré nos succès dans MARA tout en conservant une liste croissante de leçons apprises. Nous espérons pouvoir éviter que d’autres ne rencontrent les mêmes problèmes en documentant ces problèmes et en concevant en gardant ces leçons à l’esprit.
Nous avons récemment franchi une étape importante avec la version 1.0.0 de MARA , qui réorganise le répertoire du projet et modifie le processus d'instanciation et de destruction de l'environnement. Nous avons éliminé le code dupliqué, créé une structure de répertoire qui s’adapte facilement aux ajouts futurs et standardisé les scripts de gestion. Comme cette version marque un point important dans l'histoire de MARA, nous avons voulu nous arrêter et rendre compte à la communauté de nos progrès, noter ce que nous pensons être certaines des leçons les plus importantes apprises et fournir quelques informations sur notre feuille de route pour l'avenir.
Les principaux contributeurs de MARA ont de l'expérience dans l'exécution de logiciels à grande échelle et comprennent ce qu'il faut pour fournir des services du point de vue opérationnel, technique et de gestion. Ils connaissent le sentiment désagréable que vous ressentez lorsqu’une application fonctionne mal et que vous n’avez pas de moyen simple de déterminer exactement quel est le problème. Une citation circulant dans le monde DevOps résume succinctement le problème : « Déboguer des microservices, c’est comme résoudre une série de mystères de meurtre. »
Dans cet esprit, nous avons fait de l’ajout de l’observabilité une priorité absolue de notre feuille de route à court terme. L'observabilité dans ce contexte inclut la gestion des journaux, les métriques et les données de traçage. Cependant, la simple collecte de données ne suffit pas : vous devez être capable d’analyser les données et de prendre des décisions éclairées sur ce qui se passe dans l’environnement.
Notre exploration des options de traçage nous a conduit à OpenTelemetry (OTEL) car il prend en charge l’ensemble des données de télémétrie, des journaux, des métriques et des traces. Nous avons imaginé une implémentation dans laquelle l'agent OTEL collecte, traite et déduplique toutes les données de traçage avant de les transmettre au collecteur OTEL pour agrégation et exportation, avec un système de visualisation à la fin du flux de travail pour rendre les données utilisables. Cette approche offre aux utilisateurs la plus large gamme de choix pour l’affichage et l’analyse des données, tout en tirant parti de la norme OTEL pour simplifier les étapes antérieures (collecte, agrégation, etc.).
Nous avons construit l'implémentation en deux étapes :
Déployer l' opérateur OpenTelemetry pour Kubernetes pour gérer un collecteur OTEL dans l'environnement
Instrumenter l'application Bank of Sirius pour émettre des traces et des métriques
La version originale de MARA utilisait Elasticsearch avec Filebeat pour la journalisation, et bien que nous ayons envisagé de les remplacer par Grafana Loki , nous avons décidé de conserver le choix d'origine pour le moment. Du côté des métriques, nous avons réalisé que nous devions réviser le déploiement d'origine basé sur Prometheus et Grafana en remplaçant la configuration Prometheus sur mesure que nous avions initialement utilisée par le graphique Helm kube-prometheus-stack maintenu par la communauté, qui constitue un environnement Prometheus complet comprenant Grafana, des exportateurs de nœuds et une série de tableaux de bord préconfigurés et de cibles de scraping adaptés à la gestion d'un environnement Kubernetes. À cela, nous avons ajouté quelques tableaux de bord supplémentaires pour F5 NGINX Ingress Controller et l'application Bank of Sirius.
Ceci n’est qu’un bref résumé de l’immense quantité de travail nécessaire à la mise en œuvre d’OTEL. Pour épargner aux autres l'effort de gravir la même courbe d'apprentissage abrupte, nous avons documenté l'ensemble du processus dans Intégration d'OpenTelemetry dans l'architecture de référence des applications modernes - Un rapport d'avancement sur notre blog.
Dans la version initiale de MARA, nous avons choisi Amazon Elastic Kubernetes Service (EKS) comme environnement de déploiement. De nombreux utilisateurs nous ont depuis indiqué que, pour des raisons de coût, ils souhaitaient exécuter MARA dans des environnements « locaux » qui nécessitent moins de ressources, comme un laboratoire ou un poste de travail. La portabilité était un objectif clé du projet original (et le reste), c'était donc notre chance de prouver que nous pouvions l'accomplir. Pour faciliter la tâche, nous avons décidé de concevoir une procédure de déploiement pouvant s’exécuter sur n’importe quel cluster Kubernetes répondant à certaines exigences minimales.
Dans un premier temps, nous avons ajouté un nouveau projet Pulumi à MARA qui lit un fichier kubeconfig pour communiquer avec le cluster Kubernetes. Ce projet se situe entre les projets Pulumi Kubernetes et les projets d'infrastructure (des exemples de ces derniers étant des projets pour AWS et Digital Ocean). Concrètement, la création du projet kubeconfig réduit la barrière à l’intégration d’un nouveau projet d’infrastructure. Si un projet d'infrastructure peut transmettre un fichier kubeconfig, un nom de cluster et un contexte de cluster au projet kubeconfig, le reste de la procédure de déploiement MARA fonctionne de manière transparente.
Pour nos tests, nous avons utilisé plusieurs distributions Kubernetes faciles à installer avec de faibles exigences en termes de CPU et de mémoire, notamment K3s , Canonical MicroK8s et minikube . Les distributions ont toutes été déployées sur une machine virtuelle (VM) exécutant Ubuntu 21.10 avec 2 CPU et 16 Go de RAM . De plus, toutes les distributions ont été configurées pour fournir des volumes persistants et la prise en charge de Kubernetes LoadBalancer.
La partie la plus difficile de ce processus a été de travailler avec le registre privé utilisé pour le contrôleur d’entrée NGINX personnalisé qui fait partie du projet. (Notez que lors du déploiement de MARA, vous pouvez utiliser le contrôleur d'entrée NGINX standard basé sur NGINX Open Source ou NGINX Plus ainsi que ce contrôleur d'entrée NGINX personnalisé.) Nous avons découvert que nous devions découpler notre logique de registre d’ Amazon Elastic Container Registry (ECR) au profit d’une approche plus indépendante de la plateforme, une tâche actuellement en cours. Nous avons également réalisé que notre logique d’extraction du nom d’hôte de l’adresse de sortie était très spécifique à AWS Elastic Load Balancing (ELB) et devait être réécrite pour s’appliquer à d’autres cas d’utilisation.
Les scripts de gestion MARA et les projets Pulumi utilisent actuellement une logique spécifique pour contourner les problèmes décrits ci-dessus. Pour l’instant, les déploiements basés sur la configuration Kubernetes doivent utiliser NGINX Ingress Controller (basé sur NGINX Open Source ou NGINX Plus) à partir des registres NGINX officiels.
Nous avons ajouté plusieurs paramètres de réglage aux fichiers de configuration MARA pour prendre en charge les déploiements locaux qui n’offrent pas les ressources nécessaires au déploiement basé sur le cloud. La plupart des paramètres sont liés au nombre de répliques demandées pour les différents composants de la pile Elastic . À mesure que les tests progressent, des paramètres supplémentaires seront ajoutés pour affiner MARA en fonction des contraintes de ressources de l’environnement de déploiement.
Grâce à ces modifications, nous pouvons déployer avec succès sur K3s, MicroK8s et Minikube, et nous avons testé avec succès la logique sur Azure Kubernetes Service (AKS), Digital Ocean , Google Kubernetes Engine , Linode et Rancher's Harvester . Pour plus d'informations, consultez la page Statut du fournisseur MARA et MARA : Actuellement en cours d'exécution sur un poste de travail près de chez vous sur notre blog.
Nos partenaires ont été très réceptifs et ont soutenu notre travail avec MARA, nombre d'entre eux nous contactant pour en savoir plus sur le projet, demander comment ils peuvent l'exploiter avec leurs produits, voire ajouter des fonctionnalités.
Nous avons choisi Pulumi comme élément central de MARA pour sa facilité d'utilisation et sa prise en charge de Python, ce dernier étant un langage si populaire qu'il rend le code MARA facilement compris par une large communauté. De plus, la communauté dynamique de Pulumi et son engagement dans le projet étaient un modèle de l’implication communautaire que nous espérons atteindre avec MARA.
Fin 2021, nous avons travaillé avec Sumo Logic pour faire de MARA une partie de sa solution de surveillance cloud avec NGINX Ingress Controller. C'était l'occasion de mettre à l'épreuve notre affirmation selon laquelle MARA est enfichable. Le défi était de remplacer la solution Sumo Logic par Grafana, Prometheus et Elastic dans MARA. Nous sommes ravis d'avoir réussi à mettre en place la solution en utilisant la même logique que celle que nous utilisons pour d'autres déploiements, et de l'avoir configurée non seulement pour se connecter au SaaS Sumo Logic, mais également pour extraire des métriques de notre environnement.
Dans le cadre de notre travail avec OpenTelemetry, nous avons collaboré avec Lightstep et avons facilement reconfiguré notre collecteur OTEL pour exporter des traces et des métriques vers l'offre SaaS de Lightstep. Il s’agit d’un domaine que nous souhaitons approfondir, car nous sommes convaincus que l’OTEL représente l’avenir de l’observabilité.
La plus grande leçon que nous avons apprise jusqu’à présent est la sagesse d’une approche modulaire. Le travail avec Sumo Logic montre que nous pouvons mélanger et assortir avec succès les composants MARA. Nous attendons de nouvelles confirmations à mesure que nous intégrons plus complètement OTEL dans l’environnement. Nous avons précédemment mentionné que nous envisagions de remplacer Elasticsearch par Grafana Loki comme environnement de gestion des journaux, car cela réduit l’empreinte des ressources de la pile. Cela dit, nous prônons une « modularité pragmatique » plutôt que d’aller aux extrêmes en faisant de tout un microservice. Par exemple, s’il est logique de disposer d’un service spécialisé capable de traiter les journaux de nombreuses applications, il est moins évident que vous ayez besoin de microservices distincts pour la collecte, le stockage et la visualisation des journaux.
Nous avons également appris qu’il est utile de définir des valeurs par défaut en les incluant explicitement dans la configuration plutôt que de simplement omettre le paramètre concerné. Cela est pratique pour les administrateurs de deux façons : ils n’ont pas besoin de mémoriser les valeurs par défaut et ils peuvent les modifier facilement en modifiant simplement un paramètre qui apparaît déjà avec la syntaxe correcte au bon endroit dans la configuration.
Une autre leçon douloureuse que nous avons apprise est que certaines solutions sont populaires non pas parce qu’elles sont les meilleures, mais parce qu’elles sont les plus faciles à installer ou qu’elles proposent le meilleur tutoriel. C’est pourquoi il est si important de remettre en question vos hypothèses et de consulter vos collègues pendant le processus de conception. Une culture de communication ouverte contribue grandement à identifier et à résoudre les problèmes le plus tôt possible.
Cela dit, à plusieurs reprises, nous avons mis en œuvre une logique qui a fonctionné, mais qui nous a soit mis dans une impasse, soit causé d’autres problèmes. Par exemple, lorsque nous avons commencé à déployer des applications via Pulumi, nous avons utilisé des manifestes YAML pour ConfigMaps , en nous appuyant sur les transformations Pulumi pour mettre à jour les variables. Cela a fonctionné, mais ce n’était pas idéal pour plusieurs raisons, dont la moindre n’était pas la facilité d’entretien. Dans l'itération suivante, nous avons amélioré la lisibilité et la maintenabilité du code en utilisant kube2pulumi pour transformer les manifestes en code Pulumi que nous pourrions ensuite utiliser pour créer les ConfigMaps.
Une autre leçon a commencé lorsqu’une fusion a inséré des paramètres non valides dans le YAML de déploiement. Nous avons été obligés de réécrire et de revoir attentivement de grandes parties du YAML pour nous assurer que le code était à la fois syntaxiquement correct et faisait ce que nous voulions, un processus frustrant et chronophage. Pour éviter de futurs problèmes, nous avons désormais automatisé le linting et la validation du YAML générique et spécifiques à Kubernetes pendant le processus de push GitHub.
Enfin, notre objectif depuis le début a été de garantir que notre branche principale soit toujours exécutable. C'est frustrant lorsque vous découvrez un nouveau projet et que vous devez résoudre un problème que les mainteneurs ont introduit dans la ligne principale. Malheureusement, nous avons échoué à plusieurs reprises, notamment dans ces exemples avec le sous-module Bank of Sirius :
ssh
pour nous connecter à GitHub. Cependant, les utilisateurs qui n’avaient pas de clé SSH pour GitHub ont été inondés de messages d’erreur lorsqu’ils ont essayé d’initialiser le sous-module.Nous avons de grands projets pour les prochains mois de développement, notamment la refactorisation de la version NGINX Ingress Controller, la poussée du registre et la logique du nom d'hôte/adresse IP d'entrée.
Une chose que nous avons remarqué à chaque stand-up de MARA est la rapidité avec laquelle nous commençons à voir des analyses et des attaques sur NGINX Ingress Controller. Cela nous a incité à commencer à intégrer NGINX Ingress Controller avec NGINX App Protect WAF dans MARA. Cela implique le défi et l’opportunité de déterminer la meilleure façon de gérer la journalisation produite par App Protect.
Un autre changement que nous prévoyons d’apporter dans les mois à venir est que tous les modules extraient les secrets de Kubernetes plutôt que de Pulumi et de Kubernetes. Cela signifie que tous les modules utilisent un référentiel de secrets commun et donne à l'administrateur le contrôle sur la manière dont les secrets sont renseignés. Nous écrivons un nouveau module pour lire les secrets d’un référentiel choisi par l’utilisateur et créer les secrets Kubernetes correspondants.
MARA inclut actuellement un outil de génération de charge qui est une version améliorée et légèrement modifiée de l'outil basé sur Locust fourni avec l'application Bank of Anthos d'origine à partir de laquelle nous avons dérivé Bank of Sirius. Le nouvel outil de test que nous développons, Cicada Swarm, génère non seulement de la charge, mais suit et signale également lorsque les métriques dépassent les seuils que vous avez définis, ce qui en fait un cadre pour des tests de performances rapides des produits logiciels dans le cloud. Il utilise des techniques de parallélisation pour fournir des résultats de test avec le niveau de confiance dont vous avez besoin, une plus grande précision et une analyse de régression personnalisable pour déterminer le succès ou l'échec des builds sur vos pipelines CI/CD.
Enfin, nous ne pouvons pas évoquer les tests de charge sans parler de la manière dont nous allons mesurer l’impact de ces tests de charge, ce qui nous ramène à la télémétrie. Nous sommes enthousiasmés par le potentiel d’OpenTelemetry et espérons avoir bientôt une implémentation plus complète en place. Même sans une implémentation complète, notre objectif est de pouvoir exécuter un test, mesurer son impact et prendre des décisions opérationnelles sur ce que les données nous disent.
Comme toujours, nous accueillons avec plaisir vos demandes d'extraction , vos problèmes et vos commentaires . Notre objectif avec MARA est d'inspirer la communauté à travailler ensemble pour discuter, essayer, tester et itérer à travers différentes solutions potentielles afin d'accroître notre compréhension de la meilleure façon de déployer et de gérer une application moderne.
Cet article fait partie d'une série. Au fur et à mesure que nous ajoutons des fonctionnalités à MARA, nous publions les détails sur le blog :
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."