# Cuatro formas de instalar

Las cuatro rutas por las que la imagen del agente llega al router — un checkout con Go, el tar publicado, un registro del que tira el router, o un script de RouterOS que pegas — qué necesita cada una, qué escribe cada una, y cómo verificar una descarga de la release.

Source: https://jmrplens.github.io/mikroscope/es/install/routes/

El agente es una imagen de contenedor, y las cuatro rutas de abajo se
diferencian en una sola cosa: cómo llega esa imagen al router. Todo lo demás
que escribe `install` —la veth, la dirección, las dos pertenencias a listas, la
envlist, el contenedor y su etiqueta— es igual tomes la ruta que tomes, y
también lo son los requisitos previos:
[Lo que necesita el router](/mikroscope/es/install/prerequisites/) va primero en
las cuatro, porque `device-mode container=yes` exige una mano en el equipo y
ninguna ruta lo esquiva.

## Cuál elegir

| Ruta                                                   | Necesita                                                            | Prefiérela cuando                                                     |
| ------------------------------------------------------ | ------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **[Un pull del registro](#un-pull-del-registro)** — empieza por aquí | que el router llegue a Docker Hub; nada más            | casi siempre: una orden, nada que elegir, nada que subir               |
| [Un script de RouterOS](#un-script-de-routeros)        | una terminal en el router; `--remote-image`                         | llegas al router por WinBox o WebFig y no por ssh                      |
| [Un checkout, con Go](#un-checkout-con-go)             | Go 1.27 y el repositorio; ssh al router                             | trabajas en mikroscope y quieres el agente de tu propio árbol          |
| [El tar publicado](#el-tar-publicado)                  | los artefactos de la release, el correcto para la placa; ssh al router | el router no llega a ningún registro                                 |

**Toma la primera salvo que algo te lo impida.** Un pull del registro es una
sola orden sin nada que elegir: el índice de imágenes publicado lleva todas las
plataformas que puede ser un contenedor de MikroTik, así que el router
reconoce la suya y nadie tiene que saber si la placa es ARM de 64 bits o una de
las dos clases de 32 bits. Nada aterriza en la flash, y `uninstall` no tiene
ningún fichero del que dar cuenta.

El tar va el último a propósito. Es la ruta correcta para un router sin salida
a un registro, y es la única en la que **tú** eliges la arquitectura —y la
forma en que eso sale mal es una imagen que se instala, arranca y muere con
`exec format error` en el registro del contenedor—. Si la tomas, lee
[qué tar](#qué-tar) antes de descargar nada.

## Un pull del registro

La ruta recomendada, y la más corta. Una orden, nada que descargar, nada que
subir:

```sh
mikroscope install --router usuario@192.168.88.1 \
  --remote-image jmrplens/mikroscope-agent:1.0.4
```

No se sube nada, ningún tar aterriza en el equipo, y `uninstall` no tiene
ningún fichero del que dar cuenta: el paso del contenedor pasa a ser
`/container/add remote-image="jmrplens/mikroscope-agent:1.0.4" …` y el plan
imprime `the router pulls … (nothing is uploaded)` donde iría la línea de
subida. La release publica la imagen dos veces, como
`jmrplens/mikroscope-agent:1.0.4` en Docker Hub y como
`ghcr.io/jmrplens/mikroscope-agent:1.0.4` en GHCR. Las dos llevan `linux/amd64`,
`linux/arm64`, `linux/arm/v7` y `linux/arm/v5`, y RouterOS toma la que necesita
su arquitectura —que es la razón de que esta ruta no pregunte nada sobre la
placa: las dos clases de ARM de 32 bits que vende MikroTik están en el índice.

La referencia de arriba es la de Docker Hub, y no lleva host de registro: el
router se la descarga del que ya nombre `/container/config registry-url`, y
RouterOS trae ese ajuste puesto en `https://registry-1.docker.io`. En un router
donde nadie lo haya tocado, la orden de arriba no necesita fijar nada antes —en
la RB5009 sobre la que se mide este proyecto, ese ajuste vale
`https://registry-1.docker.io`—. La referencia de GHCR es la alternativa, y
necesita antes `/container/config/set registry-url=https://ghcr.io` en el
equipo, que es un cambio para todos sus contenedores.

Necesita dos cosas que las otras rutas no: que el router llegue al registro, y
que tenga sitio en RAM para las capas mientras las extrae.

> **El host del registro es un ajuste global del router**
>
> RouterOS toma el host del registro de `/container/config registry-url`, que es global al equipo y
> compartido con cualquier otro contenedor que tenga, y solo el resto de la referencia va a
> `remote-image=`. mikroscope nunca escribe ese ajuste: apuntar el registro de tu router a otro
> sitio para instalar una sonda sería cambiar los contenedores de otra persona. `doctor` lo lee en
> su lugar y, cuando la referencia nombra un host que no cuadra con el ajuste, nombra la única
> orden que hay que ejecutar: `/container/config/set registry-url=https://ghcr.io` para la
> referencia de GHCR. Instala con `--agent-tar` si prefieres no tocarlo.

Una referencia sin host —`jmrplens/mikroscope-agent:1.0.4`— deja el registro a
lo que el router ya tenga configurado, y entonces `doctor` no comprueba nada al
respecto. `--remote-image` toma su valor por defecto de
`MIKROSCOPE_REMOTE_IMAGE`, y `upgrade` también lo acepta; `image` lo rechaza,
porque no hay ningún tar que escribir.

## Un script de RouterOS

Para un router al que llegas por WinBox o WebFig, o donde no quieres ssh desde
otra máquina en absoluto:

```sh
mikroscope plan --rsc \
  --remote-image jmrplens/mikroscope-agent:1.0.4 \
  --out install.rsc
```

El fichero lleva las mismas órdenes que ejecuta `install`, en el mismo orden y
con cada objeto etiquetado igual, así que `status` y `uninstall` desde la CLI
los reconocen después. Léelo, y luego pégalo en la terminal del router, o súbelo
y hazle `/import`. Sin `--out` sale por la salida estándar. Lleva su propia
cabecera: la etiqueta que escribe, qué comprobar antes de ejecutarlo y, al
final, `/container/print where name~"mikroscope"` y la URL `/healthz` en la que
responde el agente.

Dos advertencias, ambas escritas en el propio script:

- **No puede subir nada.** Un script que se ejecuta en el router no tiene forma
  de poner la imagen ahí, así que acompáñalo de `--remote-image`. Sin él, la
  cabecera dice en su lugar qué nombre de fichero hay que dejar antes en el
  equipo —el nombre que espera el paso del contenedor— y cómo regenerar el
  script para un pull del registro.
- **Con `--token`, el fichero es una credencial.** La línea de la envlist lleva
  el token en claro, porque el router lo necesita en claro. La CLI escribe el
  fichero con permisos `0600`; lo que hagas con él después es la exposición.

Nada dentro del script comprueba nada. No hay `doctor`, ni pregunta sobre con
qué chocarían los objetos que crea, ni confirmación: escribe. Ejecuta
`mikroscope doctor` desde una máquina que pueda, o lee
[Lo que necesita el router](/mikroscope/es/install/prerequisites/) y comprueba
a mano los tres requisitos, antes de pegarlo.

Las cuatro rutas se ejecutaron de extremo a extremo contra el RB5009UG+S+ de
referencia (RouterOS 7.24.2, arm64) el 2026-09-17, una tras otra, cada una
instalando bajo su propio nombre, veth y `/30` para no tocar nada de lo que ya
había en el equipo, y cada una retirada antes de la siguiente. En todas ellas
el agente respondió a `/healthz` desde el equipo del colector: la compilación
desde el checkout y el `mikroscope-agent-arm64.tar` publicado con 2 ms de ida y
vuelta, la descarga que el propio router hizo de
`jmrplens/mikroscope-agent:1.0.4` desde Docker Hub con 2 ms, y el script de
`plan --rsc` — subido e importado con `/import`, sin CLI ninguna en la
instalación misma — con 15 ms en sus primeras muestras. `uninstall` verificó
después por recuento de propiedad en cada caso, y el `/export` del router tras
las cuatro era idéntico byte a byte al tomado antes de ellas.

> **Sin probar**
>
> `--remote-image` contra **GHCR**. `/container/config registry-url` es un único ajuste global de
> RouterOS que mikroscope lee y nunca escribe, y el router de referencia apunta a Docker Hub;
> apuntarlo a ghcr.io para probar ese camino cambiaría el registro para todos los demás
> contenedores del equipo. La imagen se publica en los dos registros y la CI la arranca desde GHCR
> en las tres arquitecturas, pero ningún router se la ha bajado de allí. Tampoco se ha ejecutado
> ninguna ruta en hardware arm ni x86_64.

## Un checkout, con Go

```sh
git clone https://github.com/jmrplens/mikroscope
cd mikroscope
make build
bin/mikroscope install --router usuario@192.168.88.1
```

`plan`, `install`, `upgrade` e `image` compilan el agente ellos mismos:
`go build ./cmd/mikroscope-agent` para `linux/<arch>` (`--arch`, por defecto
`arm64`) con `CGO_ENABLED=0`, empaquetado en un tar de imagen sin Docker. La
ruta de compilación es relativa, así que ejecuta la CLI desde el checkout. Es la
única ruta que instala un agente compilado de tu propio árbol, y por eso es la
que se usa mientras se cambia el agente.

`make build` deja la CLI en `bin/mikroscope`. Sin una toolchain de Go en
`PATH`, el verbo se detiene antes de escribir nada y nombra las otras dos rutas
y la versión de Go que quería.

## El tar publicado

La ruta para un router que no llega a ningún registro. Dos artefactos: el
archivo de la CLI para la máquina desde la que la ejecutas —que es
[Tener la CLI](/mikroscope/es/install/cli/), y no tiene nada que ver con el
router— y un tar de imagen del agente, para la arquitectura **del router**. Sin
toolchain de Go y sin checkout.

### Qué tar

| Tu MikroTik                                     | `architecture-name` | Tar de imagen del agente        |
| ------------------------------------------------ | ------------------- | ------------------------------- |
| RB5009, CCR2004, hAP ax³, otros ARM de 64 bits   | `arm64`             | `mikroscope-agent-arm64.tar`    |
| hEX Refresh / hEX S (2025), cualquier EN7562CT   | `arm`               | `mikroscope-agent-armv5.tar`    |
| Otros ARM de 32 bits (hAP ac², hAP ax², …)       | `arm`               | `mikroscope-agent-armv7.tar`, o el v5 |
| CHR, RouterOS x86                                | `x86_64`            | `mikroscope-agent-amd64.tar`    |

`mikroscope doctor --router …` imprime la arquitectura leída del equipo, así
que ejecútalo primero y deja que te lo diga. **Si no sabes qué placa ARM de
32 bits tienes, toma el tar v5**: la documentación de contenedores de MikroTik
dice que las placas EN7562CT «solo admiten imágenes de contenedor arm32v5», y
una imagen ARMv5 funciona en todos los ARM de 32 bits que vende MikroTik,
mientras que una ARMv7 no arranca en aquellas.

1. Descarga `mikroscope_1.0.4_<so>_<arch>.tar.gz` (`.zip` en Windows) y el tar
   de la imagen del agente de la tabla de arriba, junto con `checksums.txt` y
   `checksums.txt.sigstore.json`.

2. Verifícalos, más abajo, antes de desempaquetar nada.

3. Desempaqueta la CLI e instala:

   ```sh
   tar xzf mikroscope_1.0.4_linux_x86_64.tar.gz
   ./mikroscope install --router usuario@192.168.88.1 \
     --arch arm64 --agent-tar mikroscope-agent-arm64.tar
   ```

La CLI lee el tar antes de subirlo, que es lo que caza la descarga equivocada:
imprime lo que leyó, como
`using mikroscope-agent-arm64.tar: linux/arm64, agent <tamaño> KiB`, y con la
imagen ARMv7 añade la nota de que una placa EN7562CT necesita la v5. Quiere un `manifest.json` de una sola
imagen, la configuración que ese manifiesto nombra, una capa y
`/mikroscope-agent` como entrypoint; cualquier otra cosa falla con
`this is not a mikroscope agent image`. Después, la arquitectura de la imagen
tiene que ser la que dice `--arch`, o el verbo falla nombrando el artefacto que
hay que descargar en su lugar: una imagen `amd64` en una placa arm64 se
instalaría, arrancaría y moriría con `exec format error` en el log del
contenedor. De un tar que acepta imprime lo que ha leído, así:
`using mikroscope-agent-arm64.tar: linux/arm64, agent <tamaño> KiB`.

`--agent-tar` toma su valor por defecto de `MIKROSCOPE_AGENT_TAR`, y `upgrade`
e `image` también lo aceptan. De ahí en adelante la instalación es la ruta de
subida: el tar sube con `scp`, RouterOS lo extrae al añadir el contenedor, e
`install` lo borra.

> **Dos artefactos con nombres parecidos**
>
> `mikroscope-agent-arm64.tar` es la imagen de contenedor para cargar de lado, la que quiere
> `--agent-tar`. `mikroscope-agent_1.0.4_linux_arm64.tar.gz` es un archivo con el binario del agente
> a secas, para leerlo o ejecutarlo fuera de un contenedor; `--agent-tar` lo rechaza.

### Verificar la descarga

`checksums.txt` cubre todos los archivos y todos los tar de imagen del agente, y
es el único fichero por el que responde la firma. La firma es sin claves: la
identidad es la ejecución del workflow que la produjo, registrada en un registro
público de transparencia, así que no hay ninguna clave que buscar.

```sh
cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/jmrplens/mikroscope/.github/workflows/release.yml@refs/tags/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --bundle checksums.txt.sigstore.json \
  checksums.txt
sha256sum --ignore-missing -c checksums.txt
```

`--ignore-missing` es lo que permite comprobar los dos ficheros que has
descargado contra una lista que cubre toda la release. Cada archivo lleva además
un SBOM en SPDX (`<archivo>.spdx.json`) con su propio paquete de firma, que se
verifica igual.

## Véase también

- [Lo que necesita el router](/mikroscope/es/install/prerequisites/): los tres requisitos que
  comparten todas las rutas, y lo que comprueba `doctor`.
- [Instalar el agente](/mikroscope/es/install/): lo que hace `install` una vez decidida la imagen.
- [Dónde va cada cosa](/mikroscope/es/install/layout/): el disco que usan el tar y la raíz del
  contenedor, y lo que `--remote-image` deja de poner en él.
- [Llegar al agente](/mikroscope/es/install/reaching-the-agent/): la sonda que se ejecuta después.
