Blog
Nossas últimas novidadesGitLab CI: tags de runner e roteamento de jobs (sem dor)
Tags de runner são uma das formas mais simples (e mais subutilizadas) de acelerar pipelines no GitLab.
Elas resolvem um problema bem específico: garantir que um job rode no runner certo, no momento certo, com o ambiente certo.
Este post faz parte da série:
Mapa da série CI/CD
- Guia de CI/CD no Git para times pequenos: performance, cache e runners
- GitLab CI: tags de runner e roteamento de jobs
- Cache no CI/CD: como desenhar keys e evitar cache inválido (GitHub e GitLab)
- Docker layer caching no CI: BuildKit, buildx, cache-from e cache-to
- Runner dedicado no CI/CD: quando vale a pena e como planejar em time pequeno
- Runners macOS no CI: Intel vs Apple Silicon, custos e armadilhas
O problema: job preso, rodando no runner errado, ou fila infinita
Sintomas comuns:
- Job fica em “pending” por muito tempo.
- Job roda em um runner lento (e às vezes, em um runner rápido).
- Build funciona em um runner e quebra em outro (arquitetura, dependências nativas, Docker).
A causa quase sempre é uma destas:
- Não existe tag no job (ou existe tag demais, mal desenhada).
- Runner “genérico” aceita tudo.
- Existe mistura de arquiteturas (ARM64/x64) e o roteamento não leva isso em conta.
Como tags funcionam no GitLab CI (na prática)
No GitLab, um runner pode ter zero ou mais tags. Um job pode declarar tags no .gitlab-ci.yml.
Regra fundamental:
- Se o job declara tags, ele só pode rodar em um runner que tenha todas as tags do job.
- Se o runner estiver configurado para aceitar somente jobs com tag, jobs sem tags podem ficar sem runner.
1) Desenhe tags como “classes de execução”, não como apelidos
Evite tags que são só nomes (“runner-1”, “imac-do-fulano”).
Prefira tags que descrevem capacidade/ambiente:
linux-x64linux-arm64macoswindowsdockerbuild-heavygpu(se aplicável)
Dica: o melhor conjunto de tags é o menor que ainda separa seus gargalos.
2) Crie um “runner padrão” para jobs leves
Uma armadilha comum em times pequenos é ter um único runner aceitando tudo.
O resultado:
- O job pesado (build Docker) trava a fila.
- O job leve (lint) espera atrás do job pesado.
Uma estratégia simples:
- Runner A (padrão): jobs leves (lint/test rápido).
- Runner B (pesado): builds e jobs longos.
- Runner C (macOS): apenas jobs Apple.
3) Use tags para separar arquitetura (ARM64 vs x64)
Se você tem Apple Silicon, Graviton, ou ARM64 em qualquer parte do pipeline, trate isso como uma dimensão explícita.
- Cache de dependências pode não ser compatível.
- Binários pré-compilados mudam.
- Docker images precisam existir para aquela arquitetura (ou entram em emulação).
Exemplo de jobs separados:
build_amd64:
tags: [linux-x64, docker]
script:
- ./ci/build.sh
build_arm64:
tags: [linux-arm64, docker]
script:
- ./ci/build.shLeitura complementar:
4) Checklist rápido de “job stuck” (antes de culpar o GitLab)
- O job tem tags? Quais?
- Existe runner online com essas tags?
- Esse runner aceita jobs com tag (e está habilitado para esse projeto/grupo)?
- O runner está ocupado com jobs longos (fila)?
- Existe conflito de arquitetura?
Checklist final
- Tags descrevem ambiente/capacidade (não pessoas).
- Existe separação entre jobs leves e jobs pesados.
- Arquitetura (ARM/x64) é explícita em tags e em cache keys.
- Runner “genérico” não está aceitando tudo indiscriminadamente.
- Documentação rápida: “quais tags existem e quando usar”.