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 |
Desliza en horizontal para ver todas las columnas
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 |
Desliza en horizontal para ver todas las columnas
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).
Paquete container
Sección titulada «Paquete container»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/ y reinicia. doctor solo cuenta el paquete cuando está instalado
y no deshabilitado. Para leerlo en el router:
/system/package/print where name="container"Device mode
Sección titulada «Device mode»-
Ejecuta, en el terminal del router:
/system/device-mode/update container=yes -
RouterOS responde con el paso que espera. Un router dice:
update: please activate by turning power off or pressing reset or mode button in 5m00sCHR dice
update: turn off power in 5m to activate changes. -
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/ muestra container: yes cuando está hecho.
Comprobaciones previas
Sección titulada «Comprobaciones previas»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.
| Comprobación, tal como se imprime | Pasa cuando | La 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 package | el architecture-name del router es arm, arm64 o x86_64, las arquitecturas para las que MikroTik publica un paquete container | ninguno: en este router no puede ejecutarse ningún agente |
| the router picks the image's architecture | con --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 RouterOS | en arm, si el contenedor se detiene con Exec format error, instala desde mikroscope-agent-armv5.tar con --agent-tar |
| architecture matches the --agent-tar image | con --agent-tar: la arquitectura del propio tar es la del router (amd64 para x86_64); --arch no hace falta | descarga el recurso de la versión que nombra, mikroscope-agent-<arch>.tar |
| architecture read from the router | sin 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ó doctor | ninguno |
| 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 enabled | existe un paquete container con disabled=no | descarga el paquete container de esta arquitectura y versión de RouterOS, súbelo y reinicia; si ya está y deshabilitado, /system/ y reinicia |
| device-mode container=yes | /system/device-mode informa container=yes | /system/ 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 defecto | libera memoria en el router, o pide menos con --memory-max |
| free memory leaves room for the pull | un 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ón | instala 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 MiB | libera flash, o instala con --disk tmpfs o --ephemeral donde exista un disco tmpfs |
| disk <disk> exists | con --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 flash | libera espacio en ese disco, o da a un disco tmpfs un tmpfs-max-size mayor |
| disk tmpfs is RAM | con --ephemeral: el disco del slot tmpfs es de tipo tmpfs | libera el slot para un disco tmpfs, o instala con --disk <slot> sin --ephemeral |
| start-on-boot suits a root in RAM | un 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íz | pasa --start-on-boot no, o --ephemeral |
| veth name <veth> is free or ours | ninguna veth tiene ese nombre, o la que lo tiene lleva la etiqueta de esta instalación | elige otra --veth (y otra --subnet), o borra la veth a mano si es un resto tuyo |
| envlist <name>-env is free or ours | ninguna envlist tiene ese nombre, o la que lo tiene contiene la entrada MIKROSCOPE_TAG de esta instalación | elige otro --name |
| install manifest <disk/>mikroscope/<name>.manifest.txt is free or ours | no hay ningún fichero en la ruta del manifiesto de instalación, o el que hay contiene la línea tag= de esta instalación | mueve el fichero a otro sitio, o elige otro --name |
| container name <name> is free or ours | con --container-name: ningún contenedor tiene ese nombre, o el que lo tiene lleva la etiqueta de esta instalación | elige otro --container-name |
| subnet <subnet> does not overlap a route | ninguna 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 cuentan | elige otra /30 con --subnet |
| interface list <list> exists | existe 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/, 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 siguiente | ninguno |
| no firewall rule drops the agent's replies | doctor 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 relay | las --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 list | un 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 aplica | corrige 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's | con --expose: una interfaz del router tiene esa dirección | pasa la dirección que el router tiene en su LAN, tal como la lista /ip/address/print |
| --lan-address is not on the uplink | un 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 defecto | pasa 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 registry | un 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 token | un 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 valor | upgrade 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 uplink | un 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 lee | una 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 select | un 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ás | ejecuta status y uninstall sin opciones de forma, para que lean el manifiesto de la instalación, o con las opciones con que se hizo |
Desliza en horizontal para ver todas las columnas
- 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.doctorpor sí solo supone una imagen de 7 MiB. Con--remote-imageno se sube nada, y la comprobación pide la raíz extraída más 4 MiB. - Registro.
--remote-imagele pasa a RouterOS la referencia entera, con el equipo del registro incluido, así que el/container/de todo el equipo no decide de dónde sale la descarga, y mikroscope ni lo necesita fijado ni lo escribe.config registry-url doctorlo 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.
Comprobaciones de salud
Sección titulada «Comprobaciones de salud»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 |
Desliza en horizontal para ver todas las columnas
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ónlink-flapdel 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.
Tu ordenador
Sección titulada «Tu ordenador»| 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 |
Desliza en horizontal para ver todas las columnas
- ssh. La CLI ejecuta el
sshdel sistema conBatchMode=yesyConnectTimeout=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.--routeraceptausuario@equipoo un alias de la configuración de ssh;--ssh-porty--ssh-keyrecurren 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.