Note de traduction.Après une récente publication sur les méthodes pull et push en GitOps, nous avons constaté un intérêt pour ce modèle dans son ensemble, cependant, il y a eu peu de publications en russe à ce sujet (il n'y en a tout simplement pas sur Habr). Nous sommes donc heureux de vous proposer la traduction d'un autre article — bien qu'il date déjà d'un an ! — de l'entreprise Weaveworks, dont le dirigeant a inventé le terme « GitOps ». Le texte explique l'essence de l'approche et les principales différences par rapport aux modèles existants.
Il y a un an, nous avons publié À l'époque, nous avons expliqué comment l'équipe de Weaveworks a lancé un SaaS entièrement basé sur Kubernetes et a développé un ensemble de meilleures pratiques prescriptives pour le déploiement, la gestion et la surveillance dans un environnement cloud native.
L'article a été populaire. D'autres personnes ont commencé à parler de GitOps et à publier de nouveaux outils pour , , , , etc. De nombreuses publications et cas d'utilisation de GitOps sont apparus sur notre site. Mais certaines personnes ont encore des questions. En quoi le modèle se distingue-t-il du code d'infrastructure traditionnel? continuous delivery Nous avons rapidement compris qu'il était nécessaire de fournir une nouvelle description, offrant :Une définition précise de GitOps ;
Une comparaison avec la livraison continue traditionnelle.
- Dans cet article, nous avons essayé de couvrir tous ces sujets. Vous y trouverez une introduction mise à jour au GitOps ainsi qu'un point de vue des développeurs et du CI/CD. Nous nous concentrons principalement sur Kubernetes, bien que le modèle puisse être généralisé.
- Voici GitOps
- Zнакомьтесь: GitOps
Z знакомьтесь: GitOps
Z знакомьтесь: GitOps
Imagine Alice. She runs Family Insurance, offering health, auto, property, and travel insurance policies to people who are too busy to navigate the intricacies of contracts themselves. Her business started as a side project while Alice worked as a data scientist at a bank. One day, she realized she could use advanced computer algorithms for more efficient data analysis and to create insurance packages. Investors funded the project, and now her company generates over $20 million a year and is rapidly expanding. Currently, it employs 180 people in various roles, including a tech team responsible for developing, maintaining the website, the database, and analyzing the customer base. The 60-person team is led by Bob — the company’s CTO.
Bob's team deploys production systems in the cloud. Their main applications run on GKE, taking advantage of Kubernetes in Google Cloud. Additionally, they utilize various tools for data handling and analytics.
Family Insurance had no plans to use containers but caught the enthusiasm for Docker. Soon, the company's specialists discovered that GKE allows for easy and casual deployment of clusters for testing new features. Jenkins was added for CI and Quay for organizing the container registry, and scripts for Jenkins were written to push new containers and configurations to GKE.
Un certain temps s'est écoulé. Alice et Bob étaient déçus par les performances de l'approche choisie et son impact sur l'entreprise. L'adoption des conteneurs n'avait pas amélioré les performances autant que l'équipe l'espérait. Parfois, les déploiements échouaient, et il était difficile de déterminer si cela était dû aux modifications du code. Il s'est également avéré difficile de suivre les modifications des configurations. Ils devaient souvent créer un nouveau cluster et y déplacer les applications, car c'était la solution la plus simple pour démêler le désordre dans lequel le système s'était transformé. Alice craignait que la situation ne se détériore à mesure que l'application évoluait (de plus, un nouveau projet basé sur l'apprentissage automatique était en préparation). Bob avait automatisé une grande partie du travail et ne comprenait pas pourquoi le pipeline restait instable, difficile à mettre à l'échelle et nécessitait périodiquement une intervention manuelle.
Puis ils ont entendu parler de GitOps. Cette solution s'est révélée être exactement ce dont ils avaient besoin pour avancer avec assurance.
Alice et Bob entendaient parler depuis des années des workflows basés sur Git, de DevOps et de l'infrastructure en tant que code. L'unicité de GitOps est qu'il introduit un certain nombre de meilleures pratiques - catégoriques et normatives - pour mettre en œuvre ces idées dans le contexte de Kubernetes. Ce sujet , y compris dans le .
Family Insurance décide d'adopter GitOps. L'entreprise dispose désormais d'un modèle opérationnel automatisé, compatible avec Kubernetes et combinant rapidité avec stabilité, car ils :
- ont découvert que la productivité de l'équipe avait doublé sans que personne ne perde la raison ;
- ont cessé de gérer des scripts. Au lieu de cela, ils peuvent maintenant se concentrer sur de nouvelles fonctionnalités et améliorer les méthodes d'ingénierie - par exemple, en introduisant des déploiements canari et en améliorant les tests ;
- ont perfectionné le processus de déploiement - il ne tombe maintenant que rarement en panne ;
- ont acquis la capacité de restaurer les déploiements après des échecs partiels sans intervention manuelle ;
- ont gagné endeconfiance dans les systèmes de livraison. Alice et Bob ont découvert qu'ils pouvaient diviser l'équipe en groupes travaillant sur des microservices en parallèle ;
- pouvaient apporter 30 à 50 modifications au projet chaque jour grâce à chaque groupe et essayer de nouvelles techniques.
- attire facilement de nouveaux développeurs au projet, qui ont la possibilité de déployer des mises à jour en production via des pull requests en quelques heures;
- passe facilement l'audit dans le cadre du SOC2 (concernant la conformité des fournisseurs de services aux exigences de gestion sécurisée des données; pour en savoir plus, par exemple, — n.d.t.).
Que s'est-il passé?
GitOps — c'est deux choses :
- Un modèle d'exploitation pour Kubernetes et cloud native. Il fournit un ensemble de meilleures pratiques pour le déploiement, la gestion et la surveillance des clusters et applications empaquetés dans des conteneurs. Une définition élégante sous forme de à partir de :
- Le chemin vers la création d'un environnement axé sur les développeurs pour la gestion des applications. Nous appliquons le flux de travail Git tant à l'exploitation qu'au développement. Notez qu'il ne s'agit pas simplement d'un Git push, mais de l'organisation de l'ensemble de l'ensemble des outils CI/CD et UI/UX.
Quelques mots sur Git
Si vous n'êtes pas familier avec les systèmes de contrôle de version et le flux de travail basé sur Git, nous vous recommandons vivement de les étudier. Au début, travailler avec des branches et des pull requests peut sembler de la magie noire, mais les avantages valent l'effort. Voici pour commencer.
Comment fonctionne Kubernetes
Dans notre histoire, Alice et Bob se sont tournés vers GitOps après avoir travaillé un certain temps avec Kubernetes. En effet, GitOps est étroitement lié à Kubernetes — c'est un modèle d'exploitation pour l'infrastructure et les applications basées sur Kubernetes.
Qu'est-ce que Kubernetes offre aux utilisateurs?
Voici quelques-unes de ses principales fonctionnalités :
- Dans le modèle Kubernetes, tout peut être décrit de manière déclarative.
- Le serveur API Kubernetes prend une telle déclaration comme entrée, puis essaie en permanence d'amener le cluster à l'état décrit dans la déclaration.
- Les déclarations suffisent pour décrire et gérer une grande variété de charges de travail - "applications".
- En conséquence, les modifications apportées à l'application et au cluster se produisent en raison de :
- modifications des images de conteneurs;
- modifications dans la spécification déclarative;
- erreurs dans l'environnement — par exemple, des échecs de conteneurs.
Les merveilleuses capacités de convergence de Kubernetes
Lorsque l'administrateur apporte des modifications à la configuration, l'orchestrateur Kubernetes les appliquera au cluster jusqu'à ce que son état se rapproche de la nouvelle configuration. Ce modèle fonctionne pour toute ressource Kubernetes et peut être étendu à l'aide de définitions de ressources personnalisées (CRD). Par conséquent, les déploiements Kubernetes possèdent les propriétés merveilleuses suivantes :
- Automatisation: les mises à jour de Kubernetes fournissent un mécanisme pour automatiser le processus de mise en œuvre des modifications de manière correcte et opportune.
- Convergence: Kubernetes continuera d'essayer des mises à jour jusqu'à ce qu'elles réussissent.
- Idempotence: les réapplications de la convergence produisent le même résultat.
- Déterminisme: lorsque les ressources sont suffisantes, l'état du cluster mis à jour dépend uniquement de l'état souhaité.
Comment fonctionne GitOps
Nous'avons suffisamment appris sur Kubernetes pour expliquer les principes du fonctionnement de GitOps.
Revenons aux équipes de Family Insurance liées aux microservices. Quel est leur travail habituel ? Consultez la liste ci-dessous (si certains éléments vous semblent étranges ou inconnus, veuillez patienter avant de critiquer et restez avec nous). Ce ne sont que des exemples de workflows basés sur Jenkins. Il existe également de nombreux autres processus utilisant différents outils.
L'essentiel est que nous voyons que chaque mise à jour se termine par des modifications des fichiers de configuration et des dépôts Git. Ces modifications dans Git entraînent l'actualisation du cluster par l'opérateur GitOps :
1. Flux de travail :Build Jenkins — branche master».
Liste des tâches :
- Jenkins pousse des images taguées dans Quay;
- Jenkins pousse la config et les charts Helm dans le bucket de stockage principal;
- Une fonction cloud copie la config et les charts du bucket de stockage principal dans le dépôt Git principal;
- L'opérateur GitOps met à jour le cluster.
2. Build Jenkins — branche release ou hotfix:
- Jenkins pousse des images non taguées dans Quay;
- Jenkins pousse la config et les charts Helm dans le bucket de stockage de staging;
- Une fonction cloud copie la config et les charts du bucket de staging dans le dépôt Git de staging;
- L'opérateur GitOps met à jour le cluster.
3. Build Jenkins — branche develop ou feature:
- Jenkins pousse des images non taguées dans Quay;
- Jenkins pousse la config et les charts Helm dans le bucket de stockage de développement;
- Une fonction cloud copie la config et les charts du bucket de développement dans le dépôt Git de développement;
- L'opérateur GitOps met à jour le cluster.
4. Ajouter un nouveau client:
- Le gestionnaire ou l'administrateur (LCM/ops) appelle Gradle pour le déploiement initial et la configuration des load balancers réseau (NLB);
- LCM/ops commit la nouvelle config pour préparer le déploiement aux mises à jour;
- L'opérateur GitOps met à jour le cluster.
Description succincte de GitOps
- Décrivez l'état désiré de l'ensemble du système en utilisant des spécifications déclaratives pour chaque environnement (dans notre histoire, l'équipe de Bob définit toute la configuration du système dans Git).
- Le dépôt Git est la seule source de vérité concernant l'état désiré de l'ensemble du système.
- Tous les changements vers l'état désiré se font par le biais de commits dans Git.
- Tous les paramètres désirés du cluster sont également observables dans le cluster lui-même. Ainsi, nous pouvons déterminer si l'état désiré et l'état observé sont (convergent, converge) ou différents (divergent, diverge) l'un de l'autre.
- Si l'état désiré et l'état observé diffèrent, alors :
- Il existe un mécanisme de convergence qui synchronisera tôt ou tard automatiquement l'état cible et l'état observé. Au sein du cluster, cela est géré par Kubernetes.
- Le processus se déclenche immédiatement avec la notification « changement engagé ».
- Après un certain intervalle de temps configurable, une notification « diff » peut être envoyée si les états diffèrent.
- Ainsi, tous les commits dans Git entraînent des mises à jour vérifiables et idempotentes dans le cluster.
- Un rollback est une convergence vers un état désiré précédent.
- La convergence est définitive. Elle se manifeste par :
- L'absence de notifications « diff » pendant un certain temps.
- Une notification « convergé » (par exemple, webhook, événement de retour Git).
Qu'est-ce que la divergence ?
Répétons-le encore une fois : toutes les propriétés désirées du cluster doivent être observables dans le cluster lui-même..
Quelques exemples de divergence :
- Un changement dans le fichier de configuration à cause d'une fusion de branches dans Git.
- Un changement dans le fichier de configuration à cause d'un commit dans Git effectué par un client GUI.
- Multiples changements dans l'état désiré à cause d'un PR dans Git suivi d'une construction d'image de conteneur et de modifications de configuration.
- Un changement dans l'état du cluster à cause d'une erreur, d'un conflit de ressources entraînant un « mauvais comportement », ou simplement d'un écart accidentel par rapport à l'état original.
Qu'est-ce qu'un mécanisme de convergence ?
Quelques exemples :
- Pour les conteneurs et les clusters, le mécanisme de convergence est fourni par Kubernetes.
- Le même mécanisme peut être utilisé pour gérer des applications et des constructions basées sur Kubernetes (par exemple, Istio et Kubeflow).
- Le mécanisme pour gérer l'interaction de travail entre Kubernetes, les dépôts d'images et Git fournit , qui fait partie de .
- Pour les machines de base, le mécanisme de convergence doit être déclaratif et autonome. D'après notre expérience, nous pouvons dire que il est le plus proche de cette définition, mais nécessite néanmoins un contrôle humain. En ce sens, GitOps élargit les traditions de l'Infrastructure as Code.
GitOps combine Git avec un excellent mécanisme de convergence Kubernetes, offrant un modèle pour l'exploitation.
GitOps nous permet d'affirmer que seuls les systèmes pouvant être décrits et observés sont soumis à l'automatisation et au contrôle.
GitOps est destiné à l'ensemble de la pile cloud native (par exemple, Terraform, etc.)
GitOps ne se limite pas à Kubernetes. Nous voulons que tout le système soit géré de manière déclarative et utilise la convergence. Par système, nous entendons l'ensemble des environnements fonctionnant avec Kubernetes - par exemple, « dev cluster 1 », « production », etc. Chaque environnement comprend des machines, des clusters, des applications, ainsi que des interfaces pour des services externes fournissant des données, de la surveillance, etc.
Notez à quel point Terraform est important dans ce cas pour le problème du bootstrapping. Kubernetes doit être déployé quelque part, et l'utilisation de Terraform signifie que nous pouvons appliquer les mêmes workflows GitOps pour créer la couche de contrôle qui sous-tend Kubernetes et les applications. C'est une meilleure pratique utile.
Une grande attention est portée à l'application des concepts GitOps aux couches au-dessus de Kubernetes. À ce jour, il existe des solutions de type GitOps pour Istio, Helm, Ksonnet, OpenFaaS et Kubeflow, ainsi que, par exemple, pour Pulumi, qui créent une couche pour le développement d'applications cloud native.
Kubernetes CI/CD : comparaison de GitOps avec d'autres approches
Comme mentionné, GitOps est deux choses :
- Un modèle d'exploitation pour Kubernetes et cloud native, décrit ci-dessus.
- Le chemin vers l'organisation d'un environnement axé sur les développeurs pour gérer des applications.
Pour beaucoup, GitOps est avant tout un workflow basé sur les push Git. Nous aussi, nous l'aimons. Mais ce n'est pas tout : examinons maintenant les pipelines CI/CD.
GitOps assure un déploiement continu (CD) sous Kubernetes
GitOps propose un mécanisme de déploiement continu, éliminant le besoin de systèmes de gestion des déploiements séparés. Tout le travail est effectué par Kubernetes.
- La mise à jour de l'application nécessite une mise à jour dans Git. Il s'agit d'une mise à jour transactionnelle vers l'état souhaité. Le « déploiement » est ensuite effectué à l'intérieur du cluster par Kubernetes sur la base de la description mise à jour.
- En raison de la nature du fonctionnement de Kubernetes, ces mises à jour sont convergentes. Cela assure un mécanisme pour un déploiement continu, dans lequel toutes les mises à jour sont atomiques.
- Remarque : propose un opérateur GitOps qui intègre Git et Kubernetes et permet d'effectuer CD en harmonisant l'état désiré et l'état actuel du cluster.
Sans kubectl et scripts
Il est déconseillé d'utiliser kubectl pour mettre à jour le cluster, et en particulier des scripts pour regrouper les commandes kubectl. Au lieu de cela, grâce à un pipeline GitOps, l'utilisateur peut mettre à jour son cluster Kubernetes via Git.
Les avantages incluent :
- Précision. Un groupe de mises à jour peut être appliqué, convergé et enfin validé, ce qui nous rapproche de l'objectif d'un déploiement atomique. En revanche, l'utilisation de scripts ne garantit aucune convergence (voir plus de détails ci-dessous).
- Sécurité. Kelsey Hightower : « Limitez l'accès au cluster Kubernetes aux outils d'automatisation et aux administrateurs chargés de le déboguer ou d'assurer sa disponibilité. » Voir également sur la sécurité et la conformité technique, ainsi que par le vol d'identifiants à partir d'un script Jenkins mal conçu.
- Expérience utilisateur. Kubectl expose la mécanique du modèle d'objet de Kubernetes, qui est très complexe. Idéalement, les utilisateurs devraient interagir avec le système à un niveau d'abstraction plus élevé. Ici, je citerai encore Kelsey et recommande de jeter un œil à .
La différence entre CI et CD
GitOps améliore les modèles CI/CD existants.
Un serveur CI moderne est un outil d'orchestration. En particulier, c'est un outil pour orchestrer des pipelines CI. Ils incluent la construction, les tests, la fusion dans la branche principale, etc. Les serveurs CI automatisent la gestion de pipelines complexes à plusieurs étapes. La tentation courante est de créer un script pour un ensemble de mises à jour Kubernetes et de l'exécuter comme un élément du pipeline pour pousser les modifications dans le cluster. En effet, c'est ce que font de nombreux spécialistes. Cependant, ce n'est pas optimal, et voici pourquoi.
CI doit être utilisé pour apporter des mises à jour au trunk, et le cluster Kubernetes doit s'automatiser en fonction de ces mises à jour pour gérer le CD « en interne ». Nous appelons cela , contrairement au modèle de push CI. Le CD fait partie de l'orchestration runtime.
Pourquoi les serveurs CI ne doivent-ils pas faire de CD via des mises à jour directes dans Kubernetes
N'utilisez pas le serveur CI pour orchestrer des mises à jour directes dans Kubernetes sous forme de séries de tâches CI. C'est un anti-modèle, dont nous en dans notre blog.
Revenons à Alice et Bob.
Quels problèmes ont-ils rencontrés ? Le serveur CI de Bob applique des modifications au cluster, mais s'il se crash pendant le processus, Bob ne saura pas dans quel état se trouve (ou devrait se trouver) le cluster et comment le réparer. La même chose est vraie en cas de succès.
Supposons que l'équipe de Bob ait construit une nouvelle image et patché ses déploiements pour déployer l'image (tout cela depuis le pipeline CI).
Si l'image se construit correctement, mais que le pipeline échoue, l'équipe devra déterminer :
- La mise à jour a-t-elle été déployée ?
- Démarrons-nous une nouvelle build ? Cela entraînera-t-il des effets secondaires indésirables — avec la possibilité d’obtenir deux builds de la même image inchangée ?
- Devons-nous attendre la prochaine mise à jour avant de lancer la build ?
- Que s'est-il exactement passé ? Quelles étapes doivent être répétées (et lesquelles peuvent être répétées en toute sécurité) ?
Mettre en place un flux de travail basé sur Git ne garantit pas que l'équipe de Bob n'ait pas de problème avec ces questions. Ils peuvent toujours se tromper dans un push de commit, avec un tag ou tout autre paramètre ; cependant, cette approche est tout de même beaucoup plus proche d'un tout-ou-rien explicite.
En résumé, voici pourquoi les serveurs CI ne devraient pas gérer le CD :
- Les scripts de mise à jour ne sont pas toujours déterministes ; il est facile d'y introduire des erreurs.
- Les serveurs CI ne convergent pas vers un modèle déclaratif du cluster.
- Il est difficile de garantir l'idempotence. Les utilisateurs doivent comprendre la sémantique profonde du système.
- Il est plus compliqué de récupérer après une défaillance partielle.
Remarque sur Helm : si vous souhaitez utiliser Helm, nous vous recommandons de l'associer à un opérateur GitOps tel que . Cela aide à garantir la convergence. Helm, à lui seul, n'est ni déterministe ni atomique.
GitOps comme la meilleure méthode pour réaliser le Continuous Delivery pour Kubernetes
L'équipe d'Alice et Bob implémente GitOps et découvre qu'il est beaucoup plus facile de travailler avec des produits logiciels tout en maintenant une haute performance et stabilité. Terminons cet article avec des illustrations montrant à quoi ressemble leur nouvelle approche. Notez que nous parlons principalement d'applications et de services, bien que GitOps puisse être utilisé pour gérer l'ensemble de la plateforme.
Modèle d'exploitation pour Kubernetes
Regardez le diagramme suivant. Il représente Git et le registre d'images de conteneurs comme des ressources partagées pour deux cycles de vie orchestrés :
- Un pipeline d'intégration continue qui lit et écrit des fichiers dans Git et peut mettre à jour le registre des images de conteneurs.
- Un pipeline Runtime GitOps qui combine déploiement, gestion et observabilité. Il lit et écrit des fichiers dans Git et peut télécharger des images de conteneurs.
Quelles sont les conclusions principales ?
- Séparation des préoccupations: Remarquez que les deux pipelines peuvent échanger des données uniquement en mettant à jour Git ou le registre des images. En d'autres termes, il existe un pare-feu entre l'environnement CI et l'environnement runtime. Nous l'appelons "pare-feu d'immuabilité" (immutability firewall), car toutes les mises à jour des dépôts créent de nouvelles versions. Pour des informations supplémentaires sur ce sujet, veuillez vous référer aux diapositives 72-87 .
- Tout serveur CI et Git peut être utilisé: GitOps fonctionne avec n'importe quels composants. Vous pouvez continuer à utiliser vos serveurs CI et Git préférés, ainsi que vos registres d'images et ensembles de tests. Presque tous les autres outils de Continuous Delivery sur le marché nécessitent leur propre serveur CI/Git ou registre d'images. Cela peut devenir une contrainte dans le développement cloud native. Avec GitOps, vous pouvez utiliser les outils que vous connaissez.
- Événements comme outil d'intégration: Dès que les données dans Git sont mises à jour, Weave Flux (ou l'opérateur Weave Cloud) en informe l'environnement runtime. Chaque fois que Kubernetes accepte un ensemble de changements, Git est mis à jour. Cela garantit un modèle d'intégration simple pour organiser les flux de travail pour GitOps, comme montré ci-dessous.
Conclusion
GitOps fournit des garanties solides de mise à jour nécessaires à tout outil CI/CD moderne :
- automatisation;
- convergence;
- idempotence;
- déterminisme.
C'est important car il offre un modèle d'exploitation pour les développeurs dans le domaine du cloud natif.
- Les outils traditionnels de gestion et de surveillance des systèmes sont liés aux équipes d'exploitation agissant dans le cadre d'un runbook (un ensemble de procédures et d'opérations routinières — note du traducteur), lié à un déploiement spécifique.
- Dans la gestion des systèmes cloud natifs, l'outil de surveillance est le meilleur moyen d'évaluer les résultats des déploiements, permettant ainsi à l'équipe de développeurs de réagir rapidement.
Imaginez de nombreux clusters dispersés à travers divers clouds et de nombreux services avec leurs propres équipes et plans de déploiement. GitOps propose un modèle invariant à grande échelle pour gérer cette abondance.
P.S. de l'auteur
Lisez aussi dans notre blog :
- «»;
- «»;
- «».
Seuls les utilisateurs enregistrés peuvent participer au sondage. , s'il vous plaît.
Saviez-vous ce qu'était GitOps avant ces deux traductions sur Habr?
Oui, je le savais.
Uniquement en surface.
Non
35 utilisateurs ont voté. 10 utilisateurs se sont abstenus.
Source : habr.com
