PlataformaMáquinas de runner

Máquinas de runner

Jobs de Windows, macOS y self-hosted, en máquinas que registras.

Hay jobs que no pueden correr en el clúster. Un contenedor Windows necesita el kernel NT y no existe en un host Linux, y macOS no se contenedoriza — así que para windows-latest y macos-latest no hay pod en ninguna parte. Registras la máquina y la plataforma llega a ella por SSH.

app.equantic.space/config/maquinas-runner
windows-latestmacos-latest
win-runner-1windows/amd64runner@10.0.0.42Aceptando jobs
mac-mini-1macos/arm64runner@10.0.0.51Aceptando jobs
build-boxlinux/amd64runner@10.0.0.7Drenando
mac-studiomacos/arm64runner@10.0.0.52inalcanzable
1Las labels que pide el job
2Abre la sesión y pregunta
3La clave pública a instalar
Cada máquina muestra lo que la plataforma realmente sabe de ella: las labels a las que responde y si alguna vez fue alcanzada.

Cuándo necesitas una

runs-onDónde corre
ubuntu-latest, una imagen de contenedorEn el clúster. Nada que registrar.
windows-latestEn una máquina Windows registrada.
macos-latestEn un Mac registrado. La licencia de Apple exige hardware Apple.
self-hostedEn una máquina registrada de cualquier SO — eso es lo que significa la label.

Un job cuyas labels no coinciden con ninguna máquina falla en el acto en vez de correr en el sitio equivocado, y su anotación dice qué falta: ninguna máquina para ese SO, una máquina en drenaje o una label que ninguna tiene. El run falla en lugar de dar por bueno un trabajo que nunca se construyó.

Registrar una máquina

Ve a Ajustes → Plataforma → Máquinas de runner y pulsa Registrar máquina. Declaras qué es la máquina: dirección, la cuenta con la que correrá el CI, el sistema, la arquitectura y cuántos jobs admite a la vez.

En ningún momento se te pide una clave privada. La plataforma genera un par ed25519, cifra la mitad privada en reposo con el mismo cifrado que usan los secrets, y te enseña solo la pública.

Es deliberado. Pegar una clave privada en un formulario significa mover la cadena más peligrosa que tienes por una página, una petición y probablemente el portapapeles — y la clave que la mayoría coge es la suya de login, que concede muchísimo más que correr CI.

Instalar la clave

La pantalla te da el comando del sistema de esa máquina, porque el destino es realmente distinto.

En Linux y macOS, el sitio de siempre:

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

En Windows, no es ese sitio. Para cualquier cuenta del grupo Administrators, OpenSSH lee un archivo de toda la máquina e ignora por completo ~/.ssh/authorized_keys:

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"
En Windows, instalarla en la carpeta del usuario funciona, no cambia nada, y la siguiente conexión se rechaza con Permission denied (publickey) — un fallo con pinta de clave mala. Asegúrate además de que el archivo termine en salto de línea: una clave añadida a una última línea sin terminar pega las dos en una entrada inválida, y a partir de ahí no autentica nada.

Probar la conexión

Probar abre una sesión y le pregunta a la máquina qué es. Una sola ida y vuelta responde a tres cosas: SSH funciona, ahí hay un shell POSIX, y cuál es de verdad esta máquina.

Una máquina registrada con el sistema equivocado falla la prueba y lo dice. No es un problema de conexión, y es peor: el enrutado mandaría jobs windows-latest a una caja Linux, y cada uno fallaría en un comando que no está, sin nada que apunte de vuelta al registro.

Cuando la prueba falla recibes el motivo literal — ssh: connect to host 10.0.0.42 port 22: Operation timed out — en vez de un error genérico. Una máquina nunca alcanzada lo dice, que es distinto de inalcanzable.

Qué necesita la máquina

  • Un servidor SSH y una cuenta sin privilegios con la que corra el CI.
  • Un shell POSIX. En Windows eso es Git for Windows, con su bash.exe puesto como DefaultShell de OpenSSH — todos los steps pasan por ahí.
  • git y tar, que Git for Windows ya trae.

Nada más. El runtime de Node que necesitan las actions de JavaScript lo coloca la plataforma — compilado para el sistema y la arquitectura de esa máquina — la primera vez que corre un job ahí.

Drenar y quitar

Drenar termina los jobs en curso y no admite nuevos: es el estado que usas antes de reiniciar o actualizar la máquina. Quitar hace que la plataforma la olvide.

Quitarla no toca la máquina. Su authorized_keys sigue con la clave pública de la plataforma hasta que la saques.

El aislamiento es más débil que un contenedor

Conviene decirlo sin rodeos. Un job en una máquina registrada ve lo que dejó el job anterior fuera de su workspace: el directorio home, /tmp, los paquetes instalados, el estado de cualquier daemon. Un contenedor da una raíz nueva cada vez, y esto no.

Lo que sí está mitigado: la cuenta no tiene privilegios, el workspace es por job, y la limpieza rechaza cualquier ruta fuera de la raíz de trabajo. Usa una máquina registrada para el trabajo que correrías tranquilo en una build box compartida.