Notre histoire et nos humbles débuts
Taboola, une entreprise qui compte plus de 500 millions d’utilisateurs actifs quotidiens, a été l’un des premiers à adopter Kubernetes à grande échelle. Dans le passé, la société exécutait ses clusters Kubernetes à l’aide de services basés sur Systemd et les déployait à l’aide de Fantoche comme outil de gestion de configuration. Cependant, à mesure que les versions de Kubernetes devenaient plus fréquentes, nous avons trouvé difficile de suivre les dernières mises à jour et les nouvelles fonctionnalités.
Avant Kubernetes, nous utilisions Nomade clusters pour exécuter nos applications conteneurisées. Cependant, nous avons rapidement réalisé que nous avions besoin d’une infrastructure plus agile et évolutive. Nous nous sommes ensuite tournés vers Kubernetes et avons utilisé le “Kubernetes à la dure», qui a été écrit par Kelsey Hightower de Google, pour initier nos clusters.
Mise à l’échelle de l’infrastructure : défis liés aux mises à niveau et aux modifications
Au fur et à mesure que l’infrastructure de l’entreprise se développait, nous avons trouvé de plus en plus difficile de modifier et de mettre à niveau l’utilisation de Puppet. L’infrastructure de l’entreprise se composait de 7 clusters Kubernetes à grande échelle répartis sur neuf centres de données sur site et des dizaines de milliers de cœurs. Le mécanisme Puppet, qui fonctionne en représentant l’état de l’infrastructure et en le modifiant pour correspondre à l’état souhaité, a créé des défis pour l’équipe de la plate-forme et le niveau de service qu’il fournit car il ne pouvait pas effectuer de modifications progressives sur le cluster sans provoquer de temps d’arrêt.
Par conséquent, l’équipe a accumulé une dette technique importante et nous n’avons pas pu suivre le rythme rapide du cycle de publication de Kubernetes. Nous utilisions une version obsolète de Kubernetes alors que des versions plus récentes étaient déjà disponibles.
Le cycle de publication de Kubernetes a également subi un changement significatif ces derniers temps. En avril 2021, l’équipe de publication open source de Kubernetes est passée de quatre à trois versions par an. Cette décision a assuré un calendrier de publication plus prévisible et une meilleure qualité des versions logicielles.
Malgré ce changement, il est toujours crucial pour les entreprises de se tenir au courant des dernières mises à jour et des nouvelles fonctionnalités de Kubernetes, car il s’agit d’une technologie en évolution rapide qui nécessite un apprentissage et une adaptation continus.
Révolutionner la gestion de l’infrastructure : notre parcours de la voie difficile à Kubeadm
Pour surmonter ces défis, nous avons conçu une solution pour nous permettre d’initier et de relancer des clusters le plus rapidement possible.
Nous nous sommes éloignés de Puppet et avons adopté une approche de gestion d’infrastructure plus agile et évolutive.
Le KubeadmComment, un outil pour initier et gérer des clusters Kubernetes, était devenu stable et de plus en plus adopté. L’équipe a créé un nouveau cluster de développement séparé de l’infrastructure de production pour les tests et l’expérimentation. Cette approche nous a permis de construire, casser et reconstruire plus rapidement. Cela nous a aidés à rattraper la dernière version de Kubernetes.
Processus de gestion des mises à niveau
Après la restructuration de notre infrastructure, les mises à niveau et les travaux de maintenance sont devenus beaucoup plus faciles à gérer. Nous avons créé un processus pour appliquer les mises à niveau sur nos clusters sans aucun temps d’arrêt pour les services de production. Nous avons divisé le processus en trois étapes :
- Tout d’abord, nous rassemblons et décidons de toutes les nouvelles versions logicielles qui construisent notre infrastructure.
- Deuxièmement, nous construisons et testons le processus de mise à niveau avec notre cluster de développement.
- Troisièmement, nous planifions et mettons à niveau nos clusters de production.
La première étape consiste à planifier le processus de mise à niveau. Il s’agit plus d’un travail d’ingénierie que d’un travail d’exécution. Nous listons toutes les applications d’infrastructure qui construisent notre plate-forme Kubernetes et vérifions la prochaine version stable et LTS pour elles. Nous ne prenons jamais le dernier et le meilleur parce que nous privilégions la stabilité aux fonctionnalités. Nous vérifions la compatibilité de ces applications avec les nouvelles versions d’API. Nous vérifions également quelles versions sont largement adoptées par d’autres grands fournisseurs de cloud.
Dans chaque mise à jour de version de Kubernetes, nous devons mettre à niveau les applications d’infrastructure essentielles comme le Calicot CNI, Tour, Istio et plus encore, ce qui est un processus de mise à niveau difficile à planifier.
Nous testons chaque procédure que nous prévoyons sur le cluster de développement. Nous sélectionnons des versions, puis simulons l’ensemble du processus. Après cela, nous avons une idée de ce qui va se passer en production. Habituellement, nous devons ajuster les versions en raison d’une incompatibilité, ou certaines applications ont déjà de nouvelles versions mineures au moment où nous simulons. Nous exécutons le processus des dizaines de fois jusqu’à ce que nous perfectionnions la technique, et ce n’est qu’alors que nous programmons une journée de maintenance à appliquer à la production. Nous l’appelons la méthode “Kung Fu”, et cela fonctionne.
Service de mise à niveau automatisé
Une fois que nous commençons la mise à niveau, nous exploitons et surveillons activement les mises à niveau des nœuds du plan de contrôle, car ils sont intrinsèquement plus sensibles que les nœuds de travail ordinaires. Nous avons automatisé le processus de mise à niveau des nœuds de travail pour le reste du cluster avec un service que nous avons écrit dans Golang.
Nous avons conçu le service pour gérer l’ensemble du processus du début à la fin. Pour ce faire, nous nous fixons les objectifs suivants :
un. Exécutez le processus de mise à niveau en arrière-plan sans intervention humaine.
b. Aucun temps d’arrêt pour les services qui s’exécutent sur la plate-forme.
Le service surveillera en permanence la santé et les ressources du cluster. Il s’arrêtera s’il n’y a pas suffisamment de ressources pour faire fonctionner le cluster ou si la santé du cluster se dégrade.
Nous voulions que le service ait des fonctionnalités similaires au mécanisme de déploiement progressif de Kubernetes, dans le sens où lorsque la mise à niveau est bloquée ou que le cluster n’est pas sain, il cesse de continuer. Lorsque le cluster revient à un état sain, il reprend la mise à niveau. Le service de mise à niveau peut être configuré avec des options telles que “max surge” et “max unavailable” comme avec la fonctionnalité de déploiement progressif de Kubernetes. Le service peut également être configuré avec des options telles que : mettre à niveau un ou plusieurs nœuds simultanément, le nombre de nœuds pouvant être exploités simultanément, le nombre de nœuds défaillants qui arrêteront l’ensemble du processus de mise à niveau, le temps d’attente entre les opérations, etc.
Le service a deux composants principaux : un contrôleur et un exécuteur. Le contrôleur surveille le cluster et décide des nœuds à mettre à niveau.
Le contrôleur marque ces nœuds, les draine et lance un seul exécuteur pour que chaque nœud marqué fonctionne.
L’exécuteur est une unité distincte du contrôleur et peut être remplacé par différentes fonctions. Nous avons utilisé le Ansible outil de gestion de configuration pour le processus de mise à niveau, car il nécessitait l’exécution de commandes Linux et des commandes de l’outil Kubeadm. L’exécuteur est un Cosse lancée via un Emploi manifeste par le responsable du traitement. L’image du Pod contient Ansible installé sur une minuscule distribution Linux. Le point d’entrée exécute un playbook Ansible pour mettre à niveau le nœud vers une version plus récente.
L’exécuteur peut être utilisé dynamiquement pour exécuter différents playbooks à la demande. Nous avons utilisé Kubernetes ConfigMap en tant que volume monté pour transmettre le fichier playbook dans le conteneur. L’exécuteur est planifié sur l’un des nœuds du plan de contrôle pour éviter tout conflit avec un nœud au cours d’une mise à niveau. Si l’exécuteur échoue, le Job replanifie le pod jusqu’à ce qu’il réussisse ou ait épuisé toutes les tentatives.
Le playbook de mise à niveau couvre toutes les opérations nécessaires pour mettre à niveau un nœud, y compris l’installation de nouveaux packages, la modification des configurations et le redémarrage des services appropriés.
Une fois que l’exécuteur a terminé la mise à niveau d’un nœud, le contrôleur exécute des tests pour garantir le bon fonctionnement. En cas de succès, le nœud sera renvoyé au cluster. Le contrôleur continue de mettre à niveau les nœuds jusqu’à ce que le cluster devienne défectueux ou que tous les nœuds soient mis à niveau avec succès. L’exécuteur peut être remplacé par d’autres exécutables, ce qui le rend utile pour des opérations supplémentaires.
Mises à niveau automatisées pour des déploiements à grande échelle sans erreur
L’un des avantages de l’utilisation d’un service de mise à niveau automatisé est la réduction de la probabilité d’erreur humaine, ce qui est particulièrement important dans les déploiements à grande échelle comme celui de Taboola. Avec un processus automatique, l’équipe peut être sûre que chaque nœud est correctement mis à niveau et que le processus est cohérent sur tous les nœuds.
Un autre avantage est que l’équipe peut économiser du temps et des ressources. Sans le service automatisé, la mise à niveau des nœuds de travail nécessiterait un travail manuel, qui prend du temps et est sujet aux erreurs. Avec le service, l’équipe peut se concentrer sur d’autres tâches pendant que la mise à niveau est effectuée.
Danger, robot en action
La mise en œuvre d’un service de mise à niveau automatisé a ses défis. L’un des défis est que le service doit être soigneusement conçu et testé pour s’assurer qu’il fonctionne de manière fiable et efficace. L’équipe doit tenir compte de divers facteurs, tels que la taille du cluster, les ressources disponibles et les charges de travail exécutées sur le cluster.
Le service nous sert bien aujourd’hui, et nous l’utilisons souvent. Par exemple, nous avons également utilisé le service pour un projet « docker sunset ». Le projet vise à remplacer le Docker temps d’exécution avec le Conteneur runtime sur nos clusters de production. Au départ, nous n’installions Containerd que sur les nouveaux nœuds rejoignant le cluster. Cependant, il a dû être remplacé après que Docker soit devenu obsolète en tant qu’environnement d’exécution de conteneur dans l’écosystème Kubernetes. Nous avons donc utilisé notre service pour accélérer le processus de passage à la nouvelle application d’exécution. Nous avons conçu un exécuteur qui applique une fonction de réinstallation sur les nœuds pour les réinstaller en tant que machines Containerd. Le résultat est un processus plus rapide et plus contrôlé en utilisant le service.
En fin de compte, en utilisant Kubeadm et en créant un cluster de développement séparé, nous avons pu surmonter nos défis de suivre le rythme rapide du cycle de publication de Kubernetes. Adopter une approche de gestion d’infrastructure plus agile et évolutive est crucial pour les entreprises qui utilisent Kubernetes à grande échelle comme Taboola. Grâce à nos processus de mise à niveau en place, nous pouvons tout maintenir à jour et promouvoir de nouvelles fonctionnalités pour nos équipes de R&D.