PlataformaMáquinas de runner

Máquinas de runner

Jobs Windows, macOS e self-hosted, em máquinas que você registra.

Alguns jobs não rodam no cluster. Um container Windows precisa do kernel NT e não existe num host Linux, e o macOS não containeriza — então, para windows-latest e macos-latest, não há pod em lugar nenhum. Você registra a máquina, e a plataforma chega nela por SSH.

app.equantic.space/config?section=maquinas-runner
windows-latestmacos-latest
win-runner-1windows/amd64runner@10.0.0.42Aceitando jobs
mac-mini-1macos/arm64runner@10.0.0.51Aceitando jobs
build-boxlinux/amd64runner@10.0.0.7Drenando
mac-studiomacos/arm64runner@10.0.0.52inalcançável
1As labels que o job pede
2Abre a sessão e pergunta
3A chave pública a instalar
Cada máquina mostra o que a plataforma realmente sabe sobre ela: as labels que atende e se algum dia foi alcançada.

Quando você precisa de uma

runs-onOnde roda
ubuntu-latest, uma imagem de containerNo cluster. Nada a registrar.
windows-latestNuma máquina Windows registrada.
macos-latestNum Mac registrado. A licença da Apple exige hardware Apple.
self-hostedNuma máquina registrada de qualquer SO — é isso que a label significa.

Um job cujas labels não batem com nenhuma máquina falha na hora em vez de rodar no lugar errado, e a anotação dele diz o que falta: nenhuma máquina para aquele OS, uma máquina em drenagem ou uma label que nenhuma tem. O run falha em vez de reportar sucesso para algo que nunca foi construído.

Registrando uma máquina

Vá em Configurações → Plataforma → Máquinas de runner e clique em Registrar máquina. Você declara o que a máquina é: endereço, a conta com que o CI vai rodar, o sistema, a arquitetura e quantos jobs ela aceita ao mesmo tempo.

Em nenhum momento você é convidado a colar uma chave privada. A plataforma gera um par ed25519, cifra a metade privada em repouso com a mesma cifra dos secrets, e mostra apenas a pública.

Isso é de propósito. Colar uma chave privada num formulário é mover a string mais perigosa que você tem por uma página, uma requisição e provavelmente a área de transferência — e a chave que a maioria das pessoas pega é a própria chave de login, que dá muito mais do que rodar CI.

Instalando a chave

A tela entrega o comando do sistema daquela máquina, porque o destino é realmente diferente.

No Linux e no macOS, o lugar de sempre:

bash
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'ssh-ed25519 AAAA… eqs-mac-mini-1' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

No Windows, não é esse lugar. Para qualquer conta do grupo Administrators, o OpenSSH lê um arquivo da máquina inteira e ignora o ~/.ssh/authorized_keys por completo:

powershell
Add-Content -Path "$env:ProgramData\ssh\administrators_authorized_keys" -Value 'ssh-ed25519 AAAA… eqs-win-runner-1'
icacls "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
No Windows, instalar no diretório do usuário funciona, não muda nada, e a conexão seguinte é recusada com Permission denied (publickey) — uma falha que parece chave errada. Garanta também que o arquivo termine com quebra de linha: uma chave anexada a uma última linha sem terminador cola as duas numa entrada inválida, e aí nada mais autentica.

Testando a conexão

O Testar abre uma sessão e pergunta à máquina o que ela é. Uma ida e volta responde três coisas: o SSH funciona, existe um shell POSIX ali, e qual máquina é essa de verdade.

Uma máquina registrada com o sistema errado falha no teste e diz isso. Não é um problema de conexão, e é pior que um: o roteamento mandaria jobs windows-latest para uma caixa Linux, e cada um falharia num comando que não existe, sem nada apontando de volta para o registro.

Quando o teste falha você recebe o motivo literal — ssh: connect to host 10.0.0.42 port 22: Operation timed out — em vez de um erro genérico. Uma máquina que nunca foi alcançada diz isso, o que é diferente de inalcançável.

O que a máquina precisa ter

  • Um servidor SSH e uma conta sem privilégios para o CI rodar.
  • Um shell POSIX. No Windows isso é o Git for Windows, com o bash.exe dele configurado como DefaultShell do OpenSSH — todo step passa por ele.
  • git e tar, que o Git for Windows já traz.

Nada além disso. O runtime de Node que as actions JavaScript usam é colocado pela plataforma — construído para o sistema e a arquitetura daquela máquina — no primeiro job que rodar ali.

Drenar e remover

Drenar termina os jobs em curso e não aceita novos: é o estado para usar antes de reiniciar ou atualizar a máquina. Remover faz a plataforma esquecê-la.

Remover não toca na máquina. O authorized_keys dela continua com a chave pública da plataforma até você tirar.

O isolamento é mais fraco que um container

Vale dizer sem rodeios. Um job numa máquina registrada vê o que o job anterior deixou fora do workspace dele: o diretório home, o /tmp, os pacotes instalados, o estado de qualquer daemon. Um container dá uma raiz nova a cada vez, e isso aqui não dá.

O que está mitigado: a conta não tem privilégios, o workspace é por job, e a limpeza recusa qualquer caminho fora da raiz de trabalho. Use uma máquina registrada para o trabalho que você rodaria tranquilo numa build box compartilhada.