Déploiement d'applications sur VM, Nomad et Kubernetes

Salut tout le monde! Je m'appelle Pavel Agaletsky. Je travaille en tant que chef d'équipe dans une équipe qui développe le système de livraison Lamoda. En 2018, j'ai pris la parole à la conférence HighLoad++ et j'aimerais aujourd'hui présenter une transcription de mon rapport.

Mon sujet est dédié à l’expérience de notre entreprise dans le déploiement de systèmes et de services dans différents environnements. Depuis notre époque préhistorique, lorsque nous déployions tous les systèmes sur des serveurs virtuels ordinaires, pour finir avec la transition progressive de Nomad vers le déploiement dans Kubernetes. Je vais vous dire pourquoi nous l'avons fait et quels problèmes nous avons rencontrés au cours du processus.

Déployer des applications sur une VM

Commençons par le fait qu'il y a 3 ans, tous les systèmes et services de l'entreprise étaient déployés sur des serveurs virtuels classiques. Techniquement, il était organisé de telle manière que tout le code de nos systèmes était stocké et assemblé à l'aide d'outils d'assemblage automatique, à l'aide de Jenkins. À l'aide d'Ansible, il a été déployé de notre système de contrôle de version vers des serveurs virtuels. De plus, chaque système dont disposait notre entreprise était déployé sur au moins 2 serveurs : l'un en tête, le second en queue. Ces deux systèmes étaient absolument identiques l'un à l'autre dans tous leurs réglages, puissance, configuration, etc. La seule différence entre eux était que head recevait du trafic utilisateur, tandis que tail ne recevait jamais de trafic utilisateur.

Pourquoi était-ce fait?

Lorsque nous avons déployé de nouvelles versions de notre application, nous souhaitions garantir un déploiement fluide, c'est-à-dire sans conséquences notables pour les utilisateurs. Ceci a été réalisé grâce au fait que la prochaine version compilée utilisant Ansible a été déployée jusqu'au bout. Là, les personnes impliquées dans le déploiement pouvaient vérifier et s'assurer que tout allait bien : toutes les métriques, sections et applications fonctionnaient ; les scripts nécessaires sont lancés. Ce n’est qu’après avoir été convaincus que tout allait bien que la circulation a été inversée. Il a commencé à aller vers le serveur qui était auparavant en queue. Et celui qui était auparavant le chef est resté sans trafic d'utilisateurs, tout en conservant la version précédente de notre application.

C'était donc transparent pour les utilisateurs. Parce que la commutation est instantanée, puisqu'il s'agit simplement de commuter l'équilibreur. Vous pouvez très facilement revenir à la version précédente en rétablissant simplement l'équilibreur. Nous avons également pu vérifier que l’application était capable d’être produite avant même de recevoir le trafic des utilisateurs, ce qui était très pratique.

Quels avantages avons-nous vu dans tout cela ?

  1. Tout d'abord, c'est suffisant ça marche. Tout le monde comprend comment fonctionne un tel schéma de déploiement, car la plupart des gens ont déjà déployé des serveurs virtuels classiques.
  2. C'est assez de manière fiable, puisque la technologie de déploiement est simple, testée par des milliers d'entreprises. Des millions de serveurs sont déployés de cette façon. C'est difficile de casser quelque chose.
  3. Et finalement nous pourrions obtenir déploiements atomiques. Des déploiements qui se produisent simultanément pour les utilisateurs, sans étape notable de basculement entre l'ancienne version et la nouvelle.

Mais nous avons également vu plusieurs lacunes dans tout cela :

  1. En plus de l'environnement de production, l'environnement de développement, il existe d'autres environnements. Par exemple, assurance qualité et préproduction. A cette époque, nous avions de nombreux serveurs et environ 60 services. C'est pour cette raison qu'il était nécessaire pour chaque service, conserver la dernière version de celui-ci machine virtuelle. De plus, si vous souhaitez mettre à jour les bibliothèques ou installer de nouvelles dépendances, vous devez le faire dans tous les environnements. Vous deviez également synchroniser l'heure à laquelle vous allez déployer la prochaine nouvelle version de votre application avec l'heure à laquelle Devops effectue les paramètres d'environnement nécessaires. Dans ce cas, il est facile de se retrouver dans une situation où notre environnement sera quelque peu différent dans tous les environnements à la fois. Par exemple, dans un environnement d'assurance qualité, il y aura certaines versions de bibliothèques, et dans un environnement de production, il y en aura différentes, ce qui entraînera des problèmes.
  2. Difficulté à mettre à jour les dépendances ton application. Cela ne dépend pas de vous, mais de l'autre équipe. À savoir, de l’équipe devops qui maintient les serveurs. Vous devez leur confier une tâche appropriée et une description de ce que vous souhaitez faire.
  3. À cette époque, nous souhaitions également diviser les grands monolithes dont nous disposions en petits services distincts, car nous comprenions qu'ils seraient de plus en plus nombreux. À cette époque, nous en avions déjà plus de 100. Pour chaque nouveau service, il était nécessaire de créer une nouvelle machine virtuelle distincte, qui devait également être entretenue et déployée. De plus, vous n'avez pas besoin d'une voiture, mais d'au moins deux. À tout cela s’ajoute l’environnement QA. Cela provoque des problèmes et rend plus difficile la création et l’exécution de nouveaux systèmes. processus complexe, coûteux et long.

Par conséquent, nous avons décidé qu'il serait plus pratique de passer du déploiement de machines virtuelles classiques au déploiement de nos applications dans un conteneur Docker. Si vous avez Docker, vous avez besoin d'un système capable d'exécuter l'application dans un cluster, car vous ne pouvez pas simplement créer un conteneur. Habituellement, vous souhaitez suivre le nombre de conteneurs levés afin qu'ils se lèvent automatiquement. Pour cette raison, nous devions sélectionner un système de contrôle.

Nous avons longuement réfléchi à celui que nous pourrions prendre. Le fait est qu'à cette époque, cette pile de déploiement sur des serveurs virtuels ordinaires était quelque peu obsolète, car ils ne disposaient pas des dernières versions des systèmes d'exploitation. À un moment donné, il y avait même FreeBSD, qui n'était pas très pratique à prendre en charge. Nous avons compris qu’il fallait migrer vers docker le plus rapidement possible. Nos développeurs ont examiné leur expérience existante avec différentes solutions et ont choisi un système comme Nomad.

Passer à Nomade

Nomad est un produit de HashiCorp. Ils sont également connus pour leurs autres solutions :

Déploiement d'applications sur VM, Nomad et Kubernetes

"Consul" est un outil de découverte de services.

"Terraforme" - un système de gestion des serveurs qui vous permet de les configurer via la configuration, ce qu'on appelle l'infrastructure en tant que code.

"Vagabond" permet de déployer des machines virtuelles localement ou dans le cloud via des fichiers de configuration spécifiques.

Nomad semblait à l’époque être une solution assez simple vers laquelle on pouvait rapidement basculer sans modifier l’ensemble de l’infrastructure. De plus, c’est assez simple à apprendre. C'est pourquoi nous l'avons choisi comme système de filtration pour notre conteneur.

De quoi avez-vous besoin pour déployer votre système sur Nomad ?

  1. Tout d'abord, vous avez besoin image de docker ton application. Vous devez le construire et le placer dans le référentiel d'images Docker. Dans notre cas, il s'agit d'un artefact - un système qui vous permet d'y insérer divers artefacts de différents types. Il peut stocker des archives, des images Docker, des packages PHP composer, des packages NPM, etc.
  2. Aussi nécessaire fichier de configuration, qui indiquera à Nomad quoi, où et en quelle quantité vous souhaitez déployer.

Lorsque nous parlons de Nomad, il utilise le langage HCL comme format de fichier d'informations, qui signifie Langage de configuration HashiCorp. Il s'agit d'un surensemble de Yaml qui vous permet de décrire votre service en termes Nomad.

Déploiement d'applications sur VM, Nomad et Kubernetes

Il permet d'indiquer combien de conteneurs vous souhaitez déployer, à partir de quelles images leur transmettre divers paramètres lors du déploiement. Ainsi, vous transmettez ce fichier à Nomad, et il lance les conteneurs en production en fonction de celui-ci.

Dans notre cas, nous avons réalisé qu'écrire simplement des fichiers HCL absolument identiques pour chaque service ne serait pas très pratique, car il existe de nombreux services et parfois vous souhaitez les mettre à jour. Il arrive qu'un service soit déployé non pas dans une instance, mais dans plusieurs instances différentes. Par exemple, l’un des systèmes que nous avons en production compte plus de 100 instances en production. Ils s'exécutent à partir des mêmes images, mais diffèrent par les paramètres de configuration et les fichiers de configuration.

Par conséquent, nous avons décidé qu'il serait pratique pour nous de stocker tous nos fichiers de configuration à déployer dans un référentiel commun. De cette façon, ils étaient visibles : ils étaient faciles à entretenir et nous pouvions voir de quels systèmes nous disposions. Si nécessaire, il est également facile de mettre à jour ou de modifier quelque chose. L'ajout d'un nouveau système n'est pas non plus difficile - il vous suffit de créer un fichier de configuration dans le nouveau répertoire. À l'intérieur se trouvent les fichiers suivants : service.hcl, qui contient une description de notre service, et quelques fichiers env qui permettent de configurer ce même service, en cours de déploiement en production.

Déploiement d'applications sur VM, Nomad et Kubernetes

Cependant, certains de nos systèmes sont déployés en production non pas en un seul exemplaire, mais en plusieurs à la fois. Par conséquent, nous avons décidé qu'il serait pratique pour nous de stocker non pas les configurations sous leur forme pure, mais sous leur forme modélisée. Et nous avons choisi Jinja2. Dans ce format, nous stockons à la fois les configurations du service lui-même et les fichiers env nécessaires.

De plus, nous avons placé dans le référentiel un script de déploiement commun à tous les projets, qui vous permet de lancer et de déployer votre service en production, dans l'environnement souhaité, dans la cible souhaitée. Dans le cas où nous avons transformé notre configuration HCL en modèle, le fichier HCL, qui était auparavant une configuration Nomad standard, a commencé dans ce cas à paraître un peu différent.

Déploiement d'applications sur VM, Nomad et Kubernetes

Autrement dit, nous avons remplacé certaines variables d'emplacement de configuration par des insertions de variables provenant de fichiers env ou d'autres sources. De plus, nous avons eu la possibilité de collecter des fichiers HCL de manière dynamique, c'est-à-dire que nous pouvons utiliser non seulement des insertions de variables ordinaires. Étant donné que Jinja prend en charge les boucles et les conditions, vous pouvez également y créer des fichiers de configuration, qui changent en fonction de l'endroit exact où vous déployez vos applications.

Par exemple, vous souhaitez déployer votre service en pré-production et en production. Disons qu'en pré-production, vous ne souhaitez pas exécuter de scripts cron, mais souhaitez simplement voir le service sur un domaine distinct pour vous assurer qu'il fonctionne. Pour quiconque déploie le service, le processus semble très simple et transparent. Tout ce que vous avez à faire est d'exécuter le fichier déployer.sh, de spécifier quel service vous souhaitez déployer et sur quelle cible. Par exemple, vous souhaitez déployer un certain système en Russie, en Biélorussie ou au Kazakhstan. Pour ce faire, modifiez simplement un des paramètres, et vous aurez le bon fichier de configuration.

Lorsque le service Nomad est déjà déployé sur votre cluster, cela ressemble à ceci.

Déploiement d'applications sur VM, Nomad et Kubernetes

Tout d'abord, vous avez besoin d'une sorte d'équilibreur extérieur, qui recevra tout le trafic utilisateur. Il travaillera en collaboration avec Consul et découvrira où, sur quel nœud, à quelle adresse IP se trouve un service spécifique correspondant à un nom de domaine particulier. Les services de Consul proviennent de Nomad lui-même. Puisqu’il s’agit de produits de la même entreprise, ils sont assez liés les uns aux autres. Nous pouvons dire que Nomad, prêt à l'emploi, peut enregistrer tous les services qui y sont lancés dans Consul.

Une fois que votre équilibreur de charge frontal sait à quel service envoyer le trafic, il le transmet au conteneur approprié ou à plusieurs conteneurs correspondant à votre application. Bien entendu, il faut aussi penser à la sécurité. Même si tous les services s'exécutent sur les mêmes machines virtuelles dans des conteneurs, cela nécessite généralement d'empêcher le libre accès d'un service à un autre. Nous y sommes parvenus grâce à la segmentation. Chaque service a été lancé dans son propre réseau virtuel, sur lequel étaient prescrites des règles de routage et des règles pour autoriser/refuser l'accès à d'autres systèmes et services. Ils pourraient être situés à la fois à l’intérieur de ce cluster et à l’extérieur de celui-ci. Par exemple, si vous souhaitez empêcher un service de se connecter à une base de données spécifique, cela peut être fait via une segmentation au niveau du réseau. Autrement dit, même par erreur, vous ne pouvez pas vous connecter accidentellement depuis l'environnement de test à votre base de données de production.

Combien nous a coûté la transition en termes de ressources humaines ?

La transition de l'ensemble de l'entreprise vers Nomad a pris environ 5 à 6 mois. Nous avons évolué service par service, mais à un rythme assez rapide. Chaque équipe devait créer ses propres conteneurs pour les services.

Nous avons adopté une approche telle que chaque équipe est responsable indépendamment des images Docker de ses systèmes. DevOps fournit l'infrastructure générale nécessaire au déploiement, c'est-à-dire la prise en charge du cluster lui-même, la prise en charge du système CI, etc. Et à cette époque, nous avions transféré plus de 60 systèmes vers Nomad, ce qui représentait environ 2 XNUMX conteneurs.

Devops est responsable de l'infrastructure générale de tout ce qui concerne le déploiement et les serveurs. Et chaque équipe de développement, à son tour, est responsable de la mise en œuvre des conteneurs pour son système spécifique, puisque c'est l'équipe qui sait ce dont elle a généralement besoin dans un conteneur particulier.

Raisons d’abandonner Nomad

Quels avantages avons-nous obtenus en passant au déploiement utilisant Nomad et Docker, entre autres ?

  1. Nous à conditions égales pour tous les environnements. En développement, environnement QA, pré-production, production, les mêmes images de conteneurs sont utilisées, avec les mêmes dépendances. Par conséquent, vous n’avez pratiquement aucune chance que ce qui finira en production ne soit pas ce que vous avez précédemment testé localement ou dans votre environnement de test.
  2. Nous avons également constaté qu'il suffisait facile d'ajouter un nouveau service. Du point de vue du déploiement, tout nouveau système se lance très simplement. Accédez simplement au référentiel qui stocke les configurations, ajoutez-y une autre configuration pour votre système et vous êtes prêt. Vous pouvez déployer votre système en production sans aucun effort supplémentaire de la part des développeurs.
  3. tous fichiers de configuration dans un référentiel commun s'est avéré être en cours d'examen. Au moment où nous déployions nos systèmes à l'aide de serveurs virtuels, nous utilisions Ansible, dans lequel les configurations se trouvaient dans le même référentiel. Cependant, pour la plupart des développeurs, cela était un peu plus difficile à gérer. Ici, le volume de configurations et de code que vous devez ajouter pour déployer le service est devenu beaucoup plus petit. De plus, il est très facile pour les développeurs de le réparer ou de le modifier. En cas de transitions, par exemple vers une nouvelle version de Nomad, ils peuvent reprendre et mettre à jour en masse tous les fichiers d'exploitation situés au même endroit.

Mais nous avons également rencontré plusieurs inconvénients :

Il s'est avéré que nous n'a pas pu réaliser des déploiements transparents dans le cas de Nomad. Lors du déploiement de conteneurs dans différentes conditions, il pouvait s'avérer en marche, et Nomad le percevait comme un conteneur prêt à recevoir du trafic. Cela s’est produit avant même que l’application qu’il contient ait la chance de se lancer. Pour cette raison, le système a commencé à produire 500 erreurs pendant une courte période, car le trafic commençait à se diriger vers un conteneur qui n'était pas encore prêt à l'accepter.

Nous avons rencontré quelques par les tourbières. Le bug le plus important est que Nomad ne gère pas très bien un grand cluster si vous disposez de nombreux systèmes et conteneurs. Lorsque vous souhaitez retirer l'un des serveurs inclus dans le cluster Nomad pour maintenance, il existe une probabilité assez élevée que le cluster ne se sente pas très bien et s'effondre. Certains conteneurs peuvent par exemple tomber et ne pas monter - cela vous coûtera très cher plus tard si tous vos systèmes de production sont situés dans un cluster géré par Nomad.

Nous avons donc décidé de réfléchir à la prochaine étape. À ce moment-là, nous sommes devenus beaucoup plus conscients de ce que nous voulions réaliser. À savoir : nous voulons de la fiabilité, un peu plus de fonctions que ce que propose Nomad, et un système plus mature et plus stable.

À cet égard, notre choix s'est porté sur Kubernetes comme plateforme de lancement de clusters la plus populaire. D’autant plus que la taille et le nombre de nos conteneurs étaient suffisamment importants. À ces fins, Kubernetes semblait être le système le plus approprié que nous puissions envisager.

Transition vers Kubernetes

Je vais vous parler un peu des concepts de base de Kubernetes et en quoi ils diffèrent de Nomad.

Déploiement d'applications sur VM, Nomad et Kubernetes

Tout d’abord, le concept le plus basique de Kubernetes est le concept de pod. Cosse est un groupe d'un ou plusieurs conteneurs qui fonctionnent toujours ensemble. Et ils fonctionnent toujours comme s’ils étaient strictement sur une seule machine virtuelle. Ils sont accessibles entre eux via IP 127.0.0.1 sur différents ports.

Supposons que vous disposez d'une application PHP composée de nginx et de php-fpm - le schéma classique. Très probablement, vous souhaiterez conserver les conteneurs nginx et php-fpm ensemble à tout moment. Kubernetes vous permet d'y parvenir en les décrivant comme un seul pod commun. C'est exactement ce que nous ne pouvions pas obtenir avec Nomad.

La deuxième notion est déploiement. Le fait est que la capsule elle-même est une chose éphémère : elle démarre et disparaît. Voulez-vous d'abord supprimer tous vos conteneurs précédents, puis lancer de nouvelles versions en même temps, ou souhaitez-vous les déployer progressivement ? C'est le processus dont est responsable le concept de déploiement. Il décrit comment déployer vos pods, en quelle quantité et comment les mettre à jour.

La troisième notion est service. Votre service est en fait votre système, qui reçoit du trafic puis le transmet à un ou plusieurs pods correspondant à votre service. Autrement dit, cela permet de dire que tout le trafic entrant vers tel ou tel service avec tel ou tel nom doit être envoyé vers ces pods spécifiques. Et en même temps, il vous permet d’équilibrer le trafic. Autrement dit, vous pouvez lancer deux pods de votre application et tout le trafic entrant sera équilibré de manière égale entre les pods liés à ce service.

Et le quatrième concept de base est Entrée. Il s'agit d'un service qui s'exécute sur un cluster Kubernetes. Il agit comme un équilibreur de charge externe qui prend en charge toutes les requêtes. À l'aide de l'API Kubernetes, Ingress peut déterminer où ces requêtes doivent être envoyées. De plus, il le fait avec beaucoup de flexibilité. On peut dire que toutes les requêtes adressées à cet hébergeur et telle ou telle URL sont envoyées à ce service. Et ces requêtes arrivant à cet hôte et à une autre URL sont envoyées à un autre service.

Ce qui est le plus cool du point de vue de quelqu'un qui développe une application, c'est que vous puissiez tout gérer vous-même. En définissant la configuration Ingress, vous pouvez envoyer tout le trafic arrivant vers telle ou telle API vers des conteneurs séparés écrits, par exemple, en Go. Mais ce trafic, arrivant vers le même domaine, mais vers une URL différente, devrait être envoyé vers des conteneurs écrits en PHP, où il y a beaucoup de logique, mais ils ne sont pas très rapides.

Si l'on compare tous ces concepts avec Nomad, on peut dire que les trois premiers concepts sont tous ensemble Service. Et ce dernier concept est absent de Nomad lui-même. Nous avons utilisé un équilibreur externe : il peut s'agir de haproxy, nginx, nginx+, etc. Dans le cas d’un cube, vous n’avez pas besoin d’introduire cette notion supplémentaire séparément. Cependant, si vous regardez Ingress en interne, il s'agit soit de nginx, haproxy ou traefik, mais en quelque sorte intégré à Kubernetes.

Tous les concepts que j'ai décrits sont en fait des ressources qui existent au sein d'un cluster Kubernetes. Pour les décrire dans le cube, un format yaml est utilisé, plus lisible et familier que les fichiers HCL dans le cas de Nomad. Mais structurellement, ils décrivent la même chose dans le cas, par exemple, d'un pod. Ils disent : je veux y déployer tels ou tels pods, avec telles ou telles images, en telle ou telle quantité.

Déploiement d'applications sur VM, Nomad et Kubernetes

De plus, nous avons réalisé que nous ne voulions pas créer chaque ressource individuellement à la main : déploiement, services, Ingress, etc. Au lieu de cela, nous voulions décrire chacun de nos systèmes en termes de Kubernetes lors du déploiement, afin de ne pas avoir à recréer manuellement toutes les dépendances de ressources nécessaires dans le bon ordre. Helm a été choisi comme système qui nous a permis de faire cela.

Concepts de base dans Helm

Le casque est directeur chargé d'emballage pour Kubernetes. Cela ressemble beaucoup au fonctionnement des gestionnaires de packages dans les langages de programmation. Ils vous permettent de stocker un service composé, par exemple, du déploiement nginx, du déploiement php-fpm, de la configuration pour Ingress, des configmaps (il s'agit d'une entité qui vous permet de définir l'environnement et d'autres paramètres pour votre système) sous la forme de so- appelés graphiques. En même temps, Helm fonctionne sur Kubernetes. Autrement dit, il ne s'agit pas d'une sorte de système à l'écart, mais simplement d'un autre service lancé à l'intérieur du cube. Vous interagissez avec lui via son API via une commande console. Sa commodité et sa beauté sont que même si helm tombe en panne ou si vous le supprimez du cluster, vos services ne disparaîtront pas, puisque helm ne sert essentiellement qu'à démarrer le système. Kubernetes lui-même est alors responsable des performances et de l’état des services.

Nous avons également réalisé que modélisation, ce que nous étions auparavant obligés de faire nous-mêmes en introduisant jinja dans nos configurations, est l'une des principales fonctionnalités de helm. Toutes les configurations que vous créez pour vos systèmes sont stockées dans helm sous forme de modèles, un peu similaires à jinja, mais, en fait, en utilisant les modèles du langage Go, dans lequel helm est écrit, comme Kubernetes.

Helm ajoute quelques concepts supplémentaires pour nous.

Graphique - ceci est une description de votre service. Dans d'autres gestionnaires de packages, cela s'appellerait un package, un bundle ou quelque chose de similaire. Ici, cela s'appelle graphique.

Valeurs sont les variables que vous souhaitez utiliser pour créer vos configurations à partir de modèles.

Libération. Chaque fois qu'un service déployé à l'aide de helm reçoit une version incrémentielle de la version. Helm se souvient de la configuration du service dans la version précédente, de la version antérieure, etc. Par conséquent, si vous devez effectuer une restauration, exécutez simplement la commande de rappel helm, en la pointant vers la version précédente. Même si la configuration correspondante dans votre référentiel n'est pas disponible au moment de la restauration, helm se souviendra toujours de ce qu'elle était et restaurera votre système à l'état dans lequel il se trouvait dans la version précédente.

Dans le cas où nous utilisons helm, les configurations habituelles pour Kubernetes se transforment également en modèles dans lesquels il est possible d'utiliser des variables, des fonctions et d'appliquer des instructions conditionnelles. De cette façon, vous pouvez collecter la configuration de votre service en fonction de l'environnement.

Déploiement d'applications sur VM, Nomad et Kubernetes

En pratique, nous avons décidé de faire les choses un peu différemment de ce que nous avons fait avec Nomad. Si dans Nomad, les configurations de déploiement et les n variables nécessaires au déploiement de notre service étaient stockées dans un seul référentiel, nous avons décidé ici de les diviser en deux référentiels distincts. Le référentiel « deploy » stocke uniquement les n variables nécessaires au déploiement, et le référentiel « helm » stocke les configurations ou les graphiques.

Déploiement d'applications sur VM, Nomad et Kubernetes

Qu'est-ce que cela nous a apporté ?

Malgré le fait que nous ne stockons aucune donnée vraiment sensible dans les fichiers de configuration eux-mêmes. Par exemple, les mots de passe des bases de données. Ils sont stockés comme secrets dans Kubernetes, mais néanmoins, il y a encore certaines choses auxquelles nous ne voulons pas donner accès à tout le monde. Par conséquent, l'accès au référentiel « deploy » est plus limité, et le référentiel « helm » contient simplement une description du service. C’est pour cette raison qu’il peut être consulté en toute sécurité par un plus grand nombre de personnes.

Puisque nous avons non seulement de la production, mais aussi d'autres environnements, grâce à cette séparation nous pouvons réutiliser nos graphiques de barre pour déployer des services non seulement en production, mais aussi, par exemple, dans un environnement d'assurance qualité. Même pour les déployer localement en utilisant Minikube - c'est une chose pour exécuter Kubernetes localement.

À l'intérieur de chaque référentiel, nous avons laissé une division en répertoires distincts pour chaque service. Autrement dit, à l'intérieur de chaque répertoire se trouvent des modèles liés au graphique correspondant et décrivant les ressources qui doivent être déployées pour lancer notre système. Nous n'avons laissé que les environnements dans le référentiel « deploy ». Dans ce cas, nous n'avons pas utilisé de modèles utilisant jinja, car helm lui-même fournit des modèles prêts à l'emploi - c'est l'une de ses fonctions principales.

Nous avons laissé un script de déploiement - déployer.sh, qui simplifie et standardise le lancement pour le déploiement à l'aide de helm. Ainsi, pour tous ceux qui souhaitent déployer, l'interface de déploiement est exactement la même que lors du déploiement via Nomad. Le même déployer.sh, le nom de votre service et l'endroit où vous souhaitez le déployer. Cela provoque le démarrage interne de la barre. Il collecte à son tour les configurations à partir de modèles, y insère les fichiers de valeurs nécessaires, puis les déploie et les lance dans Kubernetes.

résultats

Le service Kubernetes semble être plus complexe que Nomad.

Déploiement d'applications sur VM, Nomad et Kubernetes

Ici, le trafic sortant arrive à Ingress. Il s'agit simplement du contrôleur frontal, qui prend en charge toutes les requêtes et les envoie ensuite aux services correspondant aux données de la requête. Il les détermine en fonction des configurations qui font partie de la description de votre application dans helm et que les développeurs définissent eux-mêmes. Le service envoie des requêtes à ses pods, c'est-à-dire des conteneurs spécifiques, équilibrant le trafic entrant entre tous les conteneurs appartenant à ce service. Et bien sûr, nous ne devons pas oublier que nous ne devons pas abandonner la sécurité au niveau du réseau. La segmentation fonctionne donc dans un cluster Kubernetes, qui repose sur le balisage. Tous les services ont certaines balises auxquelles sont associés les droits d’accès des services à certaines ressources externes/internes à l’intérieur ou à l’extérieur du cluster.

Au fur et à mesure de la transition, nous avons constaté que Kubernetes possédait toutes les capacités de Nomad, que nous avions précédemment utilisées, et avons également ajouté de nombreuses nouveautés. Il peut être étendu via des plugins, et en fait via des types de ressources personnalisés. Autrement dit, vous avez la possibilité non seulement d'utiliser quelque chose fourni directement avec Kubernetes, mais également de créer votre propre ressource et votre propre service qui lira votre ressource. Cela vous offre des options supplémentaires pour étendre votre système sans avoir à réinstaller Kubernetes et sans nécessiter de modifications.

Un exemple d’une telle utilisation est Prometheus, qui s’exécute au sein de notre cluster Kubernetes. Pour qu'il puisse commencer à collecter des métriques à partir d'un service particulier, nous devons ajouter un type supplémentaire de ressource, ce qu'on appelle le moniteur de service, à la description du service. Prometheus, du fait qu'il peut lire un type de ressource personnalisé lors de son lancement dans Kubernetes, commence automatiquement à collecter les métriques du nouveau système. C'est assez pratique.

Le premier déploiement que nous avons effectué sur Kubernetes a eu lieu en mars 2018. Et pendant cette période, nous n’avons jamais rencontré de problèmes. Cela fonctionne de manière assez stable sans bugs importants. De plus, nous pouvons l’étendre davantage. Aujourd'hui, nous disposons de suffisamment de capacités et nous apprécions vraiment le rythme de développement de Kubernetes. Actuellement, plus de 3000 XNUMX conteneurs se trouvent dans Kubernetes. Le cluster occupe plusieurs nœuds. En même temps, il est utilisable, stable et très contrôlable.

Source: habr.com

Ajouter un commentaire