VPN de runner de CI: o túnel sobrevive ao build?
Um runner de CI compartilhado mantém rotas e processos entre jobs. Planeje os estados da VPN antes, durante e depois do job, e limpe apenas a conexão que o job possui.
Um job de implantação se conecta, copia seu artefato e relata sucesso. O túnel que ele abriu pode continuar ativo quando o próximo job começar, e a rota que ele alterou pertence ao host inteiro. O resultado de um build descreve o comando, não o estado que ele deixou para trás. Trate a VPN como um recurso com tempo de vida, não como uma linha no início de um estágio.
O que mais roda neste host
Um nó do Jenkins pode executar vários executores ao mesmo tempo, e um job que altera rotas do host, configurações do resolvedor ou uma conexão de todo o sistema as altera para todos. Se outro job percebe isso depende da política de rotas e filtragem, não de uma regra geral sobre VPNs. Acesso ao repositório, acesso aos artefatos e o canal de controle são requisitos separados que o runner ainda precisa. Adicione-os à lista de destinos de implantação antes de escolher um túnel completo.
Se o canal de controle fosse atravessar o túnel, o projeto precisa dizer isso de propósito. Descobrir isso durante uma reversão não é um plano. Escreva as duas listas: o que o job precisa alcançar de forma privada e o que o runner precisa alcançar de qualquer maneira.
Este job precisa de acesso privado, afinal?
Pergunte, antes de adicionar o túnel, se o estágio de build precisa dele. Um agente de implantação privado pode buscar um artefato aprovado e realizar a implantação, o que mantém o estágio geral de build fora da rede privada. Essa separação costuma ser mais barata do que ensinar cada etapa do build a rotear por um túnel.
Escolha a fronteira a partir do fluxo de trabalho, não do hábito. Se a resposta for não, o resto desta página é desnecessário, e esse é o melhor resultado disponível.
O estado que o próximo job herda
Descreva o que deve ser verdadeiro antes do job, enquanto ele tem acesso privado e depois que termina, incluindo o cancelamento. O estado final é o que costuma ficar implícito, e é o que o próximo job herda. Escreva-o ao lado do pipeline em vez de deixá-lo na memória de alguém.
| 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 |
Um agente dedicado ou descartável torna essas fronteiras mais fáceis de aplicar. Um contêiner ou namespace só ajuda se o arranjo de rede e privilégios realmente isolar a mudança.
Pare a conexão, não o programa
Use o caminho de finalização do pipeline para fechar a conexão que este job iniciou e remover suas credenciais temporárias. Não combine processos pelo nome do programa em um host que outros jobs usam; pare a conexão específica. Os dois comandos abaixo são toda a limpeza, e nenhum depende de encontrar um processo.
vpn-cli disconnect --profile "$PROFILE"
rm -f "$RUNNER_TEMP/client.key"
A finalização não é isolamento: um runner que morre mantém o túnel que abriu, e um processo interrompido à força pula o bloco por completo. É por isso que o comando de limpeza sozinho não pode ser todo o projeto. Veja como isso falha na prática: um job de implantação é cancelado na etapa de cópia, o bloco de finalização nunca roda, e o próximo job no mesmo host começa com um túnel ativo e uma rota que aponta para uma rede que ele não consegue alcançar. A falha parece um problema de 'DNS' no build seguinte, horas depois de o job que a causou terminar.
Registre o nome do perfil e o caminho da credencial na saída do job. Um comando de desconexão sem identificador é difícil de auditar depois. A linha de log também é o que prova que o bloco rodou quando uma investigação posterior pergunta.
Dê ao job um host que ninguém mais usa
Infraestrutura descartável elimina o problema da herança em vez de gerenciá-lo. Um agente novo por job começa sem rota, sem perfil e sem credenciais de outros, e sua destruição limpa o que o job deixou. Isso custa mais por build, e é o preço honesto de uma fronteira que não depende do código de limpeza. Para jobs que tocam redes de produção, costuma ser a opção mais barata depois de contabilizar os incidentes.
Onde um runner compartilhado precisa ficar, teste falhas e cancelamentos com o mesmo cuidado da cópia bem-sucedida. O teste deve mostrar o que o próximo job veria se este fosse cancelado no meio do caminho. Um job termina quando seu acesso e seu estado temporário acabaram, não quando o comando de cópia retorna zero.