Ir al contenido

Requisitos

Tres cosas del router tienen que estar listas antes de que install pueda escribir nada, y la herramienta no puede hacerlas por ti. mikroscope doctor comprueba cada requisito en modo de solo lectura, en una conexión ssh, e imprime la orden o el paso físico que arregla cada uno que falte.

Requisito Valor doctor imprime
RouterOS 7.24 o posterior RouterOS 7.24 or later
Arquitectura arm64, arm o x86_64 architecture has a container package
Paquete container instalado y habilitado container package installed and enabled
Device mode container=yes device-mode container=yes
Memoria libre al menos --memory-max, 64 MiB por defecto free memory ≥ <size>
Almacenamiento la raíz extraída, y el tar en la ruta del tar free flash ≥ <size> (…)
Lista de interfaces la que nombra --iface-list, LAN por defecto interface list <list> exists
ssh un usuario administrador, con una clave o un agente ssh ninguna; la propia conexión

El router tiene que ejecutar RouterOS 7.24 o posterior en arm64, arm (RouterOS de 32 bits) o x86_64. Los routers MIPS, TILE y PPC no tienen paquete container.

7.24 es el mínimo porque el paso del contenedor escribe privileged=, un atributo que RouterOS añadió en esa versión («container - added ability to run containers in privileged mode»). --privileged=false cambia el valor escrito, no si se escribe. doctor marca una versión anterior como MISSING, y el script de instalación se detiene ahí sin escribir nada. Modo privilegiado tiene lo que cambia el atributo.

install lee la arquitectura del router (--arch auto, el valor por defecto), y cada ruta toma la compilación del agente que le corresponde:

Tu equipo architecture-name --arch Compilación del agente
RB5009, CCR2004, hAP ax³ y otros ARM de 64 bits arm64 arm64 linux/arm64
hEX Refresh / hEX S (2025), cualquier placa EN7562CT arm arm linux/arm/v5
Otros ARM de 32 bits (hAP ac², hAP ax², …) arm arm linux/arm/v5 o v7
CHR y RouterOS x86 x86_64 amd64 linux/amd64

El ARM de 32 bits no es una cosa, son dos. La documentación de contenedores de MikroTik dice que los equipos con CPU EN7562CT solo admiten imágenes de contenedor arm32v5, mientras que sus demás placas ARM de 32 bits ejecutan un espacio de usuario ARMv7. Un binario ARMv5 funciona en las dos; uno ARMv7 no arranca en las primeras, y falla con un exec format error en el registro del contenedor después de una instalación correcta. Por eso --goarm vale 5 por defecto, el nivel que arranca en todas partes, y la imagen declara la variante que le corresponde. --goarm 7 compila la ARMv7 para una placa donde se quiera ese juego de instrucciones.

Con --remote-image el router elige la compilación por su cuenta: el índice publicado lleva linux/amd64, linux/arm64, linux/arm/v7 y linux/arm/v5. En arm no se sabe cuál de las dos de 32 bits descarga RouterOS, así que doctor avisa ahí; si el contenedor se detiene con Exec format error, instala desde el tar ARMv5 (Instalación sin conexión).

Descarga el paquete container para tu arquitectura y tu versión de RouterOS desde mikrotik.com, súbelo al router y reinicia. Si ya está y deshabilitado, ejecuta /system/package/enable container y reinicia. doctor solo cuenta el paquete cuando está instalado y no deshabilitado. Para leerlo en el router:

/system/package/print where name="container"
  1. Ejecuta, en el terminal del router:

    /system/device-mode/update container=yes
  2. RouterOS responde con el paso que espera. Un router dice:

    update: please activate by turning power off or pressing reset or mode button in 5m00s

    CHR dice update: turn off power in 5m to activate changes.

  3. En esos cinco minutos, pulsa el botón reset o mode, o corta la alimentación. En CHR, apaga y enciende la máquina virtual. Si nadie lo hace, el cambio se cancela.

Tras tres intentos fallidos el router dice too many unsuccessful attempts … to reset attempt-count y necesita un ciclo de alimentación, o pulsar el botón reset o mode, antes de aceptar otro. /system/device-mode/print muestra container: yes cuando está hecho.

doctor imprime device: con la placa, la versión de RouterOS y la arquitectura, y después una línea por comprobación marcada ok, MISSING o WARN, con lo que encontró entre paréntesis y, en una que falta o en un aviso, una línea fix:. Termina con doctor: every prerequisite is met, o falla con N prerequisite(s) missing; nothing was written. Un WARN es un consejo: nunca cambia ese final, e install sigue adelante. install hace las mismas comprobaciones primero salvo que pases --no-doctor.

Las comprobaciones que ejecuta doctor
Comprobación, tal como se imprimePasa cuandoLa solución que nombra
RouterOS 7.24 or later/system/resource informa una version 7.24 o posterior, que se lee con número de parche o sin él y sea cual sea el canal, como en 7.24 (stable) o 7.25rc1 (testing)actualiza RouterOS a 7.24 o posterior (/system/package/update), y el paquete container con él
architecture has a container packageel architecture-name del router es arm, arm64 o x86_64, las arquitecturas para las que MikroTik publica un paquete containerninguno: en este router no puede ejecutarse ningún agente
the router picks the image's architecturecon --remote-image: siempre, con la arquitectura del router, porque RouterOS la elige del índice multiarquitectura de la imagen. Un aviso en arm, donde el índice tiene linux/arm/v5 y linux/arm/v7 y no se sabe cuál descarga RouterOSen arm, si el contenedor se detiene con Exec format error, instala desde mikroscope-agent-armv5.tar con --agent-tar
architecture matches the --agent-tar imagecon --agent-tar: la arquitectura del propio tar es la del router (amd64 para x86_64); --arch no hace faltadescarga el recurso de la versión que nombra, mikroscope-agent-<arch>.tar
architecture read from the routersin ninguna de las dos opciones de imagen y con --arch sin fijar (o auto): siempre; install y upgrade construyen o cargan la imagen de la arquitectura que leyó doctorninguno
architecture matches --arch <arch>con un --arch explícito y sin opciones de imagen: el architecture-name del router es el que corresponde a --arch (arm64, arm, x86_64)vuelve a ejecutar con el --arch que nombra, o quita --arch para que install la lea del router
container package installed and enabledexiste un paquete container con disabled=nodescarga el paquete container de esta arquitectura y versión de RouterOS, súbelo y reinicia; si ya está y deshabilitado, /system/package/enable container y reinicia
device-mode container=yes/system/device-mode informa container=yes/system/device-mode/update container=yes y confírmalo como pide la consola: en un router que dice update: please activate by turning power off or pressing reset or mode button, pulsa el botón reset o mode o corta la alimentación; en CHR, que dice update: turn off power in 5m to activate changes, apaga y enciende la VM en menos de 5 minutos
free memory ≥ <--memory-max>free-memory es al menos lo que pide --memory-max, 64 MiB por defectolibera memoria en el router, o pide menos con --memory-max
free memory leaves room for the pullun aviso, solo con --remote-image: free-memory es al menos --memory-max más 16 MiB, margen para que RouterOS descargue y extraiga la imagen antes de que arranque el agente. No se ha medido cuánto ocupa una descarga, así que el margen es una estimacióninstala desde un tar con --agent-tar si la descarga falla
free flash ≥ <size> (image tar + extracted root)sin --disk ni --ephemeral: free-hdd-space es al menos el doble de la imagen más 4 MiB. Con --remote-image no se sube nada y el nombre acaba en (extracted root): la raíz en la que se extrae la imagen descargada, 7 MiB, más 4 MiBlibera flash, o instala con --disk tmpfs o --ephemeral donde exista un disco tmpfs
disk <disk> existscon --disk o --ephemeral: existe un disco con ese slot/disk/add type=tmpfs tmpfs-max-size=64M slot=tmpfs para un disco en RAM, o nombra un disco existente con --disk
disk <disk> has ≥ <size> free (image tar + extracted root)con --disk o --ephemeral, cuando el disco existe: su espacio libre es al menos el doble de la imagen más 4 MiB; con --remote-image, la raíz de 7 MiB más 4 MiB, como en la comprobación de la flashlibera espacio en ese disco, o da a un disco tmpfs un tmpfs-max-size mayor
disk tmpfs is RAMcon --ephemeral: el disco del slot tmpfs es de tipo tmpfslibera el slot para un disco tmpfs, o instala con --disk <slot> sin --ephemeral
start-on-boot suits a root in RAMun aviso, cuando el disco es tmpfs: start-on-boot queda en no, porque un reinicio vacía el disco y un contenedor que arranca con el equipo no tiene raízpasa --start-on-boot no, o --ephemeral
veth name <veth> is free or oursninguna veth tiene ese nombre, o la que lo tiene lleva la etiqueta de esta instalaciónelige otra --veth (y otra --subnet), o borra la veth a mano si es un resto tuyo
envlist <name>-env is free or oursninguna envlist tiene ese nombre, o la que lo tiene contiene la entrada MIKROSCOPE_TAG de esta instalaciónelige otro --name
install manifest <disk/>mikroscope/<name>.manifest.txt is free or oursno hay ningún fichero en la ruta del manifiesto de instalación, o el que hay contiene la línea tag= de esta instalaciónmueve el fichero a otro sitio, o elige otro --name
container name <name> is free or ourscon --container-name: ningún contenedor tiene ese nombre, o el que lo tiene lleva la etiqueta de esta instalaciónelige otro --container-name
subnet <subnet> does not overlap a routeninguna ruta de la tabla main, activa o no, cae dentro de la /30, y ninguna red conectada de otra interfaz contiene su extremo del router. Las rutas que solo contienen la /30 (una ruta por defecto, un prefijo más amplio hacia una VPN), las rutas blackhole y la propia veth de la instalación no cuentanelige otra /30 con --subnet
interface list <list> existsexiste la lista --iface-list (por defecto LAN). Con --iface-list none doctor imprime interface list the veth joins y lo da por bueno: no se escribe ninguna pertenencia--iface-list none si ninguna regla del cortafuegos necesita la veth en una lista (doctor lo ofrece primero en ese caso); si no, /interface/list/add name=…, o pasa la lista que usa tu regla de descarte in-interface-list=!…
address list <list>siempre: install añade la /30 a la lista --addr-list (por defecto LANs), lo que la crea si falta, y uninstall retira la entrada. Con --addr-list none doctor imprime address list the /30 joins. Si alguna regla necesita esa pertenencia lo responde la fila siguienteninguno
no firewall rule drops the agent's repliesdoctor lee todas las reglas activas de las cadenas por las que pasan las respuestas del agente, /ip/firewall/raw prerouting y /ip/firewall/filter forward e input, y recorre cada una como RouterOS, gana la primera que coincide, con las respuestas en las listas a las que se une el plan: ninguna regla las descarta. Un aviso cuando una regla podría hacerlo, porque filtra por algo que doctor no evalúa (un destino, una marca, un límite de tasa), y cuando las respuestas a un equipo de la LAN pasan pero una regla podría descartar las que van al propio router (filter input), que necesita el transporte por relaylas --iface-list y --addr-list que dejan pasar las respuestas; cuando ninguna lista lo consigue (una regla src-address=!<rango>, por ejemplo), añade antes de esa regla una de aceptación para in-interface=<veth>, o elige una --subnet dentro del rango
no firewall rule doctor reads is invalid or names a deleted listun aviso: ninguna regla de raw prerouting ni de filter forward e input está marcada como inválida, que RouterOS salta como si no existiera (nombra una interfaz que se quitó o no está lista, y about dice cuál), y ninguna nombra una lista de interfaces que se quitó, que RouterOS guarda como el id de la lista (in-interface-list=!*2000010) y aplica como una lista vacía. Una regla cambiada un momento antes se lee inválida, sin motivo, hasta que RouterOS la aplicacorrige o quita lo que nombra una regla inválida; vuelve a poner por nombre una lista borrada, porque crear una lista con el mismo nombre no repara la regla. Sin motivo, ejecuta doctor otra vez
--lan-address <address> is the router'scon --expose: una interfaz del router tiene esa direcciónpasa la dirección que el router tiene en su LAN, tal como la lista /ip/address/print
--lan-address is not on the uplinkun aviso, con --expose: la interfaz que tiene la dirección no lleva la ruta por defecto, no está en ninguna lista WAN y no comparte ninguna lista de interfaces con la interfaz que lleva la ruta por defectopasa la dirección LAN del router: en el enlace de subida el dst-nat publicaría el agente hacia Internet
no registry credential meant for another registryun aviso, solo con --remote-image: no hay usuario en /container/config, o el host de registry-url es el host del que se descarga la imagen, contando todas las grafías de Docker Hub como una. Un registry-url vacío con usuario puesto avisa. Doctor lee si hay usuario, nunca el nombre, y no puede leer la contraseña/container/config guarda un solo usuario para todo el equipo, y una credencial de otro registro puede hacer que la descarga de una imagen pública acabe en auth error. Instala desde un tar con --agent-tar, pasa un --remote-image del registro al que pertenece el usuario, o borra el usuario si nada más lo necesita
the installed agent published on the LAN asks for a tokenun aviso, que solo aparece cuando una instalación con este --name tiene un dst-nat en la LAN: su entorno contiene un TOKEN. Doctor cuenta las entradas, nunca lee el valorupgrade con el mismo --name y --token <secreto>; o retira el agente, las reglas de LAN y el contenedor juntos con uninstall --name <nombre> --yes
the router does not answer DNS from its uplinkun aviso: allow-remote-requests de /ip/dns está apagado, o una regla de raw prerouting o de filter input descarta una consulta UDP al puerto 53 que entra por la interfaz de la ruta por defecto activa, recorrida como en la comprobación de trampas, gana la primera que coincide. Un aviso de que las consultas podrían pasar cuando una regla filtra por algo que doctor no evalúa, una lista de direcciones de origen por ejemplo. IPv6 no se leeuna regla de descarte para el puerto 53 UDP y TCP en el enlace de subida antes de cualquier aceptación que lo coja, o /ip/dns/set allow-remote-requests=no si ningún equipo de la LAN usa el router como resolvedor
nothing tagged for <name> that these flags do not selectun aviso: en cada menú donde escribe una instalación, los objetos con su etiqueta no son más que los que selecciona el plan de estas opciones. Una instalación hecha con otras opciones (--expose, otras listas, otra --subnet) deja másejecuta status y uninstall sin opciones de forma, para que lean el manifiesto de la instalación, o con las opciones con que se hizo
  • Almacenamiento. Dentro de install, la comprobación usa el tamaño real del tar: el doble de la imagen, porque el tar y la raíz extraída de él comparten el disco hasta que se borra el tar, más 4 MiB. doctor por sí solo supone una imagen de 7 MiB. Con --remote-image no se sube nada, y la comprobación pide la raíz extraída más 4 MiB.
  • Registro. --remote-image le pasa a RouterOS la referencia entera, con el equipo del registro incluido, así que el /container/config registry-url de todo el equipo no decide de dónde sale la descarga, y mikroscope ni lo necesita fijado ni lo escribe. doctor lo lee solo para el aviso de credenciales de arriba: Solución de problemas.
  • Firewall. La comprobación de la lista de interfaces y la del firewall existen por las reglas raw que descartan cada paquete que envía un contenedor: Listas del firewall.

doctor por sí solo, no el que va dentro de install, pregunta después al agente que ya está en marcha qué tiene su anillo, en una sección health tras las comprobaciones. Lee el anillo una vez, directamente desde esta máquina, en la dirección que dan --subnet y --port, la que sondea status; pasa --token (o MIKROSCOPE_TOKEN) si el agente tiene token. Nunca pasa por el relé ni por la dirección de --expose, y nunca cambia el código de salida. Se salta la sección, diciendo por qué, en dos casos:

health (what the running agent's ring shows now):
skipped: no agent answered at 172.30.10.2:9123 from this host (…)

cuando nada responde a /healthz en 3 s, y skipped: the agent answered /healthz but its ring could not be read (…) cuando /healthz responde pero el anillo no, como con un agente con token leído sin --token.

Cuando lee el anillo, imprime cuánto leyó y, o bien una línea limpia, o bien un WARN por hallazgo, cada uno con su fix:, sangrados bajo health:

health (what the running agent's ring shows now):
read 600 samples covering 60 s
ok no loop signature, STP churn, link flap or softnet drop in the window
WARN layer2-loop: 30 frames this router sent came back in on ether2 in the last 60 s, carrying the bridge's own address as their source
fix: something downstream of ether2 reaches the router by a second path. …

El anillo es de 60 s por defecto, así que esto ve lo que pasa ahora; los dashboards y las reglas de alerta leen el historial. Pide al agente como mucho 10 000 muestras, todas en los mismos 3 s: el anillo entero cuando no tiene más, y si no las 10 000 más recientes (los últimos 1 000 s a 10 Hz, los últimos 100 s a 100 Hz). Cada hallazgo es una cuenta de sucesos que un router sano no produce, no un umbral:

Hallazgo Salta con
layer2-loop tres o más tramas en la ventana que volvieron a entrar por un puerto con la propia dirección del bridge como origen
stp-churn un puerto que STP pasó a learning al menos tres veces más de las que lo dejó reenviar, sin la firma del bucle
link-flap dos o más caídas de enlace en un puerto en cualquier punto de las muestras leídas
softnet-drops cualquier paquete que el kernel descartó de su cola softnet
  • layer2-loop. Un bucle repite la firma al intervalo de hello de STP, 2 s por el valor por defecto de RouterOS, treinta veces en un anillo de 60 s, mientras los contadores de RouterOS pueden mostrar el puerto sano y STP lo mantiene bloqueado (Bucle de capa 2).
  • stp-churn. No cuenta bloqueos: un enlace sano que sube registra tres pasos a learning de golpe y llega a forwarding unos segundos después, y deja learning menos forwarding en 0.
  • link-flap. La detección link-flap del propio colector cuenta de otra forma: subidas y caídas de enlace juntas, dos o más en un puerto en 60 s. Un cable que se desenchufa y se vuelve a enchufar una vez es una oscilación allí y no aquí.
  • softnet-drops. Un paquete perdido dentro del router, donde ningún contador de interfaz lo ve. Los squeezes no cuentan: un squeeze es el kernel conteniéndose.

Cada hallazgo nombra el puerto de RouterOS en una placa que conoce el mapa de puertos, y el nombre del kernel en las demás. Los registros del log del kernel se clasifican otra vez a partir de su texto, así que un agente más antiguo se lee igual. Lo que se ha ejecutado contra un agente en marcha está en Probado en.

Necesidad Para Detalle
ssh al router doctor, install, status, upgrade, uninstall un usuario administrador, con una clave o un agente ssh
scp las rutas del tar y del código fuente la subida de la imagen
una imagen del agente install, upgrade una descarga del registro, el tar de la versión o una compilación desde el código con Go 1.27
una ruta hasta el agente record, forward, el sondeo una ruta a la /30 a través del router, el relé de la API o --expose
un usuario de la API de RouterOS el relé, --log-markers, la capa de la API del colector de solo lectura; se queda en tu máquina
  • ssh. La CLI ejecuta el ssh del sistema con BatchMode=yes y ConnectTimeout=15, así que no puede responder a una petición de contraseña ni de clave de host: usa una clave o un agente ssh, y para un router nuevo añade --ssh-option StrictHostKeyChecking=accept-new. --router acepta usuario@equipo o un alias de la configuración de ssh; --ssh-port y --ssh-key recurren a tu configuración de ssh si no se fijan.
  • Sin ssh. El Script de RouterOS, el Generador de scripts y las instalaciones manuales se ejecutan en el propio router: Métodos de instalación.
  • El agente. Acceso por red tiene las tres formas de llegar a él, y Usuario de la API la política del usuario.

Lo que no se ha probado, como una placa de otra arquitectura o un RouterOS anterior a 7.24, está en No probado.