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 porta anche a inefficienze: o gli agenti rimangono inattivi, il che significa costi, o gli build si accumulano, rallentando lo sviluppo. Qui entra in gioco l’infrastruttura di agenti auto-scalabili.
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’uso 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: Paga solo per le risorse che utilizzi. Gli agenti inattivi nel cloud sono un onere diretto sul tuo budget.
- Miglioramento 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 single point of failure.
- Riduzione delle spese di gestione: Automatizza il processo di scaling, liberando il tuo team da compiti manuali di provisioning.
- Elasticità: Gestisci facilmente picchi e flessioni imprevedibili della domanda senza intervento manuale.
Architetture comuni di auto-scaling
Sebbene le specifiche variano a seconda del sistema CI/CD e del fornitore di cloud, la maggior parte delle infrastrutture di agenti auto-scalabili segue 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, 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 uno scaling di base.
Svantaggi:
- Può essere meno granulare per il controllo di tipi specifici di agenti o condizioni.
- 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 “controller” o un “plugin” che monitora la coda di build e richiede nuovi agenti all’occorrenza.
Vantaggi:
- Ottimizzato per le esigenze specifiche della piattaforma CI/CD.
- Fornisce spesso una logica più sofisticata per il provisioning degli agenti (ad esempio, etichette specifiche, requisiti di risorse).
- Può supportare tipi di agenti eterogenei.
Svantaggi:
- Può richiedere più configurazione nel sistema CI/CD stesso.
- A volte, meno performante dell’auto-scaling nativo del cloud per cambiamenti molto rapidi.
-
Orchestrazione di contenitori (Kubernetes)
Utilizzare Kubernetes come infrastruttura sottostante per i tuoi agenti diventa sempre più popolare. Gli agenti funzionano come pod effimeri, 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’enorme flessibilità e un’efficienza delle risorse.
Vantaggi:
- Alta densità e utilizzo delle risorse (più agenti per nodo).
- Portabilità tra diversi fornitori di cloud o in locale.
- Ottima opzione per carichi di lavoro effimeri basati su compiti.
Svantaggi:
- Maggiore complessità iniziale per la configurazione di Kubernetes stesso.
- Richiede di containerizzare il tuo ambiente di build.
Guida rapida: Esempi pratici
Esploriamo esempi pratici per impostare 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’uso di Spot Instances può ridurre significativamente i costi.
Requisiti:
- Un’istanza 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 gli artefatti).
- Il plugin Jenkins EC2 installato.
Passaggi:
-
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 in primo luogo. Una volta configurato, crea un’AMI da questa 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'agente sudo systemctl enable docker sudo systemctl start docker # Configurazione manuale dell'agente Jenkins (per testare l'AMI) # Scarica agent.jar dal tuo controller Jenkins # java -jar agent.jar -jnlpUrl <la-tua-url-jenkins>/computer/<nome-agente>/slave-agent.jnlp -secret <secret> -workDir <percorso> # Una volta verificato, crea l'AMI da questa istanza EC2. -
Configura il plugin Jenkins EC2:
Vai nel dashboard di 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 utilizza il ruolo IAM per il controller Jenkins).
- Regioni EC2: Seleziona la tua regione (ad esempio,
us-east-1). - Limite di istanza: Imposta 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 lavori Jenkins per selezionare gli agenti). - Tipo di istanza:
t3.medium(o appropriato). - Zona di disponibilità: Seleziona la tua AZ preferita o lascia vuoto per casuale.
- Istanza Spot: Seleziona questa opzione.
- Prezzo massimo Spot: Imposta un’asta massima (ad esempio,
0.10). - RMFS remoto:
/home/jenkins - Utente remoto:
ubuntu(o l’utente della tua AMI). - Utilizzo:
Only build jobs with label expressions matching this node. - Timeout di terminazione di inattività: Imposta 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. Attiva più build simultaneamente. Dovresti osservare nuove istanze EC2 Spot apparire nella tua console AWS e collegarsi a Jenkins. Una volta completate le build 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 il auto-scaling tramite Docker Machine su vari fornitori di cloud.
Requisiti:
- 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 provider cloud (ad esempio, chiave di accesso AWS e chiave segreta configurate sul gestore del Runner).
Passi:
-
Installa e registra GitLab Runner:
Sul tuo server dedicato al gestore del 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 = "<your-registration-token>" 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" ] # Opzionale: 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à poi questa AMI per provisionare nuove istanze.
-
Riavvia GitLab Runner:
sudo gitlab-runner restart -
Testa l’Auto-Scaling:
Invia 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 ed 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.
Requisiti:
- Un cluster Kubernetes in esecuzione (ad esempio, EKS, AKS, GKE o auto-gestito).
kubectlconfigurato per accedere al tuo cluster.- Un sistema CI/CD in grado di distribuire compiti sotto forma di pod Kubernetes (ad esempio, plugin Jenkins Kubernetes, esecutore GitLab CI Kubernetes, Tekton, Argo Workflows).
Passi (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 unisci la policy # Crea un account di servizio e associalo 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-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-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 utilizzare 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 = "" # Lascia vuoto per la configurazione nel 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"] # Opzionale: Configura un'immagine di base per le tue build # helper_image = "gitlab/gitlab-runner-helper:latest" -
Testa l’Auto-Scaling:
Attiva più pipeline CI/CD. Osserva nuovi pod in corso di creazione nello spazio dei nomi
gitlab-runner. Se non ci sono abbastanza nodi, il Cluster Autoscaler provisionerà nuovi nodi nel tuoci-agents-pool. Una volta completati i compiti, i pod verranno arrestati e i nodi inattivi saranno ridotti.
Migliori Pratiche per gli Agenti di Auto-Scaling
- Utilizza Immagini di Agente Immobili: Crea 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 istanze Spot/Preemptible: Per costruzioni non critiche o tolleranti ai guasti, utilizzare istanze spot può ridurre notevolmente i costi. Implementa una logica di retry nel tuo CI/CD se le attività possono 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: Imposta sempre limiti massimi per i tuoi gruppi di auto-scaling o i tuoi pool di nodi per evitare sforamenti di costo imprevisti.
- Monitora la Tua Infrastruttura: Tieni d’occhio le code di costruzione, l’uso 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 efficiente degli script cloud-init e la memorizzazione nella cache delle dipendenze.
- Utilizza Etichette/Tag per la Granularità: Utilizza etichette (Jenkins, Kubernetes) o tag (GitLab) per dirigere compiti specifici verso agenti con le capacità appropriate (ad esempio,
java-17,node-lts,gpu-enabled). - Prendi in Considerazione i Pool Temporeggiati: Per scenari in cui la scalabilità rapida è essenziale, mantieni una piccola “piscina temperata” di agenti inattivi pronti a prendere compiti istantaneamente, consentendo al contempo un’ulteriore scalabilità su richiesta.
Conclusione
Un’infrastruttura di agenti in auto-scaling non è più un lusso, ma una necessità per i moderni pipeline CI/CD. Regolando dinamicamente la tua capacità di agenti, puoi ottenere risparmi significativi, migliorare la produttività degli sviluppatori grazie a feedback più rapidi e costruire un sistema di delivery più resiliente ed elastico. Che tu scelga gruppi di auto-scaling di fornitori di cloud, integrazioni specifiche per CI/CD o un approccio centrato su Kubernetes, i principi rimangono gli stessi: automatizzare, ottimizzare e scalare per rispondere alla domanda. Inizia con una configurazione semplice, monitora le sue performance e affina progressivamente la tua strategia di auto-scaling per adattarsi perfettamente alle necessità del tuo team.
🕒 Published: