DEVOXX UK. Kubernetes en production: déploiement bleu / vert, mise à l'échelle automatique et automatisation du déploiement. Partie 2

Kubernetes est un excellent outil pour exécuter des conteneurs Docker dans un environnement de production en cluster. Cependant, il existe des tâches que Kubernetes n'est pas en mesure de résoudre. Avec des déploiements fréquents dans un environnement de production, nous avons besoin d'un déploiement bleu / vert entièrement automatisé pour éviter les temps d'arrêt dans ce processus, qui nécessite également des requêtes HTTP externes et un téléchargement SSL. Cela nécessite une intégration avec un équilibreur de charge tel que ha-proxy. Une autre tâche est la mise à l'échelle semi-automatique du cluster Kubernetes lui-même lorsque vous travaillez dans le cloud, par exemple, la réduction partielle de l'échelle du cluster la nuit.

Bien que Kubernetes ne dispose pas de ces fonctionnalités, il fournit une API qui peut être utilisée pour résoudre de tels problèmes. Les outils de déploiement et de mise à l'échelle automatisés du cluster Kubernetes bleu / vert ont été développés dans le cadre du projet open source Cloud RTI.

Cette transcription vidéo décrit comment configurer Kubernetes avec d'autres composants open source pour obtenir un environnement prêt pour la production qui accepte le code de la modification git commit sans interruption de production.



DEVOXX UK. Kubernetes en production: déploiement bleu / vert, mise à l'échelle automatique et automatisation du déploiement. Partie 1

Donc, après avoir accédé à vos applications depuis le monde extérieur, vous pouvez commencer à configurer complètement l'automatisation, c'est-à-dire l'amener au stade où vous pouvez exécuter git commit et vous assurer que ce git commit se termine en production. Naturellement, dans la mise en œuvre de ces étapes, dans la mise en œuvre du déploiement, nous ne voulons pas faire face à des temps d'arrêt. Ainsi, toute automatisation dans Kubernetes commence par une API.



Kubernetes n'est pas un outil qui peut être utilisé «prêt à l'emploi» de manière productive. Bien sûr, vous pouvez le faire, utiliser kubectl et ainsi de suite, mais l'API est toujours la chose la plus intéressante et utile de cette plate-forme. En utilisant l'API comme un ensemble de fonctionnalités, vous pouvez accéder à presque tout ce que vous voulez faire dans Kubernetes. Kubectl lui-même utilise également l'API REST.

Il s'agit de REST, vous pouvez donc utiliser n'importe quel langage et outil pour travailler avec cette API, mais les bibliothèques utilisateur vous faciliteront grandement la vie. Mon équipe a écrit 2 bibliothèques de ce type: une pour Java / OSGi et une pour Go. La seconde n'est pas souvent utilisée, mais en tout cas, ces choses utiles sont à votre disposition. Il s'agit d'un projet open source partiellement sous licence. Il existe de nombreuses bibliothèques de ce type pour différentes langues, vous pouvez donc choisir la plus appropriée.



Donc, avant de vous lancer dans l'automatisation du déploiement, vous devez vous assurer que ce processus n'est soumis à aucun temps d'arrêt. Par exemple, notre équipe effectue le déploiement de la production au milieu de la journée, lorsque les gens tirent le meilleur parti de leurs applications, il est donc très important d'éviter les retards dans ce processus. Afin d'éviter les temps d'arrêt, 2 méthodes sont utilisées: déploiement bleu / vert ou mise à jour continue mise à jour continue. Dans ce dernier cas, si vous avez 5 répliques de l'application en cours d'exécution, elles sont mises à jour séquentiellement l'une après l'autre. Cette méthode fonctionne très bien, mais elle ne fonctionne pas si vous exécutez différentes versions de l'application en même temps pendant le processus de déploiement. Dans ce cas, vous pouvez mettre à jour l'interface utilisateur pendant que le backend fonctionnera avec l'ancienne version et l'application cessera de fonctionner.Par conséquent, du point de vue de la programmation, travailler dans de telles conditions est plutôt difficile.

C'est l'une des raisons pour lesquelles nous préférons utiliser le déploiement bleu / vert pour automatiser le déploiement de nos applications. Avec cette méthode, vous devez vous assurer qu'à un certain moment, une seule version de l'application est active.

Le mécanisme de déploiement bleu / vert est le suivant. Nous obtenons du trafic pour nos applications via ha-proxy, qui le dirige vers l'exécution de répliques d'applications de la même version.

Lorsqu'un nouveau déploiement est effectué, nous utilisons Deployer, qui est fourni avec de nouveaux composants, et il déploie la nouvelle version. Le déploiement d'une nouvelle version d'une application signifie qu'un nouvel ensemble de répliques "augmente", après quoi ces répliques de la nouvelle version sont lancées dans un nouveau pod distinct. Cependant, ha-proxy ne sait rien à leur sujet et ne leur a jusqu'à présent envoyé aucune charge de travail.

Par conséquent, tout d'abord, il est nécessaire de vérifier la santé des nouvelles versions de santé cheking pour vous assurer que les répliques sont prêtes à servir la charge.



Tous les composants de déploiement doivent prendre en charge une certaine forme de contrôle de santé. Cela peut être une vérification HTTP très simple avec un appel lorsque vous recevez un code avec un statut de 200, ou une vérification plus approfondie, dans laquelle vous vérifiez la connexion des répliques avec la base de données et d'autres services, la stabilité des connexions de l'environnement dynamique, si tout démarre et fonctionne correctement. Ce processus peut être assez compliqué.



Une fois que le système a vérifié que toutes les répliques mises à jour sont opérationnelles, Deployer mettra à jour la configuration et transmettra le bon confd, qui reconfigurera ha-proxy.



Ce n'est qu'après que le trafic sera dirigé vers le dessous avec des répliques de la nouvelle version, et l'ancienne disparaîtra.



Ce mécanisme n'est pas une fonctionnalité de Kubernetes. Le concept de déploiement bleu / vert existe depuis un certain temps et il a toujours utilisé un équilibreur de charge. Tout d'abord, vous dirigez tout le trafic vers l'ancienne version de l'application, et après la mise à niveau, transférez-le complètement vers la nouvelle version. Ce principe est utilisé non seulement dans Kubernetes.

Je vais maintenant vous présenter un nouveau composant de déploiement - Deployer, qui effectue un bilan de santé, reconfigure les proxys, etc. Il s'agit d'un concept qui ne s'applique pas au monde extérieur et qui existe à l'intérieur de Kubernetes. Je vais vous montrer comment créer votre propre concept Deployer à l'aide d'outils open-source.

Ainsi, la première chose que Deployer fait est de créer un contrôleur de réplication RC à l'aide de l'API Kubernetes. Cette API crée des modules et des services pour un déploiement ultérieur, c'est-à-dire qu'elle crée un cluster complètement nouveau pour nos applications. Une fois que le CR a vérifié que les répliques ont commencé, il vérifie leur bilan de santé. Pour ce faire, Deployer utilise la commande GET / health. Il lance les composants de vérification correspondants et vérifie tous les éléments qui assurent le fonctionnement du cluster.



Une fois que tous les pods ont signalé leur «santé», Deployer crée un nouvel élément de configuration - le stockage distribué, etc., qui est utilisé dans Kubernetes, y compris pour stocker la configuration de l'équilibreur de charge. Nous écrivons des données dans etcd, et un petit outil, confd, surveille etcd pour les nouvelles données.

S'il trouve des modifications dans la configuration initiale, il génère un nouveau fichier de paramètres et le transmet à ha-proxy. Dans ce cas, ha-proxy redémarre sans perdre de connexion et traite la charge avec de nouveaux services qui fournissent la nouvelle version de nos applications.



Comme vous pouvez le voir, malgré l'abondance de composants, il n'y a rien de compliqué. Vous avez juste besoin de prêter plus d'attention à l'API et etcd. Je veux vous parler du déployeur open-source que nous utilisons nous-mêmes - c'est Amdatu Kubernetes Deployer.



Il s'agit d'un outil d'orchestration de déploiement Kubernetes avec les fonctionnalités suivantes:

  • Déploiement bleu / vert
  • mise en place d'un équilibreur de charge externe;
  • Gestion des descripteurs de déploiement
  • Gestion réelle du déploiement
  • Contrôles d'intégrité pendant le déploiement
  • implémentation de variables d'environnement dans les pods.

Créé au-dessus de l'API Kubernetes, ce déployeur fournit une API REST pour gérer les descripteurs et les déploiements, ainsi qu'une API Websocket pour les journaux de flux pendant le déploiement.

Il place les données de configuration de l'équilibreur de charge dans etcd, vous ne pouvez donc pas utiliser ha-proxy avec une prise en charge "prête à l'emploi", mais il est facile d'utiliser votre propre fichier de configuration de l'équilibreur. Amdatu Deployer est écrit en Go, tout comme Kubernetes lui-même, et sous licence Apache.

Avant d'utiliser cette version du déployeur, j'ai utilisé le descripteur de déploiement suivant, qui spécifie les paramètres dont j'ai besoin.



L'un des paramètres importants de ce code est d'activer l'indicateur «useHealthCheck». Nous devons indiquer qu'un bilan de santé est requis pendant le processus de déploiement. Cette option peut être désactivée lorsque le déploiement utilise des conteneurs tiers qui n'ont pas besoin d'être vérifiés. Ce descripteur indique également le nombre de répliques et l'URL frontale dont ha-proxy a besoin. À la fin se trouve l'indicateur de spécification du pod podspec, qui appelle Kubernetes pour obtenir des informations sur la configuration du port, l'image, etc. Il s'agit d'un descripteur assez simple au format JSON.

Un autre outil qui fait partie du projet open source Amdatu est Deploymentctl. Il possède une interface utilisateur pour configurer le déploiement, stocke l'historique du déploiement et contient des webhooks pour les rappels par des utilisateurs et des développeurs tiers. Vous ne pouvez pas utiliser l'interface utilisateur, car Amdatu Deployer lui-même est une API REST, mais cette interface peut vous faciliter le déploiement sans impliquer d'API. Deploymentctl est écrit en OSGi / Vertx en utilisant Angular 2.

Maintenant, je vais démontrer ce qui précède à l'écran en utilisant un enregistrement pré-fait, vous n'avez donc pas à attendre. Nous déploierons une application simple sur Go. Ne vous inquiétez pas, si vous n'avez jamais rencontré Go auparavant, il s'agit d'une application très simple, vous devez donc tout comprendre.



Ici, nous créons un serveur HTTP qui ne répond qu'à / health, donc cette application ne vérifie que le bilan de santé et rien d'autre. Si la vérification réussit, la structure JSON illustrée ci-dessous est invoquée. Il contient la version de l'application qui sera déployée par le déployeur, le message que vous voyez en haut du fichier et le type de données logique booléen - que notre application fonctionne ou non.

J'ai un peu triché avec la dernière ligne, car j'ai placé une valeur booléenne fixe en haut du fichier, ce qui m'aidera à l'avenir à déployer même une application «malsaine». Nous y reviendrons plus tard.

Alors, commençons. Tout d'abord, nous vérifions les pods en cours d'exécution à l'aide de la commande ~ kubectl get pods, et s'il n'y a pas de réponse de l'URL frontend, nous nous assurons qu'aucun déploiement n'est en cours.



Ensuite, à l'écran, vous voyez l'interface Deploymentctl que j'ai mentionnée, dans laquelle les paramètres de déploiement sont définis: espace de noms, nom d'application, version de déploiement, nombre de répliques, URL frontale, nom du conteneur, image, limites de ressources, numéro de port pour vérifier le contrôle de santé, etc. . Les limites de ressources sont très importantes, car elles vous permettent d'utiliser la quantité maximale possible de "fer". Vous pouvez également voir le journal de déploiement du journal de déploiement ici.



Si vous répétez la commande ~ kubectl get pods maintenant, vous pouvez voir que le système "se bloque" pendant 20 secondes, pendant lesquelles la reconfiguration ha-proxy se produit. Après cela, il démarre sous et notre réplique peut être vue dans le journal de déploiement.



J'ai coupé une attente de 20 secondes dans la vidéo, et maintenant vous voyez à l'écran que la première version de l'application est déployée. Tout cela n'a été fait qu'avec l'aide de l'interface utilisateur.



Essayons maintenant la deuxième version. Pour ce faire, je modifie le message de l'application par "Bonjour, Kubernetes!" à "Bonjour, Deployer!", le système crée cette image et la place dans le registre Docker, après quoi nous cliquons simplement sur le bouton "Déployer" dans la fenêtre Deploymentctl. Dans ce cas, le journal de déploiement est automatiquement lancé de la même manière que lors du déploiement de la première version de l'application.



La commande ~ kubectl get pods montre que 2 versions de l'application sont en cours d'exécution, mais le front-end montre que nous exécutons toujours la version 1. L'



équilibreur de charge attend jusqu'à ce que le contrôle d'intégrité soit effectué, puis redirige le trafic vers la nouvelle version. Après 20 secondes, nous passons en curl et constatons que nous avons maintenant déployé la version 2 de l'application et que la première est supprimée.



C'était le déploiement d'une application «saine» - saine -. Voyons ce qui se passe si, pour la nouvelle version de l'application, je change la valeur du paramètre Healthy de true en false, c'est-à-dire que j'essaierai de déployer une application malsaine qui n'a pas passé le bilan de santé. Cela peut se produire si, au stade du développement, des erreurs de configuration ont été commises dans l'application et qu'elles sont entrées en production sous cette forme.

Comme vous pouvez le voir, le déploiement passe par toutes les étapes ci-dessus, et ~ kubectl get pods montre que les deux pods sont en cours d'exécution. Mais contrairement au déploiement précédent, le journal affiche l'état du délai d'expiration. Autrement dit, en raison du fait que le bilan de santé n'a pas réussi, la nouvelle version de l'application ne peut pas être déployée. Par conséquent, vous voyez que le système a recommencé à utiliser l'ancienne version de l'application et que la nouvelle version a simplement été supprimée.



La bonne chose à ce sujet est que même si vous avez un grand nombre de demandes simultanées entrant dans l'application, elles ne remarqueront même pas les temps d'arrêt pendant la mise en œuvre de la procédure de déploiement. Si vous testez cette application à l'aide du framework Gatling, qui lui envoie le nombre maximal de requêtes possible, aucune de ces requêtes ne sera supprimée. Cela signifie que nos utilisateurs ne remarqueront même pas les mises à jour de version en temps réel. S'il échoue, le travail se poursuivra sur l'ancienne version; s'il réussit, les utilisateurs passeront à la nouvelle version.

Une seule chose peut entraîner un échec: si le contrôle d'intégrité a réussi et que l'application s'est bloquée dès qu'elle a reçu la charge de travail, c'est-à-dire que l'effondrement ne se produit qu'une fois le déploiement terminé. Dans ce cas, vous devrez revenir manuellement à l'ancienne version. Nous avons donc examiné comment utiliser Kubernetes avec ses outils open-source. Le processus de déploiement sera beaucoup plus simple si vous intégrez ces outils dans les pipelines de création / déploiement de pipelines Build / Deploy. Dans le même temps, pour démarrer le déploiement, vous pouvez utiliser à la fois l'interface utilisateur et automatiser entièrement ce processus, en appliquant, par exemple, la validation au maître.



Notre serveur de build Build Server créera une image Docker, la collera dans le Docker Hub ou dans tout autre registre que vous utilisez. Le hub Docker prend en charge le webhook, nous pouvons donc démarrer le déploiement à distance via Deployer, comme indiqué ci-dessus. Ainsi, vous pouvez entièrement automatiser le déploiement de l'application en production potentielle.

Passons au sujet suivant - la mise à l'échelle du cluster Kubernetes. Je note que la commande kubectl est une commande de mise à l'échelle. Avec l'aide d'un autre, vous pouvez facilement augmenter le nombre de répliques dans notre cluster. Cependant, dans la pratique, nous voulons généralement augmenter le nombre de nœuds, pas de nœuds.



Dans le même temps, pendant les heures de travail, vous devrez peut-être augmenter, et la nuit, pour réduire le coût des services Amazon, diminuer le nombre d'instances en cours d'exécution de l'application. Cela ne signifie pas que seul le nombre de pods sera suffisamment évolutif, car même si l'un des nœuds n'est pas occupé, vous devez toujours payer Amazon pour cela. Autrement dit, en plus de faire évoluer les foyers, vous devez mettre à l'échelle le nombre de machines utilisées.

Cela peut être délicat car, que nous utilisions Amazon ou un autre service cloud, Kubernetes ne sait rien du nombre de machines utilisées. Il manque un outil qui vous permet de faire évoluer le système au niveau des nœuds.



Nous devrons donc prendre soin des nœuds et des pods. Nous pouvons facilement adapter le lancement de nouveaux nœuds à l'aide de l'API AWS et des machines de groupe de mise à l'échelle pour configurer le nombre de nœuds de travail Kubernetes. Vous pouvez également utiliser cloud-init ou un script similaire pour enregistrer des nœuds dans un cluster Kubernetes.

La nouvelle machine démarre dans le groupe de mise à l'échelle, s'initie en tant que nœud, s'inscrit dans le registre de l'assistant et démarre le travail. Après cela, vous pouvez augmenter le nombre de répliques à utiliser sur les nœuds résultants. La réduction de l'échelle nécessite plus d'efforts, car vous devez vous assurer qu'une telle étape n'entraînera pas la destruction des applications déjà en cours d'exécution après l'arrêt des machines "inutiles". Pour éviter ce scénario, vous devez amener les nœuds à l'état «non programmable». Cela signifie que le planificateur par défaut lors de la planification des pods DaemonSet ignorera ces nœuds. Le planificateur ne supprimera rien de ces serveurs, mais il n'y lancera également aucun nouveau conteneur. L'étape suivante consiste à déplacer le nœud de vidange, c'est-à-dire à transférer les foyers de travail de celui-ci vers une autre machine, ou d'autres nœuds qui ont une capacité suffisante pour cela.Après avoir vérifié qu'il n'y a plus de conteneurs sur ces nœuds, vous pouvez les supprimer de Kubernetes. Après cela, pour Kubernetes, ils cessent simplement d'exister. Ensuite, vous devez utiliser l'API AWS pour désactiver les nœuds ou machines inutiles.
Vous pouvez utiliser Amdatu Scalerd, un autre outil de mise à l'échelle open-source similaire à l'API AWS. Il fournit une CLI pour ajouter ou supprimer des nœuds dans un cluster. Sa fonctionnalité intéressante est la possibilité de configurer le planificateur à l'aide du fichier json suivant.



Le code affiché réduit de moitié la capacité du cluster la nuit. Il est configuré comme le nombre de réplicas disponibles et la capacité souhaitée du cluster Amazon. L'utilisation de ce planificateur réduira automatiquement le nombre de nœuds la nuit et les augmentera le matin, économisant ainsi le coût d'utilisation des nœuds d'un service cloud comme Amazon. Cette fonctionnalité n'est pas intégrée à Kubernetes, mais l'utilisation de Scalerd vous permettra de faire évoluer cette plateforme à votre guise.

Je veux attirer votre attention sur le fait que beaucoup de gens me disent: "Tout cela est bien, mais qu'en est-il de ma base de données, qui est généralement dans un état statique?" Comment puis-je exécuter quelque chose comme ça dans un environnement dynamique comme Kubernetes? À mon avis, vous ne devriez pas faire cela, ne devriez pas essayer d'organiser le fonctionnement de l'entrepôt de données à Kubernetes. Techniquement, c'est possible, et il existe des manuels sur Internet à ce sujet, mais cela va sérieusement compliquer votre vie.

Oui, le concept de stockage persistant existe dans Kubernetes, et vous pouvez essayer d'exécuter des entrepôts de données tels que Mongo ou MySQL, mais c'est une tâche assez longue. Cela est dû au fait que les entrepôts de données ne prennent pas pleinement en charge l'interaction avec un environnement dynamique. La plupart des bases de données nécessitent un réglage important, y compris la configuration manuelle du cluster, n'aiment pas la mise à l'échelle automatique et d'autres choses similaires.
Par conséquent, ne compliquez pas votre vie lorsque vous essayez de démarrer un entrepôt de données dans Kubernetes. Organisez leur travail de manière traditionnelle en utilisant des services familiers et donnez simplement à Kubernetes la possibilité de les utiliser.



À la fin du sujet, je veux vous présenter la plate-forme Cloud RTI basée sur Kubernetes, sur laquelle mon équipe travaille. Il fournit une journalisation centralisée, surveille les applications et les clusters, et possède de nombreuses autres fonctionnalités utiles qui vous sont utiles. Il utilise divers outils open source tels que Grafana pour afficher la surveillance.





La question a été posée, pourquoi utiliser l'équilibreur de charge ha-proxy avec Kubernetes. Bonne question, car il existe actuellement 2 niveaux d'équilibrage de charge. Les services Kubernetes sont toujours situés sur des adresses IP virtuelles. Vous ne pouvez pas les utiliser pour les ports hôtes externes, car si Amazon redémarre son hôte cloud, l'adresse changera. C'est pourquoi nous plaçons les services ha-proxy devant les services - pour créer une structure plus statique pour une interaction fluide du trafic avec Kubernetes.

Une autre bonne question est de savoir comment puis-je prendre soin de modifier le schéma de la base de données pendant le déploiement bleu / vert? Le fait est que, quelle que soit l'utilisation de Kubernetes, la modification du schéma de la base de données est une tâche complexe. Vous devez vous assurer de la compatibilité de l'ancien et du nouveau schéma, après quoi vous pouvez mettre à jour la base de données, puis mettre à jour les applications elles-mêmes. Vous pouvez échanger à chaud la base de données, puis mettre à niveau les applications. Je connais des gens qui ont téléchargé un tout nouveau cluster de bases de données avec un nouveau schéma, c'est une option si vous avez une base de données sans schéma comme Mongo, mais en tout cas ce n'est pas une tâche facile. S'il n'y a plus de questions, merci de votre attention!


Un peu de publicité :)


Merci de rester avec nous. Aimez-vous nos articles? Vous voulez voir des matériaux plus intéressants? Soutenez-nous en passant une commande ou en recommandant à vos amis des VPS basés sur le cloud pour les développeurs à partir de 4,99 $ , un analogue unique de serveurs d'entrée de gamme que nous avons inventés pour vous: Toute la vérité sur les VPS (KVM) E5-2697 v3 (6 cœurs) 10 Go DDR4 480 Go SSD 1 Gbit / s à partir de 19 $ ou comment diviser le serveur? (les options sont disponibles avec RAID1 et RAID10, jusqu'à 24 cœurs et jusqu'à 40 Go de DDR4).

Dell R730xd 2 fois moins cher au centre de données Equinix Tier IV à Amsterdam? Nous avons seulement 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV à partir de 199 $ aux Pays-Bas!Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - à partir de 99 $! En savoir plus sur la création d'un bâtiment d'infrastructure. classe c utilisant des serveurs Dell R730xd E5-2650 v4 coûtant 9 000 euros pour un sou?

All Articles