Introduzione all’infrastruttura di agenti auto-scalabili
Nel mondo dell’integrazione continua e della consegna continua (CI/CD), gli agenti di build (o lavoratori, esecutori) sono i protagonisti che compilano il codice, eseguono test e distribuiscono applicazioni. Man mano che i team di sviluppo crescono e la complessità dei progetti aumenta, la domanda per questi agenti può fluttuare in modo significativo. La fornitura manuale di agenti e il loro de-provisioning è non solo dispendiosa in termini di tempo ma comporta anche inefficienze: o gli agenti rimangono inattivi, il che costa soldi, o i build si accumulano, rallentando lo sviluppo. È qui che l’infrastruttura di agenti auto-scalabili diventa indispensabile.
L’auto-scaling consente alla tua flotta di agenti di regolare dinamicamente la propria capacità in base alla domanda. Quando c’è un aumento delle richieste di build, nuovi agenti vengono creati automaticamente. Quando la domanda diminuisce, gli agenti inattivi vengono arrestati, ottimizzando l’utilizzo delle risorse e i costi. Questo articolo fornisce una guida pratica per implementare l’auto-scaling nella tua infrastruttura di agenti CI/CD, concentrandosi su modelli comuni e fornendo esempi concreti.
Perché l’auto-scaling? I principali vantaggi
- Ottimizzazione dei costi: Paghi solo per le risorse che utilizzi. Gli agenti inattivi nel cloud sono un onere diretto sul tuo budget.
- Controllo del throughput: Elimina le code di build. Più agenti significano più build simultanee, portando a cicli di feedback più rapidi per gli sviluppatori.
- Aumento dell’affidabilità: Distribuisci i carichi di lavoro su più agenti, riducendo il rischio di un punto di guasto unico.
- Riduzione dei costi operativi: Automatizza il processo di scalabilità, liberando così il tuo team da compiti di provisioning manuale.
- Elasticità: gestisci facilmente picchi e cali imprevedibili di domanda senza intervento manuale.
Architetture comuni di auto-scaling
Sebbene le specifiche varino a seconda del sistema CI/CD e del fornitore di cloud, la maggior parte delle infrastrutture di agenti auto-scalabili seguono alcuni modelli di base:
-
Gruppi di auto-scaling dei fornitori di cloud (ASG)
Molti sistemi CI/CD si integrano direttamente con i gruppi di auto-scaling specifici dei fornitori di cloud (ad esempio, AWS Auto Scaling Groups, Azure Virtual Machine Scale Sets, Google Cloud Managed Instance Groups). Definisci un’immagine di base (AMI, VHD, immagine di VM) per il tuo agente, specifica politiche di scaling (basate sull’utilizzo della CPU, la lunghezza della coda, metriche personalizzate) e il fornitore di cloud gestisce la gestione del ciclo di vita.
Vantaggi:
- Fortemente integrato con l’infrastruttura cloud.
- Utilizza servizi cloud collaudati.
- Spesso il più semplice da configurare per una scalabilità di base.
Svantaggi:
- Potrebbe essere meno granulare per il controllo di tipi o condizioni di agenti specifici.
- Legato a un solo fornitore di cloud.
-
Integrazioni specifiche per sistemi CI/CD
Molte piattaforme CI/CD moderne (ad esempio, Jenkins, GitLab CI, Buildkite, CircleCI, GitHub Actions) offrono i propri meccanismi di auto-scaling o integrazioni dirette con vari fornitori di cloud/orchestratori di contenitori. Questo implica spesso un “controllore” o un “plugin” che monitora la coda di build e richiede nuovi agenti secondo necessità.
Vantaggi:
- Ottimizzato per le esigenze specifiche della piattaforma CI/CD.
- Fornisce spesso una logica più sofisticata per il provisioning di agenti (ad esempio, etichette specifiche, requisiti di risorse).
- Può supportare tipi di agenti eterogenei.
Svantaggi:
- Potrebbe richiedere più configurazioni nel sistema CI/CD stesso.
- A volte, meno performante rispetto all’auto-scaling nativo del cloud per cambiamenti molto rapidi.
-
Orchestrazione dei contenitori (Kubernetes)
Utilizzare Kubernetes come infrastruttura sottostante per i tuoi agenti sta diventando sempre più popolare. Gli agenti operano come pod efimeri e il Cluster Autoscaler di Kubernetes (o strumenti simili) può scalare il gruppo di nodi sottostante in base alle richieste dei pod in attesa. Questo offre un’immensa flessibilità e un’efficienza delle risorse.
Vantaggi:
- Alta densità e utilizzo delle risorse (più agenti per nodo).
- Portabilità tra diversi fornitori di cloud o on-premise.
- Ottima opzione per carichi di lavoro efimeri basati su attività.
Svantaggi:
- Maggiore complessità iniziale per l’impostazione di Kubernetes stesso.
- Richiede di containerizzare il tuo ambiente di build.
Guida rapida: Esempi pratici
Esploriamo esempi pratici per implementare l’auto-scaling con due strumenti CI/CD popolari e un approccio incentrato su Kubernetes.
Esempio 1: Jenkins con AWS EC2 Spot Instances
Jenkins, un server di automazione open-source ampiamente utilizzato, ha un ottimo supporto per l’auto-scaling basato sul cloud, in particolare con AWS EC2. L’utilizzo di Spot Instances può ridurre significativamente i costi.
Prerequisiti:
- Un’istanza di Jenkins in esecuzione (preferibilmente su EC2 o una VM dedicata).
- Un account AWS con le autorizzazioni IAM appropriate (EC2, VPC, S3 se utilizzi S3 per artefatti).
- Il plugin Jenkins EC2 installato.
Fasi:
-
Prepara un’AMI EC2 per il tuo agente Jenkins:
Avvia un’istanza EC2 (ad esempio,
t3.medium, Ubuntu LTS). Installa il Kit di sviluppo Java (JDK), tutti gli strumenti di build necessari (Maven, Gradle, npm, Docker CLI) e configura l’agente Jenkins. Assicurati che l’agente si connetta correttamente al tuo controller Jenkins per prima cosa. Una volta configurato, crea un’AMI da quest’istanza. Questa AMI sarà il modello per i tuoi agenti auto-scalabili.# Esempio di configurazione su Ubuntu per un agente Java di base sudo apt update sudo apt install -y openjdk-11-jdk maven docker.io sudo usermod -aG docker jenkins # Supponendo che jenkins sia l'utente per l'agent sudo systemctl enable docker sudo systemctl start docker # Configurazione manuale dell'agent Jenkins (per testare l'AMI) # Scarica agent.jar dal tuo controller Jenkins # java -jar agent.jar -jnlpUrl <il-tuo-url-jenkins>/computer/<nome-agent>/slave-agent.jnlp -secret <secret> -workDir <percorso> # Una volta verificato, crea l'AMI da quest'istanza EC2. -
Configura il plugin Jenkins EC2:
Vai nel cruscotto Jenkins -> Gestisci Jenkins -> Gestisci nodi e cloud -> Configura i cloud.
Aggiungi un nuovo Cloud -> Amazon EC2.
- Nome:
AWS-Spot-Agents - Informazioni di identificazione Amazon EC2: Aggiungi la tua chiave di accesso AWS e la tua chiave segreta (o usa il ruolo IAM per il controller Jenkins).
- Region EC2: Seleziona la tua regione (ad esempio,
us-east-1). - Limite d’istanza: Fissa un limite ragionevole (ad esempio,
10) per evitare costi eccessivi. - Chiave SSH: Seleziona una chiave SSH esistente per l’accesso agli agenti.
- Aggiungi una nuova AMI:
- ID dell’AMI: Inserisci l’ID dell’AMI che hai creato.
- Descrizione:
Agente di build Java Ubuntu - Etichette:
java-agent linux(utilizzato dai job Jenkins per selezionare gli agenti). - Tipo d’istanza:
t3.medium(o appropriato). - Zona di disponibilità: Seleziona la tua AZ preferita o lascia vuoto per casuale.
- Instance Spot: Spunta questa casella.
- Prezzo max Spot: Fissa un’offerta massima (ad esempio,
0.10). - RMFS remoto:
/home/jenkins - Utente remoto:
ubuntu(o l’utente della tua AMI). - Utilizzo:
Solo job di build con espressioni di etichette corrispondenti a questo nodo. - Timeout di inattività: Fissa una durata (ad esempio,
10minuti) dopo la quale un agente inattivo verrà arrestato.
- Nome:
-
Testa l’auto-scaling:
Crea un job Jenkins e configurarlo per essere eseguito su un agente con l’etichetta
java-agent. Avvia più compilation simultaneamente. Dovresti vedere nuove istanze EC2 Spot apparire nella tua console AWS e connettersi a Jenkins. Una volta che le compilazioni sono completate e gli agenti diventano inattivi per il tempo configurato, verranno terminati.
Esempio 2: GitLab CI con GitLab Runner su Docker Machine
GitLab CI si integra perfettamente con GitLab Runner, che può essere configurato per l’auto-scaling tramite Docker Machine su vari fornitori di cloud.
Prerequisiti:
- Un’istanza GitLab in esecuzione (SaaS o auto-ospitata).
- Un server (ad esempio, EC2, VM) per ospitare il gestore di GitLab Runner.
- Docker e Docker Machine installati sul server di gestione di GitLab Runner.
- Credenziali del fornitore di cloud (ad esempio, chiave di accesso AWS e chiave segreta configurate sul gestore di Runner).
Passaggi:
-
Installa e registra GitLab Runner:
Sul tuo server dedicato al gestore Runner, installa GitLab Runner:
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash sudo apt install gitlab-runner # Registra il runner (ottieni il tuo token di registrazione dalle impostazioni del progetto/gruppo GitLab) sudo gitlab-runner register --url "https://gitlab.com/" --registration-token "<il-tuo-token-di-registrazione>" --description "Docker Machine Auto-scaling Runner" --tag-list "docker,aws" --executor "docker+machine" -
Configura
config.tomlper Docker Machine:Modifica il file di configurazione del Runner, solitamente situato in
/etc/gitlab-runner/config.toml.Aggiungi/modifica la sezione
[[runners]]e aggiungi una sezione[runners.docker]e[runners.machine].[[runners]] name = "Docker Machine Auto-scaling Runner" url = "https://gitlab.com/" token = "<il-tuo-token-di-registrazione>" executor = "docker+machine" [runners.docker] tls_verify = false image = "ubuntu:latest" # Immagine predefinita per le build privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache"] shm_size = 0 [runners.machine] IdleCount = 1 # Mantieni almeno una macchina inattiva IdleTime = 600 # Termina le macchine inattive dopo 10 minuti MaxBuilds = 100 # Termina la macchina dopo 100 build MachineDriver = "amazonec2" MachineName = "gitlab-runner-%s" MachineOptions = [ "amazonec2-instance-type=t3.medium", "amazonec2-ami=ami-0abcdef1234567890", # Usa un'AMI di base con Docker pre-installato "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" ] # Facoltativo: Configura Docker Machine per le istanze Spot # MachineOptions = [ # ..., # "amazonec2-request-spot-instance=true", # "amazonec2-spot-price=0.05", # ]Nota sull’AMI: Per Docker Machine, la tua AMI deve avere Docker pre-installato e configurato per avviarsi all’avvio. Docker Machine utilizzerà quindi questa AMI per fornire nuove istanze.
-
Riavvia GitLab Runner:
sudo gitlab-runner restart -
Testa l’Auto-Scaling:
Inoltra alcune modifiche a un repository GitLab che attiva una pipeline CI. Avvia più pipeline simultaneamente. Dovresti vedere nuove istanze EC2 o VM sul cloud scelto avviarsi e eseguire i tuoi compiti. Dopo un periodo di inattività, verranno terminate.
Esempio 3: Kubernetes con Cluster Autoscaler
Per carichi di lavoro altamente dinamici e containerizzati, Kubernetes offre una potente soluzione di auto-scaling. Qui, i tuoi agenti CI/CD vengono eseguiti come pod, e il Cluster Autoscaler di Kubernetes regola il pool di nodi sottostante.
Prerequisiti:
- Un cluster Kubernetes in esecuzione (ad esempio, EKS, AKS, GKE o auto-gestito).
kubectlconfigurato per accedere al tuo cluster.- Un sistema CI/CD capace di distribuire compiti sotto forma di pod Kubernetes (ad esempio, plugin Jenkins Kubernetes, esecutore GitLab CI Kubernetes, Tekton, Argo Workflows).
Passaggi (Concettuale per l’Esecutore Kubernetes CI GitLab):
-
Distribuisci il Cluster Autoscaler:
Segui la documentazione per distribuire il Cluster Autoscaler specifico per il tuo fornitore di cloud (ad esempio, EKS Cluster Autoscaler, GKE Cluster Autoscaler). Questo componente monitora i pod in attesa e regola i gruppi di nodi verso l’alto o verso il basso.
Esempio (EKS – semplificato, consulta la documentazione ufficiale):
# Crea una policy IAM per il Cluster Autoscaler # Crea un ruolo IAM e aggiungi la policy # Crea un account di servizio e collegalo al ruolo IAM # Distribuisci il deployment del Cluster Autoscaler utilizzando Helm o YAML # Esempio di comando Helm per il Cluster Autoscaler EKS helm upgrade --install cluster-autoscaler stable/cluster-autoscaler \ --namespace kube-system \ --set autoDiscovery.clusterName=<il-tuo-nome-del-cluster> \ --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 # Corrisponde alla tua versione K8s -
Configura Gruppi di Nodi/Pools di Nodi Dinamici:
Assicurati che il tuo cluster Kubernetes abbia gruppi/pools di nodi configurati per l’auto-scaling. Definisci dimensioni minime e massime per questi gruppi.
Esempio (GKE):
gcloud container node-pools create ci-agents-pool \ --cluster <il-tuo-nome-del-cluster> \ --machine-type=e2-medium \ --num-nodes=0 \ --min-nodes=0 \ --max-nodes=10 \ --enable-autoscaling \ --region=<la-tua-regione> -
Configura il Sistema CI/CD per usare l’Esecutore Kubernetes:
Per GitLab CI, registra un Runner con l’esecutore Kubernetes. Questo esecutore lancerà un nuovo pod per ogni compito.
sudo gitlab-runner register --url "https://gitlab.com/" --registration-token "<il-tuo-token-di-registrazione>" --description "Kubernetes CI Runner" --tag-list "kubernetes,docker" --executor "kubernetes"Modifica
/etc/gitlab-runner/config.toml:[[runners]] name = "Kubernetes CI Runner" url = "https://gitlab.com/" token = "<il-tuo-token-di-registrazione>" executor = "kubernetes" [runners.kubernetes] host = "" # Lascialo vuoto per la configurazione in cluster namespace = "gitlab-runner" cpu_limit = "500m" memory_limit = "1Gi" image = "docker:20.10.16-dind-rootless" # O la tua immagine di base preferita pull_policy = ["if-not-present", "always"] # Facoltativo: Configura un'immagine di base per le tue build # helper_image = "gitlab/gitlab-runner-helper:latest" -
Testa l’Auto-Scaling:
Avvia più pipeline CI/CD. Osserva nuovi pod in fase di creazione nello spazio dei nomi
gitlab-runner. Se non ci sono abbastanza nodi, il Cluster Autoscaler fornirà nuovi nodi nel tuoci-agents-pool. Una volta completati i compiti, i pod verranno fermati e i nodi inattivi verranno ridotti.
Buone Pratiche per gli Agenti di Auto-Scaling
- Usa Immagini di Agente Immutabili: Costruisci le tue immagini di agente (AMIs, immagini Docker) con tutti gli strumenti necessari pre-installati. Questo garantisce coerenza e accelera i tempi di avvio degli agenti.
- Utilizza Istanza Spot/Preemptible: Per costruzioni non critiche o tolleranti ai guasti, utilizzare istanze spot può ridurre notevolmente i costi. Implementa una logica di ripetizione nel tuo CI/CD se le attività rischiano di essere interrotte.
- Configura una Riduzione Aggressiva: Per ottimizzare i costi, configura gli agenti in modo che si terminino rapidamente dopo essere diventati inattivi.
- Definisci Limiti per le Istanze: Definisci sempre limiti massimi per i tuoi gruppi di auto-scaling o per i tuoi pool di nodi per evitare sforamenti di costo imprevisti.
- Monitora la Tua Infrastruttura: Tieni d’occhio le code di costruzione, l’utilizzo degli agenti e i costi del cloud. Regola le politiche di scaling se necessario.
- Ottimizza il Tempo di Avvio degli Agenti: Minimizza il tempo necessario affinché un agente sia pronto. Questo include l’ottimizzazione delle dimensioni dell’immagine, l’uso efficace degli script cloud-init e la memorizzazione nella cache delle dipendenze.
- Usa Etichette/Tag per la Granularità: Usa etichette (Jenkins, Kubernetes) o tag (GitLab) per indirizzare compiti specifici verso agenti con le giuste capacità (ad esempio,
java-17,node-lts,gpu-enabled). - Considera i Pool Temporizzati: Per scenari in cui la scalabilità rapida è essenziale, mantieni un piccolo “piscina temporizzata” di agenti inattivi pronti a prendere compiti istantaneamente, consentendo inoltre una scalabilità aggiuntiva su richiesta.
Conclusione
Un’infrastruttura di agenti in auto-scaling non è più un lusso ma una necessità per i pipeline CI/CD moderni. Regolando dinamicamente la tua capacità di agente, puoi ottenere risparmi significativi, migliorare la produttività degli sviluppatori grazie a risposte più rapide e costruire un sistema di consegna più resiliente ed elastico. Che tu scelga gruppi di auto-scaling di fornitori di cloud, integrazioni specifiche per CI/CD o un approccio incentrato su Kubernetes, i principi rimangono gli stessi: automatizzare, ottimizzare e scalare per rispondere alla domanda. Inizia con una configurazione semplice, monitora le sue prestazioni e affina gradualmente la tua strategia di auto-scaling per adattarla perfettamente alle esigenze del tuo team.
🕒 Published: