MikroTik RouterOS CHR#
MikroTik RouterOS Cloud Hosted Router (CHR) from the official mikrotik/chr image is identified with the mikrotik_chr kind in the topology file. The image is published by MikroTik for amd64 and arm64 and is used as is: no vrnetlab build is needed.
The image is a QEMU VM (Alpine, qemu and the CHR disk) in a container. Its own /start.sh is not made for orchestrated links (#3116), so the kind writes a launcher script into the node's lab directory, mounts it read-only and runs it as the entrypoint instead. The launcher uses only the tools that ship in the image.
Note
The mikrotik_ros kind runs CHR from an image you build with vrnetlab. Both kinds use the same interface naming and startup config format, so a lab moves from one to the other by changing kind and image.
Getting MikroTik RouterOS CHR image#
Tags follow RouterOS versions, plus stable, long-term, testing and development. This kind has been tested with 7.24.5 (stable), 7.23.8 (long-term) and 7.25rc2 (testing).
Managing MikroTik RouterOS CHR nodes#
Winbox (TCP 8291) and the RouterOS API (TCP 8728, 8729 for TLS) are reachable on the node's management address.
The serial console is on port 5000 inside the container:
The node's management address is RouterOS's own ether1 address (transparent management), so every service RouterOS runs answers on it directly, with nothing forwarded.
Note
Default credentials are admin:admin. With custom credentials the kind creates that user in the full group and disables the factory admin account, which has a blank password on a fresh CHR disk.
Interface naming#
You can use interface names in the topology file like they appear in RouterOS: etherX, where X is the port number.
ether2- first data portether3- second data port, and so on
Warning
Data ports start at ether2: ether1 is the management interface. Using ether1 in a topology results in an error.
The container interface ethN is RouterOS ether(N+1), also when links leave gaps: a link on eth12 alone still lands on ether13, with ether2 to ether12 present and unlinked. Interface MTU follows the link MTU, and LLDP frames are forwarded, so /ip neighbor shows the peers.
Node configuration#
MikroTik RouterOS CHR nodes boot with the default CHR configuration plus the credentials, the identity (set to the node name) and the management setup described below.
Startup configuration#
A RouterOS script (.rsc) set with startup-config is imported once the router is up:
name: chr_lab
topology:
nodes:
r1:
kind: mikrotik_chr
image: mikrotik/chr:7.24.5
startup-config: r1.rsc
The file is copied to the node's lab directory as ftpboot/config.auto.rsc and imported over the REST API. RouterOS imports line by line and stops at the first error: in that case the container log carries RouterOS's own reason with the line number, for example
chr-launch: startup config import FAILED: Script Error: bad parameter network-type (line 3 column 59); lines before the failing one were applied, the rest were not
and the node does not become ready.
Saving configuration#
containerlab save writes each node's /export to ftpboot/config.auto.rsc in its lab directory. The management objects the launcher creates at every boot (everything tagged clab-mgmt, and the ether1 DHCP client) are left out, so the saved file can be used as the startup config of the next deployment, also one with different management addresses.
Node readiness#
The node is ready once RouterOS accepted the credentials and the startup config, reaches its gateway from the management address and, unless the configuration disables SSH, its SSH server answers. An SSH server that does not answer within CHR_BOOT_WAIT is logged, and the node is still declared ready, since REST and the console work. The container log then shows
and the kind's default healthcheck reports the container healthy, so stages with wait-for can depend on it. A node whose startup config was rejected never becomes healthy. The default healthcheck's start period follows the launcher's own deadlines (CHR_INTF_WAIT + 3 × CHR_BOOT_WAIT + 90 s, 1050 s with the defaults), so a slow boot never reports unhealthy. A healthcheck set in the topology replaces the default one.
Resources#
The kind reads the official image's own environment variables:
| Variable | Default | Purpose |
|---|---|---|
MEM |
256 MiB + 8 MiB per data interface and vCPU | VM memory (a QEMU -m value, e.g. 1024 or 1G) |
CPUS |
1 |
VM vCPUs |
DISK |
128M |
minimum disk size (the disk only grows) |
CHR_INTF_WAIT |
60 |
seconds to wait for the data interfaces containerlab attaches before the VM starts |
CHR_BOOT_WAIT |
300 |
seconds to wait for RouterOS to answer, for the startup config import, and for SSH before the node is declared ready |
KVM is used when /dev/kvm is available. Without it the image's QEMU runs under TCG emulation: the node works, but boots several times slower.
Management connectivity#
Management is transparent: the IPv4 and IPv6 addresses and gateways containerlab gives the node's eth0 are configured on RouterOS ether1, and the container's eth0 is bridged to the VM's ether1. The router is the node's management address: SSH, the REST API, Winbox, SNMP and every other service answer on it, LLDP/MNDP work on the management network, and the address in the topology table is the one in the RouterOS configuration.
The image ships busybox only (no tc), so where vrnetlab's transparent management redirects with tc-mirred, this kind uses a Linux bridge. The container itself has no address on the management network; it reaches RouterOS for bootstrap over IPv6 link-local on that bridge.
The management return path lives in its own routing table, mgmt, selected by routing rules for the management addresses, and CHR's ether1 DHCP client is disabled. A default route in the lab configuration, a PPPoE client's default route or a dual-WAN setup in main therefore does not cut SSH or REST access to the node. RouterOS's router advertisements on ether1 carry a zero router lifetime, so no host on the management network takes the router as its IPv6 default gateway; the container joins the management network only once this is in place. The objects carry the comment clab-mgmt and are re-applied at boot when the container's addressing changed.
Warning
Do not remove or change the clab-mgmt objects or the mgmt routing table: management of the node depends on them.
Restarts#
containerlab restart and a /system reboot inside RouterOS keep the interface names, MAC addresses, configuration and links: the launcher persists the NIC identity in the container on first boot and does not re-run the bootstrap. A plain docker restart keeps the router and its management, but Docker deletes the node's veth links, which stay down until the node is restarted with containerlab or the lab is redeployed.
File mounts#
For each node containerlab creates in its lab directory:
ftpboot/- mounted to/ftpboot, holdsconfig.auto.rscchr-launch.sh- the launcher, mounted read-only to/chr-launch.shand rewritten on every deploy