VPN per runner CI: il tunnel sopravvive alla build?
Un runner CI condiviso conserva rotte e processi tra i job. Pianifica gli stati della VPN prima, durante e dopo il job, e pulisci solo la connessione che il job possiede.
Un job di deployment si connette, copia il suo artefatto e segnala il successo. Il tunnel che ha aperto può essere ancora attivo quando inizia il job successivo, e la rotta che ha modificato appartiene all'intero host. Il risultato di una build descrive il comando, non lo stato che ha lasciato dietro di sé. Tratta la VPN come una risorsa con una durata, non come una riga all'inizio di una fase.
Cos'altro gira su questo host
Un nodo Jenkins può eseguire più executor insieme, e un job che cambia le rotte dell'host, le impostazioni del resolver o una connessione a livello di sistema le cambia per tutti. Se un altro job se ne accorga dipende dalla politica di rotte e filtraggio, non da una regola generale sulle VPN. L'accesso al repository, l'accesso agli artefatti e il canale di controllo sono requisiti separati di cui il runner ha ancora bisogno. Aggiungili all'elenco delle destinazioni di deployment prima di scegliere un tunnel completo.
Se il canale di controllo dovesse attraversare il tunnel, il progetto deve dirlo deliberatamente. Scoprirlo durante un rollback non è un piano. Scrivi i due elenchi: cosa deve raggiungere il job in privato e cosa deve raggiungere il runner comunque.
Questo job ha davvero bisogno di accesso privato?
Chiedi, prima di aggiungere il tunnel, se la fase di build ne ha bisogno. Un agente di deployment privato può recuperare un artefatto approvato ed eseguire il deployment, il che tiene la fase di build generale fuori dalla rete privata. Quella separazione di solito costa meno che insegnare a ogni passo di build a instradarsi attraverso un tunnel.
Scegli il confine dal flusso di lavoro, non dall'abitudine. Se la risposta è no, il resto di questa pagina è inutile, ed è il miglior risultato disponibile.
Lo stato che eredita il job successivo
Descrivi ciò che dovrebbe essere vero prima del job, mentre ha accesso privato e dopo che è finito, compresa l'annullamento. Lo stato finale è quello che più spesso resta implicito, ed è quello che eredita il job successivo. Scrivilo accanto alla pipeline invece di lasciarlo nella memoria di qualcuno.
| Moment | What proves it | What leaks if it is skipped |
|---|---|---|
| Job start: pre-flight route check | The route table shows no tunnel from an earlier job, and the profile list is empty | A stale route sends deployment traffic into a dead tunnel |
| Job end: disconnect and shred | The profile is down and the temporary key file is gone | The next job inherits an open tunnel and a usable credential |
| Cancelled job: reboot or disposal | The host is replaced or rebooted before the next job starts | A killed process leaves the tunnel up with no owner |
Un agente dedicato o usa e getta rende quei confini più facili da far rispettare. Un container o un namespace aiuta solo se la sua disposizione di rete e privilegi isola davvero il cambiamento.
Ferma la connessione, non il programma
Usa il percorso di finalizzazione della pipeline per chiudere la connessione che questo job ha aperto e rimuovere le sue credenziali temporanee. Non far corrispondere i processi per nome del programma su un host che altri job usano; ferma invece la connessione specifica. I due comandi qui sotto sono tutta la pulizia, e nessuno dipende dal trovare un processo.
vpn-cli disconnect --profile "$PROFILE"
rm -f "$RUNNER_TEMP/client.key"
La finalizzazione non è isolamento: un runner che muore conserva il tunnel che ha aperto, e un processo interrotto con la forza salta del tutto il blocco. Per questo il comando di pulizia da solo non può essere l'intero progetto. Ecco come fallisce in pratica: un job di deployment viene annullato allo step di copia, il blocco di finalizzazione non viene mai eseguito e il job successivo sullo stesso host parte con un tunnel attivo e una rotta che punta a una rete che non riesce a raggiungere. Il guasto sembra un problema di 'DNS' nella build successiva, ore dopo la fine del job che l'ha causato.
Registra il nome del profilo e il percorso della credenziale nell'output del job. Un comando di disconnessione nudo e senza identificatore è difficile da verificare in seguito. La riga di log è anche ciò che dimostra che il blocco è stato eseguito quando un'indagine successiva lo chiede.
Dai al job un host che nessun altro usa
L'infrastruttura usa e getta elimina il problema dell'ereditarietà invece di gestirlo. Un agente nuovo per ogni job parte senza rotta, senza profilo e senza credenziali di altri, e la sua distruzione pulisce ciò che il job ha lasciato. Costa di più per build, ed è il prezzo onesto di un confine che non dipende dal codice di pulizia. Per i job che toccano reti di produzione, di solito è l'opzione più economica una volta contati gli incidenti.
Dove un runner condiviso deve restare, prova il fallimento e l'annullamento con la stessa cura della copia riuscita. Il test dovrebbe mostrare cosa vedrebbe il job successivo se questo fosse annullato a metà. Un job è finito quando il suo accesso e il suo stato temporaneo sono terminati, non quando il comando di copia restituisce zero.