Chef chez PagerDuty
Il s'agit du premier article d'une série en plusieurs parties sur certains des défis opérationnels que l'équipe de PagerDuty résout.
Chez PagerDuty, nous nous efforçons d'assurer une haute disponibilité à chaque couche de notre pile. Nous y parvenons en écrivant des logiciels résilients qui fonctionnent ensuite sur une infrastructure résiliente. Nous en tenons compte lorsque nous concevons l’automatisation de notre infrastructure. Nous supposons que les pièces échoueront et que nous devrons les remplacer ou les reconstruire rapidement.
Pour ce premier article sur notre équipe d'ingénierie opérationnelle, nous aborderons la manière dont nous automatisons notre infrastructure à l'aide de Chef, un outil de gestion de configuration hautement extensible, basé sur Ruby et piloté par la recherche, et les pratiques que nous avons apprises. Nous aborderons notre flux de travail typique et la manière dont nous garantissons que nous pouvons déployer en toute sécurité une nouvelle infrastructure résiliente et prévisible.
L'équipe
Avant de plonger dans les détails techniques, d’abord, quelques informations sur l’équipe derrière la magie. Notre équipe d’ingénierie des opérations chez PagerDuty est actuellement composée de 4 ingénieurs. L'équipe est responsable de quelques domaines : l'automatisation de l'infrastructure, la sécurité au niveau de l'hôte, la persistance/les magasins de données et les outils de productivité. L'équipe est composée de généralistes, chaque membre de l'équipe ayant 1 à 2 domaines de profondeur. Bien que l'équipe d'ingénierie des opérations ait sa propre rotation de garde PagerDuty , chaque équipe d'ingénierie de PagerDuty participe également à la garde.
Le matériel
Nous possédons actuellement plus de 150 serveurs répartis sur plusieurs fournisseurs de cloud. Les serveurs sont répartis en plusieurs environnements (Staging, Load Test et Production) et plusieurs services (serveurs d'applications, serveurs de persistance, équilibreurs de charge et serveurs de messagerie). Chacun de nos trois environnements dispose d'un serveur chef dédié pour empêcher les hôtes de polluer d'autres environnements.
Le flux de travail
La base de code du chef a 3 ans et compte environ 3,5 000 commits.
Voici le squelette de notre référentiel de chef :
- dépôt git
- livres de cuisine (stocke les livres de cuisine communautaires qui contiennent nos personnalisations)
- site-coobooks (stocke nos wrappers autour des livres de cuisine communautaires, nos livres de cuisine personnalisés, lwrps, etc.)
- data_bags (stocke tous les sacs de données qui ne sont pas cryptés)
- lib (bibliothèques Ruby utilisées dans les plugins site-cookbook/* et knife)
- rôles (stocke tous les rôles)
Nous utilisons le workflow de branche de fonctionnalité standard pour notre dépôt. Une fonctionnalité peut être un travail tactique (création d'un nouveau type de service), un travail de maintenance (mise à niveau/correction) ou un travail stratégique (améliorations de l'infrastructure, refactorisation à grande échelle, etc.). Les branches de fonctionnalités sont testées unitairement via Jenkins qui surveille constamment Github pour les nouveaux changements. Nous utilisons ensuite l'environnement de test pour les tests d'intégration. Les branches de fonctionnalités qui réussissent les tests sont ensuite déployées sur le serveur chef de l'environnement de test. Cela dépend de la fonctionnalité, mais la plupart des branches passeront par une révision du code via une demande d'extraction. La révision du code est volontairement manuelle et nous nous assurons qu'au moins un autre membre de l'équipe donne un +1 sur le code. S'il y a un débat plus large sur le code, nous bloquons du temps lors de nos réunions d'équipe pour en discuter. À partir de là, la branche de fonctionnalité est fusionnée et nous invoquons notre script de restauration pour supprimer tous les livres de recettes existants du serveur chef, télécharger tous les rôles, environnements et livres de recettes du master. En général, le processus de restauration prend moins d'une minute. Nous ne suivons aucun calendrier de déploiement strict, nous préférons déployer dès que nous le pouvons. À moins qu'il ne s'agisse d'un correctif, nous préférons effectuer les déploiements pendant les heures de bureau lorsque tout le monde est réveillé. Nous exécutons chef-client tout au long de la semaine une fois par jour via cron. Si nous avons besoin d'une exécution de chef à la demande, nous utilisons pssh ou knife ssh avec un niveau de concurrence contrôlé.
Chef test
Tous les livres de recettes personnalisés PagerDuty ont un répertoire de spécifications qui contient des tests basés sur ChefSpec et nous avons récemment migré vers ChefSpec 3 . Nous utilisons Chefspec et Rspec Les capacités de stubbing sont très importantes, car la grande majorité de nos recettes personnalisées utilisent la recherche, les sacs de données cryptés, etc. Outre les tests unitaires spécifiques aux livres de recettes qui résident dans le sous-répertoire spec des livres de recettes individuels, nous avons un répertoire spec de niveau supérieur, qui contient des tests fonctionnels et unitaires. Les tests unitaires sont principalement des assertions de rôle ou d'environnement basées sur ChefSpec, tandis que les tests fonctionnels sont tous des assertions basées sur lxc et Rspec. La suite de tests fonctionnels utilise chef zero pour créer un serveur en mémoire, puis utilise le script de restauration et le plugin chef restore knife pour émuler un serveur de préparation ou de production. Ensuite, nous générons des fichiers individuels lxc par rôle en utilisant le même processus d'amorçage que nos serveurs de production. Une fois que nous avons réussi à faire converger un nœud, nous affirmons en fonction du rôle. Par exemple, une spécification fonctionnelle de zookeeper se connectera localement par telnet et s'exécutera 'Statistiques' pour voir si les requêtes peuvent être traitées. Cela couvre la majeure partie de notre base de code, à l'exception de l'intégration avec des fournisseurs de cloud individuels.
Gestion des livres de recettes
Nous utilisons beaucoup les livres de cuisine communautaires. Nous essayons de ne pas créer de livres de recettes s'il existe une alternative open source bien entretenue. Nous préférons écrire des livres de recettes wrapper avec un préfixe « pd » qui répond à notre personnalisation par rapport aux livres de recettes de la communauté. Un exemple serait le livre de recettes pd-memcached qui englobe les livres de recettes de la communauté memcached et fournit iptables et d'autres personnalisations spécifiques à PagerDuty .
Les livres de cuisine communautaires ainsi que nos livres de cuisine personnalisés PagerDuty sont gérés par Étagère Berkshelf . Tous les livres de recettes personnalisés (pd-*) restent dans le répertoire site-cookbooks dans chef repo Nous utilisons plusieurs plugins de couteaux personnalisés. Deux d'entre eux, chef restore et chef backup, se chargent de sauvegarder et de restaurer entièrement notre serveur chef (nœuds, clients, sacs de données). Grâce à cela, nous pouvons facilement déplacer les serveurs chef d'un hôte à un autre. D'autres plugins de couteaux sont utilisés pour générer des serveurs, effectuer des démontages et vérifier l'état des services tiers.
Gagner en confiance grâce aux tests et à la prévisibilité
Actuellement, nous sommes confiants quant à notre capacité à générer et à démanteler en toute sécurité notre infrastructure lorsque nous aurons mis en place les tests appropriés. Lorsque nous avons initialement pris une TDD En ce qui concerne notre approche de l'infrastructure, l'équipe a dû apprendre à se débrouiller rapidement. Nous rencontrons toujours des problèmes lorsque nous faisons tourner des nœuds sur plusieurs fournisseurs et des dépendances réseau pour des configurations externes (par exemple, des services de surveillance hébergés, des services de gestion des journaux), nous avons donc introduit des modes de défaillance et des exigences de sécurité supplémentaires. Nous avons répondu à ces défis en adoptant des mesures agressives mémorisation techniques, introduction d'outils d'automatisation des tests de sécurité (par exemple gant ) dans la boîte à outils des opérations (plus d’informations à ce sujet dans un prochain article).
Le problème de gestion des versions entre composants et les efforts proactifs et en amont pour mettre à jour les dépendances constituent toujours un défi majeur. Certains problèmes liés à la qualité du code issus des livres de recettes de la communauté nous ont également gênés. Mais nous comprenons qu'il s'agit de problèmes complexes et limités dans le temps. Nous faisons partie de la communauté plus vaste chargée de les résoudre.