L’équipe d’ingénierie dédiée à l’expérience développeur de GitHub travaille à créer des solutions sûres, conviviales et inclusives afin que les ingénieurs de GitHub puissent coder, déployer et exploiter des logiciels avec efficacité, en servant d’exemple au monde sur la manière de construire des logiciels avec GitHub. Pour cela, nous offrons à nos développeurs une voie facilitée — un ensemble complet d’outils et d’applications automatisées destiné à optimiser nos plateformes d’exécution, de déploiement et d’hébergement, qui aide à piloter certains des microservices sur la plateforme GitHub.com et de nombreux outils internes. Examinons plus en détail comment fonctionne l’un de nos principaux chemins facilités.
Notre écosystème de développement
Le chemin pavé principal de GitHub couvre tout ce qui est nécessaire pour exécuter des logiciels : créer, déployer, faire évoluer, déboguer et exécuter des applications. C’est un écosystème d’outils tels que Kubernetes, Docker, des balanceurs de charge et de nombreuses applications personnalisées qui travaillent ensemble pour offrir une expérience cohérente à nos ingénieurs. Il ne s’agit pas seulement d’infrastructure et il ne s’agit pas uniquement de Kubernetes. Kubernetes est notre couche de base, et le chemin pavé est une combinaison de conventions, d’outils et de configurations construites autour de lui.
Les types de services que nous exécutons habituellement via ce chemin incluent des applications web, des pipelines de calcul, des processeurs par lots et des systèmes de surveillance.
Kubernetes, qui est la couche de base du chemin pavé, s’exécute sur une topologie multi-cluster et multi-région.
Avantages du chemin tracé
Il y a des centaines de services sur GitHub — allant d’un petit outil interne à une API externe qui prend en charge des charges de travail en production. Pour diverses raisons, il serait inefficace de créer des machines virtuelles pour chaque service.
- La planification et l’utilisation des capacités à travers tous les services ne seraient pas efficaces. Nous rencontrerions des coûts supplémentaires importants pour la gestion continue de l’infrastructure physique et de Kubernetes.
- Les équipes devraient développer une connaissance approfondie de la gestion de leurs propres clusters Kubernetes et auraient moins de temps pour se concentrer sur les besoins spécifiques de leurs applications.
- Nous aurions moins de visibilité centralisée sur les applications.
- Il serait difficile de standardiser et d’imposer la sécurité et la conformité.
Grâce au chemin pavé basé sur Kubernetes et à d’autres applications d’exécution, nous sommes en mesure de:
- Planifier la capacité de manière centralisée et uniquement pour les nœuds Kubernetes, afin que nous puissions utiliser la capacité de manière optimale entre les nœuds, car des charges de travail petites et grandes coexistent sur les mêmes machines.
- Augmenter rapidement l’échelle grâce à la planification centralisée de la capacité.
- Gérer facilement la configuration et les déploiements de tous les services à partir d’un plan de contrôle central.
- Fournir de manière cohérente des informations sur les performances des applications et des déploiements pour chaque service individuel.
Intégration d’un service
L’intégration d’un service avec le code de son propre dépôt est devenue facile grâce à notre service de commandes ChatOps, appelé Hubot, et les GitHub Apps. Les propriétaires du service peuvent facilement générer la structure de base nécessaire à son déploiement en exécutant une commande telle que :
hubot gh-platform app scaffold monalisa-app
Une application GitHub personnalisée installée dans le dépôt GitHub du service générera automatiquement une pull request pour ajouter les configurations nécessaires, y compris :
- Un fichier
deployment.yamlqui définit les environnements de déploiement du service. - Des manifestes Kubernetes qui définissent les objets
DeploymentetServicepour le déploiement du service. - Un Dockerfile Debian qui exécute un serveur web simple pour démarrer, lequel sera utilisé par les manifestes Kubernetes.
- Configurer des builds de CI comme vérifications GitHub qui créent les images Docker à chaque push et les stockent dans un registre de conteneurs, prêtes à être déployées.
Chaque service intégré au chemin pavé possède son propre namespace Kubernetes, défini par <app-name>-<environment>, un environnement de test (staging) et un environnement de production (production). Cela aide à séparer les charges de travail de multiples services, ainsi que multiples environnements pour le même service, puisque chaque environnement reçoit son propre namespace Kubernetes.
Déploiement d’un service
Sur GitHub, nous déployons des branches et effectuons des déploiements via des commandes ChatOpsHubot. Pour déployer une branche nommée bug-fixes dans le dépôt monalisa-app sur l’environnement staging, un développeur lancerait une commande ChatOps telle que :
hubot deploy monalisa-app/bug-fixes to staging
Cela déclenche un déploiement qui récupère l’image Docker associée au commit le plus récent sur la branche bug-fixes, met à jour les manifestes Kubernetes et applique ces manifestes sur les clusters de la plateforme d’exécution concernée par cet environnement.
Normalement, l’image Docker serait déployée sur plusieurs clusters Kubernetes situés dans divers lieux géographiques au sein d’une région faisant partie de la plateforme d’exécution.
Pour automatiser la fusion des pull requests dans les branches les plus actives et orchestrer le déploiement dans tous les environnements, nous utilisons également des files de fusion et des pipelines de déploiement, que nos ingénieurs peuvent suivre et avec lesquels ils peuvent interagir pendant le déploiement.
Assurer la sécurité de nos services
Pour toute entreprise, la sécurité de la plateforme elle-même, ainsi que des services qui y sont exécutés, est primordiale. En plus de nos pratiques d’ingénierie, comme l’exigence de révisions par deux personnes sur chaque demande de tirage (pull request), nous disposons également d’équipes de Sécurité et de Plateforme qui automatisent des mesures de sécurité, telles que :
- Des images Docker pré-construites à utiliser comme images de base pour les Dockerfiles. Ces images de base contiennent uniquement les paquets/dépendances nécessaires avec des mises à jour de sécurité, un ensemble de logiciels installés qui est traçable et sélectionné en fonction des besoins partagés.
- Des analyses périodiques et en temps réel de tous les paquets et images de conteneurs en exécution, à la recherche de vulnérabilités ou de dépendances nécessitant une correction, réalisées par le biais de nos propres produits de sécurité de la chaîne d’approvisionnement logicielle, tels que Dependabot.
- La compilation et l’analyse périodique des dépôts de services GitHub à la recherche de secrets exposés et de vulnérabilités, en utilisant les ressources de sécurité natives de GitHub pour la sécurité avancée, telles que l’analyse de code et la détection de secrets.
- De multiples mécanismes d’authentification et d’autorisation qui permettent à seulement les individus pertinents d’accéder directement aux ressources Kubernetes sous-jacentes.
- Une télémétrie complète pour la détection des menaces.
- Les services exécutés sur la plateforme sont par défaut accessibles uniquement à l’intérieur des réseaux internes de GitHub et ne sont pas exposés sur Internet public.
- Les politiques de protection des branches s’appliquent à tous les dépôts de production. Ces politiques empêchent la fusion d’une pull request tant que les tests automatisés désignés n’ont pas été approuvés et que la modification a été examinée par un développeur différent de celui qui l’a proposée.
Un autre aspect fondamental de la sécurité d’une application est la gestion des secrets, tels que les clés et les jetons. Chez GitHub, nous utilisons un coffre-fort centralisé des secrets pour les gérer. Chaque service et chaque environnement au sein du service disposent de leur propre coffre-fort pour stocker les secrets. Ces secrets sont ensuite injectés dans les pods pertinents dans Kubernetes, qui, à leur tour, sont exposés aux conteneurs.
Le flux de déploiement, de la fusion à la mise en production.
Tout le processus de déploiement se déroulerait plus ou moins ainsi :
- Un ingénieur GitHub fusionne une pull request dans une branche d’un dépôt. Dans l’exemple ci-dessus, il s’agit de la branche
bug-fixesde la branchemasterdu dépôtmonalisa-app. Ce dépôt contiendrait également les fichiers modèles de manifestes Kubernetes pour le déploiement de l’application. - La fusion du pull request déclenche des flux de travail CI pertinents. L’un d’eux consiste à créer l’image Docker, qui construit l’image du conteneur à partir du Dockerfile spécifié dans le dépôt et envoie l’image vers un registre d’artefacts interne.
- Dès que tous les flux de travail CI se terminent avec succès, l’ingénieur démarre un déploiement en exécutant une commande ChatOps telle que
hubot deploy monalisa-app/bug-fixes to staging. Cela déclenche un déploiement dans nos environnements, commeStaging. - Les systèmes de build obtiennent les fichiers de manifeste Kubernetes à partir de la branche du dépôt, remplacent l’image la plus récente à déployer à partir du registre d’artefacts, injectent les secrets de l’application à partir du coffre-fort et exécutent quelques opérations personnalisées. À l’issue de cette étape, un manifeste Kubernetes prêt à être déployé est disponible.
- Nos systèmes de déploiement appliquent le manifeste Kubernetes sur les clusters concernés et surveillent l’état du déploiement des nouvelles modifications.
Conclusion
Le chemin interne facilité par GitHub aide les développeurs à se concentrer sur la création de services et sur la livraison de valeur à nos utilisateurs, avec un minimum d’attention portée à l’infrastructure. Nous y parvenons en offrant à nos ingénieurs GitHub une voie simplifiée qui exploite la puissance des conteneurs et de Kubernetes; des mécanismes de sécurité, d’authentification et d’autorisation évolutifs; et la plateforme GitHub.com elle-même.
Envie d’essayer certaines de ces astuces ? Pour en savoir plus sur toutes les fonctionnalités de GitHub, rendez-vous sur github.com/features. Si vous avez adopté certaines de nos pratiques pour votre propre développement, dites-le-nous sur le Twitter !




