Nos résultats d'une année de migration de GitLab.com vers Kubernetes

Noter. trad.: L'adoption de Kubernetes chez GitLab est considérée comme l'un des deux principaux facteurs contribuant à la croissance de l'entreprise. Cependant, jusqu'à récemment, l'infrastructure du service en ligne GitLab.com était construite sur des machines virtuelles, et il y a seulement environ un an a commencé sa migration vers les K8, qui n'est toujours pas terminée. Nous sommes heureux de présenter la traduction d'un article récent rédigé par un ingénieur GitLab SRE sur la manière dont cela se produit et les conclusions tirées par les ingénieurs participant au projet.

Nos résultats d'une année de migration de GitLab.com vers Kubernetes

Depuis environ un an maintenant, notre division infrastructure migre tous les services exécutés sur GitLab.com vers Kubernetes. Pendant cette période, nous avons rencontré des défis liés non seulement au déplacement des services vers Kubernetes, mais également à la gestion du déploiement hybride pendant la transition. Les précieuses leçons que nous avons apprises seront discutées dans cet article.

Dès le début de GitLab.com, ses serveurs fonctionnaient dans le cloud sur des machines virtuelles. Ces machines virtuelles sont gérées par Chef et installées à l'aide de notre paquet Linux officiel. Stratégie de déploiement au cas où l'application aurait besoin d'être mise à jour, consiste simplement à mettre à jour le parc de serveurs de manière coordonnée et séquentielle à l'aide d'un pipeline CI. Cette méthode - bien que lente et un peu ennuyeux - garantit que GitLab.com utilise les mêmes pratiques d'installation et de configuration que les utilisateurs hors ligne (autogéré) Installations GitLab utilisant nos packages Linux pour cela.

Nous utilisons cette méthode car il est extrêmement important de vivre toutes les peines et toutes les joies que les membres ordinaires de la communauté éprouvent lors de l'installation et de la configuration de leurs copies de GitLab. Cette approche a bien fonctionné pendant un certain temps, mais lorsque le nombre de projets sur GitLab a dépassé les 10 millions, nous avons réalisé qu'elle ne répondait plus à nos besoins de mise à l'échelle et de déploiement.

Premiers pas vers Kubernetes et GitLab cloud natif

Le projet a été créé en 2017 Graphiques GitLab pour préparer GitLab au déploiement dans le cloud et pour permettre aux utilisateurs d'installer GitLab sur des clusters Kubernetes. Nous savions alors que déplacer GitLab vers Kubernetes augmenterait l'évolutivité de la plateforme SaaS, simplifierait les déploiements et améliorerait l'efficacité des ressources informatiques. Dans le même temps, de nombreuses fonctions de notre application dépendaient de partitions NFS montées, ce qui ralentissait la transition depuis les machines virtuelles.

La poussée vers le cloud natif et Kubernetes a permis à nos ingénieurs de planifier une transition progressive, au cours de laquelle nous avons abandonné certaines dépendances de l'application au stockage réseau tout en continuant à développer de nouvelles fonctionnalités. Depuis que nous avons commencé à planifier la migration à l'été 2019, bon nombre de ces limitations ont été résolues, et le processus de migration de GitLab.com vers Kubernetes est désormais bien avancé !

Fonctionnalités de GitLab.com dans Kubernetes

Pour GitLab.com, nous utilisons un seul cluster GKE régional qui gère tout le trafic des applications. Pour minimiser la complexité de la migration (déjà délicate), nous nous concentrons sur les services qui ne dépendent pas du stockage local ou de NFS. GitLab.com utilise une base de code Rails principalement monolithique et nous acheminons le trafic en fonction des caractéristiques de la charge de travail vers différents points de terminaison isolés dans leurs propres pools de nœuds.

Dans le cas du frontend, ces types sont divisés en requêtes vers le Web, API, Git SSH/HTTPS et Registry. Dans le cas du backend, nous répartissons les tâches dans la file d'attente selon diverses caractéristiques en fonction de limites de ressources prédéfinies, qui nous permettent de définir des objectifs de niveau de service (SLO) pour diverses charges de travail.

Tous ces services GitLab.com sont configurés à l'aide d'un graphique Helm GitLab non modifié. La configuration est effectuée dans des sous-graphiques, qui peuvent être activés de manière sélective au fur et à mesure que nous migrons progressivement les services vers le cluster. Même si nous avons décidé de ne pas inclure certains de nos services avec état dans la migration, comme Redis, Postgres, GitLab Pages et Gitaly, l'utilisation de Kubernetes nous permet de réduire radicalement le nombre de VM gérées actuellement par Chef.

Visibilité et gestion de la configuration Kubernetes

Tous les paramètres sont gérés par GitLab lui-même. Pour cela, trois projets de configuration basés sur Terraform et Helm sont utilisés. Nous essayons d'utiliser GitLab lui-même autant que possible pour exécuter GitLab, mais pour les tâches opérationnelles, nous disposons d'une installation GitLab distincte. Cela est nécessaire pour garantir que vous ne dépendez pas de la disponibilité de GitLab.com lors des déploiements et des mises à jour de GitLab.com.

Bien que nos pipelines pour le cluster Kubernetes s'exécutent sur une installation GitLab distincte, il existe des miroirs des référentiels de code qui sont accessibles publiquement aux adresses suivantes :

  • k8s-workloads/gitlab-com — Framework de configuration GitLab.com pour le graphique GitLab Helm ;
  • k8s-workloads/gitlab-helmfiles - Contient des configurations pour les services qui ne sont pas directement associés à l'application GitLab. Ceux-ci incluent des configurations pour la journalisation et la surveillance des clusters, ainsi que des outils intégrés comme PlantUML ;
  • Infrastructure Gitlab-com — Configuration Terraform pour Kubernetes et l'infrastructure de VM existante. Ici, vous configurez toutes les ressources nécessaires à l'exécution du cluster, y compris le cluster lui-même, les pools de nœuds, les comptes de service et les réservations d'adresses IP.

Nos résultats d'une année de migration de GitLab.com vers Kubernetes
La vue publique est affichée lorsque des modifications sont apportées. court résumé avec un lien vers la différence détaillée que SRE analyse avant d'apporter des modifications au cluster.

Pour SRE, le lien mène à une différence détaillée dans l'installation GitLab, qui est utilisée pour la production et dont l'accès est limité. Cela permet aux collaborateurs et à la communauté, sans accès au projet opérationnel (qui n'est ouvert qu'aux SRE), de visualiser les modifications de configuration proposées. En combinant une instance publique GitLab pour le code avec une instance privée pour les pipelines CI, nous maintenons un flux de travail unique tout en garantissant l'indépendance de GitLab.com pour les mises à jour de configuration.

Ce que nous avons découvert lors de la migration

Au cours du déménagement, nous avons acquis une expérience que nous appliquons aux nouvelles migrations et déploiements dans Kubernetes.

1. Augmentation des coûts due au trafic entre les zones de disponibilité

Nos résultats d'une année de migration de GitLab.com vers Kubernetes
Statistiques de sortie quotidiennes (octets par jour) pour la flotte de référentiels Git sur GitLab.com

Google divise son réseau en régions. Celles-ci sont à leur tour divisées en zones d'accessibilité (AZ). L'hébergement Git est associé à de grandes quantités de données, il est donc important pour nous de contrôler la sortie du réseau. Pour le trafic interne, la sortie n’est gratuite que si elle reste dans la même zone de disponibilité. Au moment d'écrire ces lignes, nous traitons environ 100 To de données au cours d'une journée de travail typique (et cela concerne uniquement les référentiels Git). Les services qui résidaient dans les mêmes machines virtuelles dans notre ancienne topologie basée sur les machines virtuelles s'exécutent désormais dans différents pods Kubernetes. Cela signifie qu’une partie du trafic qui était auparavant local sur la VM pourrait potentiellement voyager en dehors des zones de disponibilité.

Les clusters GKE régionaux vous permettent de couvrir plusieurs zones de disponibilité à des fins de redondance. Nous envisageons la possibilité diviser le cluster GKE régional en clusters à zone unique pour les services qui génèrent de gros volumes de trafic. Cela réduira les coûts de sortie tout en maintenant la redondance au niveau du cluster.

2. Limites, demandes de ressources et mise à l'échelle

Nos résultats d'une année de migration de GitLab.com vers Kubernetes
Nombre de réplicas traitant le trafic de production sur Registry.gitlab.com. Le trafic culmine à ~ 15h00 UTC.

Notre histoire de migration a commencé en août 2019, lorsque nous avons migré notre premier service, GitLab Container Registry, vers Kubernetes. Ce service critique à fort trafic était un bon choix pour la première migration car il s'agit d'une application sans état avec peu de dépendances externes. Le premier problème que nous avons rencontré était un grand nombre de pods expulsés en raison d’un manque de mémoire sur les nœuds. Pour cette raison, nous avons dû modifier les demandes et les limites.

Il a été découvert que dans le cas d'une application où la consommation de mémoire augmente avec le temps, de faibles valeurs de requêtes (réservation de mémoire pour chaque pod) couplées à une limite stricte d'utilisation « généreuse » entraînaient une saturation. (saturation) nœuds et un niveau élevé d’expulsions. Pour résoudre ce problème, il s'agissait il a été décidé d'augmenter les demandes et d'abaisser les limites. Cela a soulagé les nœuds et garanti que les pods avaient un cycle de vie qui n'exerçait pas trop de pression sur le nœud. Nous commençons maintenant les migrations avec des valeurs de demande et limites généreuses (et presque identiques), en les ajustant si nécessaire.

3. Métriques et journaux

Nos résultats d'une année de migration de GitLab.com vers Kubernetes
La division infrastructure se concentre sur la latence, les taux d'erreur et la saturation des systèmes installés. objectifs de niveau de service (SLO) lié à disponibilité générale de notre système.

Au cours de l'année écoulée, l'un des événements clés de la division Infrastructure a été l'amélioration de la surveillance et de la collaboration avec les SLO. Les SLO nous ont permis de fixer des objectifs pour des services individuels que nous avons étroitement surveillés pendant la migration. Mais même avec cette observabilité améliorée, il n’est pas toujours possible de détecter immédiatement les problèmes à l’aide de mesures et d’alertes. Par exemple, en nous concentrant sur la latence et les taux d’erreur, nous ne couvrons pas entièrement tous les cas d’utilisation d’un service en cours de migration.

Ce problème a été découvert presque immédiatement après la migration de certaines charges de travail vers le cluster. Cela est devenu particulièrement aigu lorsque nous avons dû vérifier des fonctions pour lesquelles le nombre de requêtes était faible, mais qui avaient des dépendances de configuration très spécifiques. L'une des principales leçons de la migration était la nécessité de prendre en compte non seulement les métriques lors de la surveillance, mais également les journaux et la « longue traîne ». (C'est à propos de telle leur répartition sur la carte - env. trad.) les erreurs. Désormais, pour chaque migration, nous incluons une liste détaillée des requêtes de journaux (requêtes de journal) et planifier des procédures de retour en arrière claires qui peuvent être transférées d'une équipe à l'autre si des problèmes surviennent.

Servir les mêmes requêtes en parallèle sur l'ancienne infrastructure de VM et la nouvelle infrastructure basée sur Kubernetes représentait un défi unique. Contrairement à la migration lift-and-shift (transfert rapide des applications « telles quelles » vers une nouvelle infrastructure ; plus de détails peuvent être lus, par exemple, ici - environ. trad.), le travail parallèle sur les « anciennes » VM et Kubernetes nécessite que les outils de surveillance soient compatibles avec les deux environnements et soient capables de combiner les métriques en une seule vue. Il est important que nous utilisions les mêmes tableaux de bord et requêtes de journaux pour obtenir une observabilité cohérente pendant la période de transition.

4. Basculer le trafic vers un nouveau cluster

Pour GitLab.com, une partie des serveurs est dédiée à stade canari. Canary Park sert nos projets internes et peut également activé par les utilisateurs. Mais il est avant tout conçu pour tester les modifications apportées à l’infrastructure et à l’application. Le premier service migré a commencé par accepter une quantité limitée de trafic interne, et nous continuons à utiliser cette méthode pour garantir que les SLO sont respectés avant d'envoyer tout le trafic vers le cluster.

Dans le cas d'une migration, cela signifie que les requêtes vers les projets internes sont d'abord envoyées à Kubernetes, puis nous basculons progressivement le reste du trafic vers le cluster en modifiant le poids du backend via HAProxy. Lors de la migration de VM vers Kubernetes, il est devenu évident qu'il était très avantageux de disposer d'un moyen simple de rediriger le trafic entre l'ancienne et la nouvelle infrastructure et, par conséquent, de garder l'ancienne infrastructure prête à être restaurée dans les premiers jours suivant la migration.

5. Capacités de réserve des pods et leur utilisation

Presque immédiatement, le problème suivant a été identifié : les pods pour le service de registre ont démarré rapidement, mais le lancement des pods pour Sidekiq a pris jusqu'à deux minutes. Le long temps de démarrage des pods Sidekiq est devenu un problème lorsque nous avons commencé à migrer des charges de travail vers Kubernetes pour les travailleurs qui devaient traiter les tâches et évoluer rapidement.

Dans ce cas, la leçon est que même si l'HPA (Horizontal Pod Autoscaler) de Kubernetes gère bien la croissance du trafic, il est important de prendre en compte les caractéristiques des charges de travail et d'allouer de la capacité disponible aux pods (en particulier lorsque la demande est inégalement répartie). Dans notre cas, il y a eu une augmentation soudaine du nombre de tâches, entraînant une mise à l'échelle rapide, ce qui a conduit à une saturation des ressources CPU avant que nous ayons eu le temps de faire évoluer le pool de nœuds.

Il est toujours tentant de retirer le plus possible d'un cluster, cependant, après avoir rencontré au départ des problèmes de performances, nous commençons maintenant avec un budget de pod généreux et le réduisons plus tard, en surveillant de près les SLO. Le lancement des pods pour le service Sidekiq s'est considérablement accéléré et prend désormais environ 40 secondes en moyenne. De la réduction du temps de lancement des pods a gagné à la fois GitLab.com et nos utilisateurs d'installations autogérées travaillant avec la charte officielle GitLab Helm.

Conclusion

Après avoir migré chaque service, nous nous sommes réjouis des avantages de l'utilisation de Kubernetes en production : un déploiement d'applications plus rapide et plus sûr, une mise à l'échelle et une allocation plus efficace des ressources. De plus, les avantages de la migration vont au-delà du service GitLab.com. Chaque amélioration de la charte officielle Helm profite à ses utilisateurs.

J'espère que vous avez apprécié l'histoire de nos aventures de migration Kubernetes. Nous continuons à migrer tous les nouveaux services vers le cluster. Des informations supplémentaires peuvent être trouvées dans les publications suivantes :

PS du traducteur

A lire aussi sur notre blog :

Source: habr.com

Ajouter un commentaire