Au cours des années d'existence de Pinterest, 300 millions d'utilisateurs du service ont créé plus de 200 milliards de broches sur plus de 4 milliards de cartes. Pour servir cette armée d'utilisateurs et une base de contenu étendue, le portail a développé des milliers de services, allant des microservices que plusieurs processeurs peuvent gérer, et se terminant par des monolithes géants qui tournent sur toute une flotte de machines virtuelles. Et puis le moment est venu où les yeux de la société sont tombés sur les k8. À quoi ressemblait le "cube" en "Intérêt"? Vous en saurez plus à ce sujet grâce à notre traduction du dernier article de blog sur l'ingénierie Pinterest .
Ainsi, des centaines de millions d'utilisateurs et des centaines de milliards de broches. Pour servir cette armée d'utilisateurs et une base de contenu étendue, nous avons développé des milliers de services, allant des microservices pouvant être gérés par plusieurs CPU aux monolithes géants qui tournent sur toute une flotte de machines virtuelles. De plus, nous avons une variété de frameworks qui peuvent également nécessiter des ressources CPU, de la mémoire ou un accès aux E / S.
À l'appui de ce zoo d'outils, l'équipe de développement fait face à un certain nombre de défis:
- Les ingénieurs ne disposent pas d'un moyen unifié pour exécuter un environnement de travail. Les services apatrides, les services avec état et les projets en développement actif sont basés sur des piles technologiques complètement différentes. Cela a conduit à la création d'une formation complète pour les ingénieurs, et complique également sérieusement le travail de notre équipe d'infrastructure.
- Les développeurs disposant de leur propre parc de machines virtuelles créent une charge énorme sur les administrateurs internes. En conséquence, des opérations aussi simples que la mise à jour du système d'exploitation ou de l'AMI durent des semaines et des mois. Cela entraîne une augmentation de la charge de travail dans des situations apparemment absolument quotidiennes.
- Difficultés à créer des outils de gestion d'infrastructure globale en plus des solutions existantes. La situation est compliquée par le fait qu'il n'est pas facile de trouver les propriétaires de machines virtuelles. Autrement dit, nous ne savons pas s'il est sûr d'extraire ces capacités pour travailler dans d'autres parties de notre infrastructure.
Les systèmes d'orchestration de conteneurs sont un moyen d'unifier la gestion de la charge de travail. Ils vous permettent d'augmenter la vitesse de développement et de simplifier la gestion de l'infrastructure, car toutes les ressources impliquées dans le projet sont gérées par un système centralisé.
Figure 1: Priorités de l'infrastructure (fiabilité, productivité des développeurs et efficacité).L'équipe de Cloud Management Platform sur Pinterest a rencontré K8 en 2017. Au premier semestre 2017, nous avons documenté la plupart de nos installations de production, y compris l'API et tous nos serveurs Web. Après cela, nous avons soigneusement évalué les différents systèmes d'orchestration de solutions de conteneurs, en créant des clusters et en travaillant avec eux. Fin 2017, nous avons décidé d'utiliser Kubernetes. Il était suffisamment flexible et largement pris en charge dans la communauté des développeurs.
Jusqu'à présent, nous avons créé nos propres outils d'amorçage de cluster basés sur Kops et migré vers les composants d'infrastructure existants de Kubernetes tels que le réseau, la sécurité, les métriques, la journalisation, la gestion des identités et le trafic. Nous avons également implémenté un système de modélisation de la charge de travail pour notre ressource, dont la complexité est cachée aux développeurs. Désormais, nous nous concentrons sur la stabilité du cluster, son évolutivité et la connexion de nouveaux clients.
Kubernetes: la manière de Pinterest
Débuter avec Kubernetes à l'échelle Pinterest en tant que plate-forme que nos ingénieurs vont adorer est écrasant.
En tant que grande entreprise, nous avons investi massivement dans les outils d'infrastructure. Les exemples incluent les outils de sécurité qui traitent les certificats et distribuent les clés, les composants de contrôle du trafic, les systèmes de découverte de service, la visibilité et l'envoi de journaux et de métriques. Tout cela a été collecté pour une raison: nous avons suivi la voie normale des essais et erreurs, et nous avons donc voulu intégrer toute cette économie dans la nouvelle infrastructure de Kubernetes au lieu de réinventer l'ancien vélo sur une nouvelle plate-forme. Cette approche a généralement simplifié la migration, car toute la prise en charge des applications existe déjà, elle n'a pas besoin d'être créée à partir de zéro.
D'un autre côté, les modèles de prévision de charge dans Kubernetes lui-même (par exemple, les déploiements, les travaux et les kits Daemon) ne sont pas suffisants pour notre projet. Ces problèmes d'utilisabilité sont d'énormes obstacles au passage à Kubernetes. Par exemple, nous avons entendu des développeurs de services se plaindre d'un paramètre de connexion manquant ou incorrect. Nous avons également rencontré une mauvaise utilisation des moteurs de modèle lorsque des centaines de copies ont été créées avec les mêmes spécifications et tâches, ce qui a entraîné des problèmes de cauchemar avec le débogage.
Il était également très difficile de prendre en charge différentes versions dans le même cluster. Imaginez la complexité du support client si vous avez besoin de travailler immédiatement dans de nombreuses versions du même runtime, avec tous leurs problèmes, bugs et mises à jour.
Ressources et contrôleurs personnalisés Pinterest
Pour faciliter la mise en œuvre de Kubernetes pour nos ingénieurs, ainsi que pour simplifier et accélérer l'infrastructure, nous avons développé nos propres définitions de ressources personnalisées (CRD).
Les CRD offrent les fonctionnalités suivantes:
- Combiner diverses ressources natives de Kubernetes pour les faire fonctionner en une seule charge. Par exemple, la ressource PinterestService comprend un déploiement, un service de connexion et une carte de configuration. Cela permet aux développeurs de ne pas se soucier de la configuration du DNS.
- Implémentez le support d'application nécessaire. L'utilisateur doit se concentrer uniquement sur la spécification du conteneur en fonction de sa logique métier, tandis que le contrôleur CRD implémente tous les conteneurs d'initialisation, les variables d'environnement et les spécifications de pod nécessaires. Cela offre aux développeurs un niveau de confort fondamentalement différent.
- Les contrôleurs CRD gèrent également le cycle de vie de leurs propres ressources et augmentent la disponibilité du débogage. Cela comprend l'accord sur les spécifications souhaitées et réelles, la mise à jour de l'état du CRD et la maintenance des journaux d'événements et plus encore. Sans CRD, les développeurs seraient obligés de gérer un large ensemble de ressources, ce qui ne ferait qu'augmenter la probabilité d'une erreur.
Voici un exemple de PinterestService et de la ressource interne contrôlée par notre contrôleur:

Comme vous pouvez le voir ci-dessus, pour prendre en charge un conteneur personnalisé, nous devons intégrer un conteneur d'initialisation et plusieurs modules complémentaires pour garantir la sécurité, la visibilité et travailler avec le trafic réseau. De plus, nous avons créé des modèles de mappage de configuration et implémenté la prise en charge des modèles PVC pour les travaux par lots, ainsi que le suivi de diverses variables d'environnement pour suivre l'identification, la consommation des ressources et la collecte des ordures.
Il est difficile d'imaginer que les développeurs voudraient écrire ces fichiers de configuration manuellement sans prise en charge de CRD, sans parler de la prise en charge et du débogage supplémentaires des configurations.
Déploiement d'applications de workflow

La figure ci-dessus montre comment déployer une ressource personnalisée Pinterest dans un cluster Kubernetes:
- Les développeurs interagissent avec notre cluster Kubernetes via la CLI et l'interface utilisateur.
- Les outils CLI / UI extraient les fichiers YAML de configuration du workflow et d'autres propriétés d'assembly (même identifiant de version) à partir d'Artifactory, puis les envoient au Job Submission Service. Cette étape garantit que seules les versions de production sont livrées au cluster.
- JSS est la passerelle vers diverses plates-formes, dont Kubernetes. C'est là que l'authentification des utilisateurs, l'émission des quotas et la vérification partielle de notre configuration CRD ont lieu.
- Après avoir vérifié le CRD du côté JSS, les informations sont envoyées à l'API de la plate-forme k8s.
- Notre contrôleur CRD surveille les événements sur toutes les ressources utilisateur. Il convertit CR en ressources natives k8s, ajoute les modules nécessaires, définit les variables d'environnement appropriées et effectue d'autres travaux auxiliaires, ce qui garantit aux applications utilisateur des conteneurs un support d'infrastructure suffisant.
- Ensuite, le contrôleur CRD transfère les données reçues à l'API Kubernetes afin qu'elles soient traitées par l'ordonnanceur et mises en service.
Remarque : ce déploiement de workflow pré-version a été créé pour les premiers utilisateurs de la nouvelle plate-forme k8s. Nous sommes maintenant en train de finaliser ce processus afin de nous intégrer pleinement à notre nouveau CI / CD. Cela signifie que nous ne pouvons pas tout dire sur Kubernetes. Nous avons hâte de partager notre expérience et de parler à l'équipe de ces progrès dans notre prochain article de blog «Construire une plateforme CI / CD pour Pinterest».
Types de ressources spéciales
Sur la base des besoins spécifiques de Pinterest, nous avons développé les CRD suivants qui conviennent à une variété de flux de travail:
- PinterestService est un service sans état de longue durée. Beaucoup de nos principaux systèmes sont basés sur un ensemble de ces services.
- PinterestJobSet modélise les travaux par lots à cycle complet. Pinterest a un scénario commun, selon lequel plusieurs tâches exécutent les mêmes conteneurs en parallèle, et indépendamment d'autres processus similaires.
- PinterestCronJob est largement utilisé en conjonction avec de petites charges périodiques. Il s'agit d'un shell natif cron avec des mécanismes de support Pinterest qui sont responsables de la sécurité, du trafic, des journaux et des métriques.
- PinterestDaemon comprend l'infrastructure de Daemon. Cette famille continue de croître à mesure que nous ajoutons davantage de soutien à nos grappes.
- PinterestTrainingJob s'étend aux processus Tensorflow et Pytorch, offrant le même niveau de support en ligne que tous les autres CRD. Puisque Pinterest utilise activement Tensorflow et d'autres systèmes d'apprentissage automatique, nous avions une raison de construire un CRD distinct autour d'eux.
Nous travaillons également sur PinterestStatefulSet, qui sera bientôt adapté pour les entrepôts de données et autres systèmes avec état.
Prise en charge du runtime
Lorsque le module d'application s'exécute dans Kubernetes, il reçoit automatiquement un certificat pour s'identifier. Ce certificat est utilisé pour accéder au magasin secret ou pour communiquer avec d'autres services via mTLS. Pendant ce temps, le configurateur d'initialisation de conteneur et Daemon téléchargeront toutes les dépendances nécessaires avant de lancer l'application conteneur. Lorsque tout est prêt, le trafic sidecar et Daemon enregistrent l'adresse IP du module dans notre Zookeeper afin que les clients puissent la trouver. Tout cela fonctionnera, car le module réseau a été configuré avant le lancement de l'application.
Voici des exemples typiques de prise en charge de la charge de travail au moment de l'exécution. Pour d'autres types de charges de travail, une prise en charge légèrement différente peut être requise, mais elles sont toutes présentées comme des machines virtuelles de niveau pod sidecar, nodal ou Daemon. Nous veillons à ce que tout cela soit déployé dans le cadre de l'infrastructure de gestion et coordonné entre les applications, ce qui en fin de compte réduit considérablement la charge en termes de travail technique et de support client.
Tests et assurance qualité
Nous avons mis en place un pipeline de test de bout en bout au-dessus de l'infrastructure de test Kubernetes existante. Ces tests s'appliquent à tous nos clusters. Notre pipeline a subi de nombreux changements avant de faire partie du cluster de produits.
En plus de tester les systèmes, nous avons des systèmes de surveillance et d'alerte qui surveillent en permanence l'état des composants du système, la consommation des ressources et d'autres indicateurs importants, nous informant uniquement lorsque l'intervention humaine est nécessaire.
Alternatives
Nous avons examiné quelques alternatives aux ressources personnalisées, telles que les contrôleurs d'accès mutationnels et les systèmes de modèles. Cependant, tous sont confrontés à de graves difficultés de travail, nous avons donc choisi la voie de la CRD.
Un contrôleur de tolérance aux mutations a été utilisé pour saisir des side-cars, une variable d'environnement et d'autres supports d'exécution. Néanmoins, il a été confronté à divers problèmes, par exemple avec la liaison des ressources et la gestion de leur cycle de vie, lorsque ces problèmes ne se posent pas dans CRD.
Remarque: Les systèmes de modèles tels que les diagrammes de Helm sont également largement utilisés pour exécuter des applications avec des configurations similaires. Cependant, nos applications de production sont trop diverses pour les gérer avec des modèles. De plus, lors d'un déploiement continu, l'utilisation de modèles générera trop d'erreurs.
Travaux futurs
Nous avons maintenant affaire à une charge mixte sur tous nos clusters. Pour prendre en charge des processus similaires de différents types et tailles, nous travaillons dans les domaines suivants:
- Un cluster de clusters distribue des applications volumineuses sur plusieurs clusters pour offrir évolutivité et stabilité.
- Assurer la stabilité, l'évolutivité et la visibilité du cluster pour créer la connexion de l'application et de son SLA.
- Gestion des ressources et des quotas afin que les applications n'entrent pas en conflit et que l'échelle du cluster soit contrôlée par nous.
- Nouvelle plateforme CI / CD pour la prise en charge et le déploiement d'applications dans Kubernetes.