Introduction à l’infrastructure d’agent auto-scalable
Dans le monde de l’intégration continue et de la livraison continue (CI/CD), les agents de build (ou travailleurs, exécuteurs) sont les incontournables qui compilent le code, exécutent des tests et déploient des applications. À mesure que les équipes de développement grandissent et que la complexité des projets augmente, la demande pour ces agents peut fluctuer de manière significative. La provision de manière manuelle d’agents et leur déprovisionnement est non seulement chronophage mais entraîne également des inefficacités : soit les agents restent inactifs, ce qui coûte de l’argent, soit les builds s’accumulent, ralentissant le développement. C’est ici que l’infrastructure d’agents auto-scalables devient indispensable.
L’auto-scaling permet à votre flotte d’agents d’ajuster dynamiquement sa capacité en fonction de la demande. Lorsqu’il y a une augmentation des demandes de build, de nouveaux agents sont automatiquement créés. Lorsque la demande diminue, les agents inactifs sont arrêtés, optimisant l’utilisation des ressources et les coûts. Cet article fournit un guide pratique pour implémenter l’auto-scaling dans votre infrastructure d’agents CI/CD, en se concentrant sur des modèles communs et en fournissant des exemples concrets.
Pourquoi l’auto-scaling ? Les avantages principaux
- Optimisation des coûts : Payez uniquement pour les ressources que vous utilisez. Les agents inactifs dans le cloud sont un drain direct sur votre budget.
- Amélioration du débit : Éliminez les files d’attente de builds. Plus d’agents signifient plus de builds simultanés, ce qui entraîne des cycles de rétroaction plus rapides pour les développeurs.
- Fiabilité accrue : Répartissez les charges de travail sur plusieurs agents, réduisant le risque de point de défaillance unique.
- Réduction des frais d’exploitation : Automatisez le processus de mise à l’échelle, libérant ainsi votre équipe des tâches de provisionnement manuel.
- Élasticité : gérez aisément des pics et des creux imprévisibles de demande sans intervention manuelle.
Architectures d’auto-scaling courantes
Bien que les spécificités varient selon le système CI/CD et le fournisseur de cloud, la plupart des infrastructures d’agents auto-scalables suivent quelques modèles de base :
-
Groupes d’auto-scaling des fournisseurs de cloud (ASG)
De nombreux systèmes CI/CD s’intègrent directement aux groupes d’auto-scaling spécifiques aux fournisseurs de cloud (par exemple, AWS Auto Scaling Groups, Azure Virtual Machine Scale Sets, Google Cloud Managed Instance Groups). Vous définissez une image de base (AMI, VHD, image de VM) pour votre agent, spécifiez des politiques de mise à l’échelle (basées sur l’utilisation du CPU, la longueur de la file d’attente, des métriques personnalisées), et le fournisseur de cloud gère la gestion du cycle de vie.
Avantages :
- Fortement intégré à l’infrastructure cloud.
- Utilise des services cloud éprouvés.
- Souvent le plus simple à configurer pour une mise à l’échelle de base.
Inconvénients :
- Peut être moins granulaire pour le contrôle de types ou conditions d’agents spécifiques.
- Lié à un seul fournisseur de cloud.
-
Intégrations spécifiques aux systèmes CI/CD
De nombreuses plateformes CI/CD modernes (par exemple, Jenkins, GitLab CI, Buildkite, CircleCI, GitHub Actions) offrent leurs propres mécanismes d’auto-scaling ou des intégrations directes avec divers fournisseurs de cloud/orchestateurs de conteneurs. Cela implique souvent un “contrôleur” ou un “plugin” qui surveille la file d’attente de build et demande de nouveaux agents au besoin.
Avantages :
- Optimisé pour les besoins spécifiques de la plateforme CI/CD.
- Fournit souvent une logique plus sophistiquée pour le provisionnement d’agents (par exemple, étiquettes spécifiques, exigences en matière de ressources).
- Peut prendre en charge des types d’agents hétérogènes.
Inconvénients :
- Peut nécessiter plus de configuration dans le système CI/CD lui-même.
- Parfois, moins performant que l’auto-scaling natif du cloud pour des changements très rapides.
-
Orchestration de conteneurs (Kubernetes)
Utiliser Kubernetes comme infrastructure sous-jacente pour vos agents devient de plus en plus populaire. Les agents fonctionnent comme des pods éphémères, et le Cluster Autoscaler de Kubernetes (ou des outils similaires) peut mettre à l’échelle le groupe de nœuds sous-jacent en fonction des demandes des pods en attente. Cela offre une flexibilité immense et une efficacité des ressources.
Avantages :
- Densité élevée et utilisation des ressources (plusieurs agents par nœud).
- Portabilité entre différents fournisseurs de cloud ou sur site.
- Excellente option pour des charges de travail éphémères basées sur des tâches.
Inconvénients :
- Complexité initiale plus élevée pour la mise en place de Kubernetes lui-même.
- Nécessite de containeriser votre environnement de build.
Guide rapide : Exemples pratiques
Explorons des exemples pratiques pour mettre en place l’auto-scaling avec deux outils CI/CD populaires et une approche centrée sur Kubernetes.
Exemple 1 : Jenkins avec AWS EC2 Spot Instances
Jenkins, un serveur d’automatisation open-source largement utilisé, a un excellent support pour l’auto-scaling basé sur le cloud, en particulier avec AWS EC2. L’utilisation de Spot Instances peut réduire considérablement les coûts.
Prérequis :
- Une instance Jenkins en cours d’exécution (de préférence sur EC2 ou une VM dédiée).
- Un compte AWS avec les autorisations IAM appropriées (EC2, VPC, S3 si vous utilisez S3 pour les artefacts).
- Le plugin Jenkins EC2 installé.
Étapes :
-
Préparez une AMI EC2 pour votre agent Jenkins :
Lancez une instance EC2 (par exemple,
t3.medium, Ubuntu LTS). Installez le Kit de développement Java (JDK), tous les outils de build nécessaires (Maven, Gradle, npm, Docker CLI) et configurez l’agent Jenkins. Assurez-vous que l’agent se connecte correctement à votre contrôleur Jenkins en premier lieu. Une fois configuré, créez une AMI à partir de cette instance. Cette AMI sera le modèle pour vos agents auto-scalables.# Exemple de configuration sur Ubuntu pour un agent Java de base sudo apt update sudo apt install -y openjdk-11-jdk maven docker.io sudo usermod -aG docker jenkins # En supposant que jenkins est l'utilisateur pour l'agent sudo systemctl enable docker sudo systemctl start docker # Configuration manuelle de l'agent Jenkins (pour tester l'AMI) # Téléchargez agent.jar depuis votre contrôleur Jenkins # java -jar agent.jar -jnlpUrl <votre-url-jenkins>/computer/<nom-agent>/slave-agent.jnlp -secret <secret> -workDir <chemin> # Une fois vérifié, créez l'AMI à partir de cette instance EC2. -
Configurez le plugin Jenkins EC2 :
Allez dans le tableau de bord Jenkins -> Gérer Jenkins -> Gérer les nœuds et clouds -> Configurer les clouds.
Ajoutez un nouveau Cloud -> Amazon EC2.
- Nom :
AWS-Spot-Agents - Informations d’identification Amazon EC2 : Ajoutez votre clé d’accès AWS et votre clé secrète (ou utilisez le rôle IAM pour le contrôleur Jenkins).
- Régions EC2 : Sélectionnez votre région (par exemple,
us-east-1). - Limite d’instance : Fixez une limite raisonnable (par exemple,
10) pour éviter des coûts excessifs. - Clé SSH : Sélectionnez une clé SSH existante pour l’accès aux agents.
- Ajoutez une nouvelle AMI :
- ID de l’AMI : Entrez l’ID de l’AMI que vous avez créée.
- Description :
Agent de build Java Ubuntu - Étiquettes :
java-agent linux(utilisé par les jobs Jenkins pour sélectionner les agents). - Type d’instance :
t3.medium(ou approprié). - Zone de disponibilité : Sélectionnez votre AZ préférée ou laissez vide pour aléatoire.
- Instance Spot : Cochez cette case.
- Prix max Spot : Fixez une enchère maximale (par exemple,
0.10). - RMFS distant :
/home/jenkins - Utilisateur distant :
ubuntu(ou l’utilisateur de votre AMI). - Utilisation :
Only build jobs with label expressions matching this node. - Délai de terminaison d’inactivité : Fixez une durée (par exemple,
10minutes) après laquelle un agent inactif sera arrêté.
- Nom :
-
Testez l’auto-scaling :
Créez un job Jenkins et configurez-le pour s’exécuter sur un agent avec l’étiquette
java-agent. Déclenchez plusieurs builds simultanément. Vous devriez observer de nouvelles instances EC2 Spot apparaissant dans votre console AWS et se connectant à Jenkins. Une fois les builds terminés et les agents devenus inactifs pendant le temps configuré, ils seront terminés.
Exemple 2 : GitLab CI avec GitLab Runner sur Docker Machine
GitLab CI s’intègre parfaitement avec GitLab Runner, qui peut être configuré pour l’auto-scaling via Docker Machine sur divers fournisseurs de cloud.
Prérequis :
- Une instance GitLab en cours d’exécution (SaaS ou auto-hébergée).
- Un serveur (par exemple, EC2, VM) pour héberger le gestionnaire de GitLab Runner.
- Docker et Docker Machine installés sur le serveur de gestion de GitLab Runner.
- Identifiants de fournisseur de cloud (par exemple, clé d’accès AWS et clé secrète configurées sur le gestionnaire de Runner).
Étapes :
-
Installez et enregistrez GitLab Runner :
Sur votre serveur dédié au gestionnaire Runner, installez GitLab Runner :
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash sudo apt install gitlab-runner # Enregistrez le runner (obtenez votre token d'enregistrement depuis les paramètres du projet/groupe GitLab) sudo gitlab-runner register --url "https://gitlab.com/" --registration-token "<votre-token-d'enregistrement>" --description "Docker Machine Auto-scaling Runner" --tag-list "docker,aws" --executor "docker+machine" -
Configurez
config.tomlpour Docker Machine :Modifiez le fichier de configuration du Runner, généralement situé à
/etc/gitlab-runner/config.toml.Ajoutez/modifiez la section
[[runners]]et ajoutez une section[runners.docker]et[runners.machine].[[runners]] name = "Docker Machine Auto-scaling Runner" url = "https://gitlab.com/" token = "<your-registration-token>" executor = "docker+machine" [runners.docker] tls_verify = false image = "ubuntu:latest" # Image par défaut pour les constructions privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 [runners.machine] IdleCount = 1 # Maintenir au moins une machine inactive IdleTime = 600 # Terminer les machines inactives après 10 minutes MaxBuilds = 100 # Terminer la machine après 100 constructions MachineDriver = "amazonec2" MachineName = "gitlab-runner-%s" MachineOptions = [ "amazonec2-instance-type=t3.medium", "amazonec2-ami=ami-0abcdef1234567890", # Utiliser une AMI de base avec Docker pré-installé "amazonec2-region=us-east-1", "amazonec2-vpc-id=vpc-0123456789abcdef0", "amazonec2-subnet-id=subnet-0abcdef1234567890", "amazonec2-security-group=gitlab-runner-sg", "amazonec2-use-private-address=true", "amazonec2-tags=gitlab-runner-managed,project:my-project" ] # Optionnel : Configurer Docker Machine pour les instances Spot # MachineOptions = [ # ..., # "amazonec2-request-spot-instance=true", # "amazonec2-spot-price=0.05", # ]Remarque sur l’AMI : Pour Docker Machine, votre AMI doit avoir Docker pré-installé et configuré pour démarrer au démarrage. Docker Machine utilisera ensuite cette AMI pour provisionner de nouvelles instances.
-
Redémarrer GitLab Runner :
sudo gitlab-runner restart -
Tester l’Auto-Scaling :
Poussez quelques modifications vers un dépôt GitLab qui déclenche un pipeline CI. Déclenchez plusieurs pipelines simultanément. Vous devriez voir de nouvelles instances EC2 ou des VM sur le cloud choisi se lancer et exécuter vos tâches. Après une période d’inactivité, elles seront terminées.
Exemple 3 : Kubernetes avec Cluster Autoscaler
Pour des charges de travail hautement dynamiques et conteneurisées, Kubernetes offre une solution d’auto-scaling puissante. Ici, vos agents CI/CD s’exécutent en tant que pods, et le Cluster Autoscaler de Kubernetes ajuste le pool de nœuds sous-jacent.
Prérequis :
- Un cluster Kubernetes en cours d’exécution (par exemple, EKS, AKS, GKE ou auto-géré).
kubectlconfiguré pour accéder à votre cluster.- Un système CI/CD capable de déployer des tâches sous forme de pods Kubernetes (par exemple, plugin Jenkins Kubernetes, exécuteur GitLab CI Kubernetes, Tekton, Argo Workflows).
Étapes (Conceptuel pour l’Exécuteur Kubernetes CI GitLab) :
-
Déployer le Cluster Autoscaler :
Suivez la documentation pour déployer le Cluster Autoscaler spécifique à votre fournisseur de cloud (par exemple, EKS Cluster Autoscaler, GKE Cluster Autoscaler). Ce composant surveille les pods en attente et ajuste les groupes de nœuds à la hausse ou à la baisse.
Exemple (EKS – simplifié, consultez la documentation officielle) :
# Créer une politique IAM pour le Cluster Autoscaler # Créer un rôle IAM et joindre la politique # Créer un compte de service et l'associer au rôle IAM # Déployer le déploiement du Cluster Autoscaler en utilisant Helm ou YAML # Exemple de commande Helm pour le Cluster Autoscaler EKS helm upgrade --install cluster-autoscaler stable/cluster-autoscaler \ --namespace kube-system \ --set autoDiscovery.clusterName=<your-cluster-name> \ --set rbac.create=true \ --set serviceAccount.create=true \ --set serviceAccount.name=cluster-autoscaler \ --set image.repository=k8s.gcr.io/cluster-autoscaler \ --set image.tag=v1.22.0 # Correspondre à votre version K8s -
Configurer des Groupes de Nœuds/Pools de Nœuds Dynamiques :
Assurez-vous que votre cluster Kubernetes a des groupes/pools de nœuds configurés pour l’auto-scaling. Définissez des tailles minimales et maximales pour ces groupes.
Exemple (GKE) :
gcloud container node-pools create ci-agents-pool \ --cluster <your-cluster-name> \ --machine-type=e2-medium \ --num-nodes=0 \ --min-nodes=0 \ --max-nodes=10 \ --enable-autoscaling \ --region=<your-region> -
Configurer le Système CI/CD pour utiliser l’Exécuteur Kubernetes :
Pour GitLab CI, enregistrez un Runner avec l’exécuteur Kubernetes. Cet exécuteur lancera un nouveau pod pour chaque tâche.
sudo gitlab-runner register --url "https://gitlab.com/" --registration-token "<your-registration-token>" --description "Kubernetes CI Runner" --tag-list "kubernetes,docker" --executor "kubernetes"Éditez
/etc/gitlab-runner/config.toml:[[runners]] name = "Kubernetes CI Runner" url = "https://gitlab.com/" token = "<your-registration-token>" executor = "kubernetes" [runners.kubernetes] host = "" # Laissez vide pour la configuration en cluster namespace = "gitlab-runner" cpu_limit = "500m" memory_limit = "1Gi" image = "docker:20.10.16-dind-rootless" # Ou votre image de base préférée pull_policy = ["if-not-present", "always"] # Optionnel : Configurer une image de base pour vos constructions # helper_image = "gitlab/gitlab-runner-helper:latest" -
Tester l’Auto-Scaling :
Déclenchez plusieurs pipelines CI/CD. Observez de nouveaux pods en cours de création dans l’espace de noms
gitlab-runner. S’il n’y a pas assez de nœuds, le Cluster Autoscaler provisionnera de nouveaux nœuds dans votreci-agents-pool. Une fois les tâches terminées, les pods seront arrêtés et les nœuds inactifs seront réduits.
Meilleures Pratiques pour les Agents d’Auto-Scaling
- Utilisez des Images d’Agent Immutables : Construisez vos images d’agent (AMIs, images Docker) avec tous les outils nécessaires pré-installés. Cela garantit la cohérence et accélère les temps de lancement des agents.
- Utilisez des Instances Spot/Préemptibles : Pour des constructions non critiques ou tolérantes aux pannes, utiliser des instances spot peut réduire considérablement les coûts. Implémentez une logique de réessai dans votre CI/CD si les tâches risquent d’être interrompues.
- Configurez une Réduction Aggressive : Pour optimiser les coûts, configurez les agents pour qu’ils se terminent rapidement après être devenus inactifs.
- Définissez des Limites pour les Instances : Définissez toujours des limites maximales pour vos groupes d’auto-scaling ou vos pools de nœuds afin d’éviter des dépassements de coûts inattendus.
- Surveillez Votre Infrastructure : Gardez un œil sur les files d’attente de construction, l’utilisation des agents et les coûts du cloud. Ajustez les politiques de mise à l’échelle si nécessaire.
- Optimisez le Temps de Démarrage des Agents : Minimisez le temps nécessaire pour qu’un agent soit prêt. Cela inclut l’optimisation de la taille de l’image, l’utilisation efficace des scripts cloud-init et la mise en cache des dépendances.
- Utilisez des Étiquettes/Tags pour la Granularité : Utilisez des étiquettes (Jenkins, Kubernetes) ou des tags (GitLab) pour diriger des tâches spécifiques vers des agents avec les bonnes capacités (par exemple,
java-17,node-lts,gpu-enabled). - Considérez les Pools Tempérés : Pour les scénarios où l’évolutivité rapide est essentielle, maintenez un petit "piscine tempérée" d’agents inactifs prêts à prendre des tâches instantanément, tout en permettant une mise à l’échelle supplémentaire à la demande.
Conclusion
Une infrastructure d’agent en auto-scaling n’est plus un luxe mais une nécessité pour les pipelines CI/CD modernes. En ajustant dynamiquement votre capacité d’agent, vous pouvez réaliser des économies significatives, améliorer la productivité des développeurs grâce à des retours plus rapides et construire un système de livraison plus résilient et élastique. Que vous choisissiez des groupes d’auto-scaling de fournisseur de cloud, des intégrations spécifiques à CI/CD ou une approche centrée sur Kubernetes, les principes restent les mêmes : automatiser, optimiser et mettre à l’échelle pour répondre à la demande. Commencez avec une configuration simple, surveillez ses performances, et affinez progressivement votre stratégie d’auto-scaling pour correspondre parfaitement aux besoins de votre équipe.
🕒 Published: