BLOG

Plan de contrôle pour le PaaS Kubernetes distribué

Vignette d'Ankur Singla
Ankur Singla
Publié le 15 novembre 2019

Ce blog est le premier d'une série de blogs qui couvrent divers aspects de ce qu'il nous a fallu pour créer et exploiter notre service SaaS :

  1. Plan de contrôle pour le PaaS Kubernetes distribué
  2. Service mesh global pour applications distribuées
  3. Sécurité de la plateforme pour les infrastructures, les applications et les données distribuées
  4. Sécurité des applications et des réseaux des clusters distribués
  5. Observabilité sur une plateforme distribuée à l'échelle mondiale
  6. Opérations et SRE d'une plateforme distribuée à l'échelle mondiale
  7. Cadre de service Golang pour les microservices distribués

Comme nous l'avons décrit dans notre blog précédent , nos clients créent des ensembles complexes et diversifiés de solutions commerciales, telles que la fabrication intelligente, la vidéo-criminalité pour la sécurité publique, le trading algorithmique, les réseaux de télécommunications 5G. Nous devons donc offrir une expérience toujours active, connectée et fiable pour ces applications et leurs utilisateurs finaux.

Étant donné que ces applications pouvaient être exécutées dans plusieurs clusters auprès de fournisseurs de cloud ou sur les sites périphériques des clients, notre équipe de plateforme a dû créer un plan de contrôle distribué et un service PaaS pour déployer, sécuriser et exploiter plusieurs clusters Kubernetes multi-locataires. Ce plan de contrôle distribué a offert de nombreux avantages opérationnels, de mise à l'échelle et de performances que nous aborderons dans notre présentation ( lien vidéo ) — par exemple, comment gérer des milliers de clusters K8 Edge avec GitOps — et également dans un article de blog distinct dans les semaines à venir.

TL;DR (Résumé)

  • Nous n'avons pas pu trouver sur le marché une solution simple à utiliser capable de résoudre le problème du déploiement, de la sécurisation et de l'exploitation de plusieurs clusters d'applications répartis entre des fournisseurs de cloud, des clouds privés ou plusieurs emplacements périphériques.
     
  • Nous n'avons pas pu trouver de distribution Kubernetes ou PaaS robuste (par exemple OpenShift, Cloud Foundry, etc.) qui fournisse un ensemble complet de services de sécurité et opérationnels nécessaires aux clusters distribués, par exemple l'identité basée sur PKI, la gestion RBAC et l'accès des utilisateurs, la gestion des secrets et des clés entre les fournisseurs de cloud, le maillage de services multi-cluster, l'observabilité et les journaux d'audit, ou la sécurité des applications et du réseau.
     
  • Anthos (Google), Azure Arc (Microsoft) et Rancher sont des stations de gestion multi-cluster et un package de plusieurs services différents. Notre analyse a montré que ces solutions n’auraient pas résolu les exigences opérationnelles, de mise à l’échelle, de sécurité et de multi-location que nous avions pour les services d’application et d’infrastructure sur plusieurs clusters.
     
  • Nous avons dû créer notre propre plan de contrôle distribué pour notre PaaS géré, construit sur Kubernetes. Nous avons commencé avec Kubernetes vanilla, puis avons apporté des modifications importantes pour fournir les services de plateforme nécessaires à nos équipes DevOps et SRE. De plus, nous avons dû créer un plan de contrôle pour gérer un grand nombre de clusters distribués et fournir une architecture multi-locataire sur une infrastructure hétérogène (en périphérie, sur notre réseau et auprès de plusieurs fournisseurs de cloud).

Kubernetes pour la gestion des applications : Pourquoi et comment

Nous avons choisi Kubernetes (K8s) comme cœur de notre plateforme de gestion des applications distribuées, car il fournit un riche ensemble de fonctionnalités sans être trop prescriptif, ce qui nous donne la flexibilité d'innover sur des sujets qui, selon nous, sont importants pour nos clients. Nous avons utilisé cela comme base sur laquelle commencer à construire notre service et avec la popularité croissante de K8s, il est également plus facile de trouver des développeurs et des opérateurs qui le connaissent.

Cela dit, déployer et gérer un grand nombre de clusters Kubernetes de qualité production dans un environnement hybride (plusieurs clouds, points de présence réseau et emplacements périphériques) n'est pas très simple car il n'existe pas de solutions prêtes à l'emploi pour Kubernetes qui peuvent :

  1. Harmoniser les ressources d'infrastructure hétérogènes avec un clustering, une mise à l'échelle et un provisionnement sans intervention automatisés ; cela était particulièrement pénible à la périphérie et dans nos points de présence réseau
  2. Offrez une connectivité fiable et performante sur des sites disparates, en particulier lorsque vous utilisez plusieurs fournisseurs de cloud et que vous êtes en provenance d'emplacements périphériques
  3. Résolvez le problème de sécurité des données en transit, des données au repos, des secrets, des clés et du réseau… le tout soutenu par une identité PKI uniforme qui fonctionne sur l'ensemble du périmètre, du réseau et du cloud
  4. Offrez une véritable multi-location (isolation des locataires et garanties de sécurité) avec la possibilité d'exécuter des charges de travail de production et de développement pour les besoins internes et clients sur les mêmes clusters
  5. Offrez une observabilité et des opérations sur des clusters distribués qui s'intègrent à une politique et à une intention centralisées, sans avoir besoin de créer une collecte complexe de journaux et de mesures

Après plusieurs preuves de concept avec plusieurs fournisseurs de cloud et plateformes open source comme GKE, AKS, EKS et RKE ainsi qu'OpenShift et Cloud Foundry, nous avons réalisé qu'aucun d'entre eux ne pouvait répondre à l'ensemble des cinq exigences ci-dessus. En conséquence, nous avons décidé de créer notre propre PaaS, en commençant par Kubernetes « vanilla » et en effectuant plusieurs ajouts pour l’identité, la mise en réseau, la sécurité, le multi-locataire, la journalisation, les métriques, etc. Bien que nous utilisions Kubernetes pour répondre à nos besoins internes, nous avons dû prendre des décisions difficiles, comme ne pas exposer ces clusters Kubernetes directement à nos utilisateurs internes et/ou clients pour exécuter leurs charges de travail (nous y reviendrons plus tard, car le multi-hébergement était un objectif clé pour nous).

En plus des nombreuses nouvelles fonctionnalités que nous devions ajouter, il était également nécessaire d'exécuter nos charges de travail/services parallèlement aux charges de travail des clients dans de nombreux emplacements à travers la périphérie, notre réseau et les clouds publics/privés. Cela signifiait que nous devions créer des capacités supplémentaires pour gérer plusieurs clusters dans plusieurs environnements… tous connectés à l’aide de notre réseau mondial et de nos passerelles d’applications distribuées pour fournir une connectivité de niveau application et de confiance zéro sur ces clusters.

La partie difficile : Multi-Tenancy et Multi-Cluster pour Kubernetes

La création et l’exploitation d’applications exécutées dans un seul cluster Kubernetes est une tâche non triviale, même si elle utilise un cluster géré par un fournisseur de cloud. C’est pourquoi il est courant pour les équipes DevOps et SRE de minimiser leurs frais généraux et de ne pas gérer les complexités de nombreux clusters. Il est assez courant de voir des équipes créer un grand cluster Kubernetes et placer tous les types de ressources dans le même cluster. Bien que cela semble formidable car ils peuvent simplifier les opérations et exécuter le cluster pour une efficacité de calcul et un coût maximum, ce n'est pas la meilleure idée pour plusieurs raisons. Premièrement, les besoins en charges de travail de production sont très différents de ceux des tests et du développement et de la préparation : des charges de travail de développement instables peuvent potentiellement causer des problèmes pour des charges de travail de production plus stables.

Outre les besoins de charges de travail variées, les limitations de sécurité et d'isolement de K8 constituent un autre moteur du multi-cluster. Une approche typique pour résoudre le problème de sécurité et d’isolation des ressources de K8 consiste à créer des clusters indépendants pour chaque locataire à l’aide d’un modèle multi-locataire. Bien que cela soit possible dans le cloud, il n’est pas possible d’exécuter plusieurs clusters en périphérie. Les sites Edge ont des limitations de ressources de calcul et de stockage et une bande passante réseau limitée pour envoyer des journaux et des métriques pour chaque cluster supplémentaire au cloud central.

Pour faire face au problème des multiples clusters Kubernetes, nous avons évalué Rancher pour la gestion centralisée de nos clusters Kubernetes (lorsque nous avons commencé, Anthos et Azure Arc n'existaient pas) et KubeFed. Les deux approches disponibles à l’époque étaient (et sont toujours les mêmes aujourd’hui) :

  1. La gestion multi-cluster (par exemple Rancher) à partir d'une console centrale nous aurait donné la possibilité de déployer plusieurs clusters dans n'importe quel emplacement et d'effectuer des opérations de gestion du cycle de vie telles que les mises à niveau, la restauration, etc. Certains de ces systèmes ont également donné la possibilité d'adresser un cluster individuel avec l'automatisation de la configuration et du déploiement des applications.
     
  2. Une autre approche consiste à déployer un plan de contrôle de fédération de clusters Kubernetes (KubeFed) et il peut faire en sorte que plusieurs clusters physiques ressemblent à un seul cluster. Ce projet venait juste de démarrer au moment où nous l'avons examiné et même aujourd'hui, il n'est qu'en phase alpha.

Après l’annonce récente de GCP Anthos et Azure Arc, nous avons réévalué notre décision initiale de créer un plan de contrôle distribué et la conclusion était que même ces deux nouvelles offres n’auraient pas pu résoudre deux problèmes critiques avec les clusters distribués. Ces deux fonctionnalités clés dont nous avions besoin pour notre plateforme étaient :

  1. Gestion de plusieurs clusters en tant que flotte pour résoudre le problème de l'exécution d'opérations sur l'ensemble ou un groupe logique de clusters : opérations telles que la configuration, le déploiement, les métriques, etc. Ceci est essentiel car nous souhaitons réduire les frais généraux d'exploitation pour nos équipes SRE, améliorer la capacité de débogage de notre DevOps et améliorer l'évolutivité de notre système.
     
  2. Possibilité de découper un cluster Kubernetes physique individuel pour une utilisation multi-locataire sans avoir besoin de créer des clusters physiques. Ceci est particulièrement essentiel dans les environnements aux ressources limitées où nous ne voulons pas ajouter de nouveaux clusters physiques uniquement pour une utilisation multi-locataire.

Pour résoudre ces deux problèmes, nous avons dû mettre au point une nouvelle technique — le plan de contrôle distribué — pour résoudre la surcharge opérationnelle des clusters « multiples » et fournir un équivalent de « clusters multiples » pour la multilocation dans des environnements aux ressources limitées.

Plan de contrôle distribué : Comment nous avons réalisé un Kubernetes multi-cluster

Notre équipe de plateforme a décidé de créer un plan de contrôle distribué pour Kubernetes qui expose les API Kubernetes à l'usage de notre équipe. Cependant, ces API proviennent de clusters « virtuels » qui n'existent que dans notre plan de contrôle : un serveur API K8s virtuel (vK8s) pour un cluster K8s virtuel (comme illustré dans la Figure 1 ). Ce plan de contrôle mappe l’intention de l’utilisateur sur plusieurs clusters Kubernetes physiques exécutés dans notre périphérie, nos POP réseau et nos emplacements de cloud public. Ces clusters physiques ne sont accessibles qu'à notre plan de contrôle distribué, et non à un locataire/utilisateur individuel.

plan de contrôle 01
Figure 1 : Plan de contrôle distribué

Ce plan de contrôle fournit à chaque locataire un ou plusieurs clusters d'applications « virtuels » où il peut déployer ses applications et, en fonction de la configuration, le plan de contrôle les répliquera et les gérera sur plusieurs clusters Kubernetes physiques. Outre les opérations de configuration et de déploiement, les opérations de surveillance suivent également ce cluster « virtuel » sans qu’il soit nécessaire de créer des outils pour collecter et décortiquer les données de plusieurs clusters physiques.

Prenons un exemple d’application d’interface utilisateur appelée productpage, où l’intention de l’utilisateur est de l’exécuter distribuée sur 3 emplacements : pa2-par, ny8-nyc et ams9-ams avec 2 répliques dans chacun d’eux. Lorsque l'utilisateur crée un objet vK8s et l'attache à un cluster virtuel, ce dernier provisionne immédiatement un serveur API vK8s pouvant être utilisé avec kubectl standard.

À l’étape suivante, l’utilisateur télécharge le kubeconfig pour ce cluster virtuel et crée un fichier yaml standard pour décrire un déploiement K8s pour la page produit.

Après la création de la spécification de déploiement, l'utilisateur peut procéder à la création d'un déploiement sur ce cluster virtuel :

Maintenant, si l'utilisateur vérifie son déploiement, il voit que 6 répliques ont été démarrées avec 2 à chaque emplacement (pa2-par, ny8-nyc et ams9-ams).

La sortie suivante montre 2 pods exécutés à chaque emplacement avec un mappage vers un nœud physique particulier

Cet exemple simple montre à quel point il est simple d’obtenir une réplication multi-cluster de n’importe quelle application en quelques minutes sans aucune charge d’installation ni de gestion. En plus de mapper l'intention, le plan de contrôle distribué offre également une observabilité pour le cluster virtuel et non sur une base de cluster individuel.

Contrôle distribué et gestion centralisée pour le multi-locataire

Comme vous pouvez le voir dans la Figure 2 , notre plan de gestion centralisé s’exécute sur deux fournisseurs de cloud public (une région chacun) : un dans AWS et un dans Azure (pour la redondance). Ce plan de gestion permet à notre SRE de créer des locataires avec une multi-location stricte — par exemple, une équipe de développement travaillant sur notre service VoltMesh peut être un locataire et une équipe de solutions client travaillant sur des POC client peut être son propre locataire avec son propre ensemble d'utilisateurs.

Figure 2 : Multi-location et multi-cluster

Chacun de ces locataires peut créer de nombreux espaces de noms et affecter un groupe d’utilisateurs pour collaborer sur ces espaces de noms. Ces espaces de noms ne sont pas des espaces de noms Kubernetes : ils constituent une limite d’isolement dans notre plateforme avec des règles RBAC et des politiques IAM pour les utilisateurs.

Lorsqu'un utilisateur au sein d'un espace de noms souhaite créer un cluster d'applications, il crée un objet vK8s et celui-ci crée à son tour un serveur API vK8s dans notre plan de gestion. À l’aide de cet objet vK8s, l’utilisateur peut créer des déploiements, des ensembles avec état, des PVC, etc. et le plan de contrôle garantira que ces opérations se produisent sur un ou plusieurs clusters physiques, en fonction des sites associés à l’objet vK8s.

Étant donné que chaque locataire et utilisateur utilise les opérations K8 standard sans aucune modification, le système peut être compatible avec un certain nombre d'outils populaires auprès des opérateurs, par exemple Spinnaker, Helm, Jenkins, etc.

Gains réalisés grâce à un plan de contrôle distribué

Le grand avantage d’un plan de contrôle distribué est qu’il a résolu les problèmes de surcharge opérationnelle pour nos équipes SRE et DevOps. Ils peuvent désormais effectuer des opérations (configuration, déploiement, surveillance, politique, etc.) sur un cluster virtuel et le plan de contrôle le mappera automatiquement sur plusieurs clusters physiques. Outre la simplification opérationnelle pour plusieurs clusters, le plan de contrôle a également résolu le problème de sécurité et d'isolement pour le multi-locataire.

Ce plan de contrôle distribué a également amélioré la productivité des développeurs qui souhaitent ajouter de nouvelles fonctionnalités à notre plateforme : ils n’ont pas besoin de créer une nouvelle automatisation à chaque fois qu’ils ajoutent de nouvelles fonctionnalités qui ont un impact sur la configuration ou les opérations sur plusieurs clusters. Ils utilisent le modèle de configuration basé sur l’intention et le plan de contrôle sait ce qui doit être fait. De plus, ils peuvent continuer à interagir avec cet objet de cluster distribué et multiple — kubernetes virtuel — en utilisant kubectl et non une autre CLI.

Après avoir exécuté ce plan de contrôle dans nos environnements de développement, de test, de préparation et de production pendant plus d’un an, nous avons réalisé que ce plan de contrôle distribué à l’échelle mondiale (exécuté dans nos points de présence réseau) offre également des avantages significatifs en termes d’évolutivité, de performances et de fiabilité, ce que nous n’avions pas complètement imaginé à nos débuts. Nous aborderons cette découverte dans notre prochaine présentation KubeCon et dans un article de blog séparé dans les semaines à venir.

À suivre…

Cette série de blogs couvrira divers aspects de ce qu'il nous a fallu pour créer et exploiter notre service SaaS distribué à l'échelle mondiale avec de nombreux clusters d'applications dans le cloud public, nos PoP de réseau privé et nos sites périphériques. La prochaine étape est Global Service Mesh pour les applications distribuées