Skip to content

Storage and container settings

install puts the image tar, the container root and the install manifest on one disk, and creates the container with the settings below. Run mikroscope plan with your flags to see every value before anything is written.

Object Default Flag
veth + /30 veth-mikroscope, 172.30.10.0/30 (router .1, agent .2) --veth, --subnet
router address 172.30.10.1/30 on the veth derived from --subnet
install manifest mikroscope/<name>.manifest.txt on the internal flash --disk, --ephemeral
image tar <name>.tar, uploaded with scp and deleted once the image is extracted; none with --remote-image --disk, --ephemeral, --remote-image
container root mikroscope/<name> on the internal flash --disk, --ephemeral
container no name=: RouterOS names it --container-name
envlist <name>-env --rate, --buffer, --port, --token, …
tag mikroscope:<name> (managed by mikroscope) on every object that takes a comment; as MIKROSCOPE_TAG in the envlist --name, default mikroscope
  • --subnet is an IPv4 /30 given at its network address; the router takes .1 and the agent .2. If 172.30.10.0/30 is in use on your router, pick another: doctor names a route that overlaps it.
  • --name and --container-name take up to 32 characters and --veth up to 64: letters, digits, _, . and -, starting with a letter or digit.
  • --disk is a RouterOS disk slot: empty for the internal flash, tmpfs, disk1, usb1 and so on. With --disk, the manifest, the tar and the root move together: <disk>/<name>.tar and <disk>/mikroscope/<name>.
  • Every removal selects the container by its tag, not by its name.

doctor checks the space and the disk before install writes:

The checks doctor runs
Check, as printedPasses whenThe fix it names
free flash ≥ <size> (image tar + extracted root)without --disk or --ephemeral: free-hdd-space is at least twice the image plus 4 MiB. With --remote-image nothing is uploaded and the name ends in (extracted root): the root the pulled image is extracted into, 7 MiB, plus 4 MiBfree flash, or install with --disk tmpfs or --ephemeral where a tmpfs disk exists
disk <disk> existswith --disk or --ephemeral: a disk with that slot exists/disk/add type=tmpfs tmpfs-max-size=64M slot=tmpfs for a RAM disk, or name an existing disk with --disk
disk <disk> has ≥ <size> free (image tar + extracted root)with --disk or --ephemeral, once the disk exists: its free space is at least twice the image plus 4 MiB; with --remote-image, the 7 MiB root plus 4 MiB, as the flash checkfree space on that disk, or give a tmpfs disk a larger tmpfs-max-size
disk tmpfs is RAMwith --ephemeral: the disk in slot tmpfs is of type tmpfsfree the slot for a tmpfs disk, or install with --disk <slot> without --ephemeral
start-on-boot suits a root in RAMa warning, when the disk is a tmpfs disk: start-on-boot resolves to no, since a reboot empties the disk and a container started at boot has no rootpass --start-on-boot no, or --ephemeral
Default --disk tmpfs --ephemeral
Manifest, tar and root internal flash the tmpfs disk the tmpfs disk
start-on-boot yes yes; doctor warns no
Flash writes the tar and the root none for the tar and the root none
After a reboot the agent starts again the root is gone, and a container started at boot has none the container is stopped, with its root, image and manifest gone
  • Persistent is the default: the root on the internal flash, start-on-boot=yes, and restart-policy=on-failure bounded to five restarts ten seconds apart, so a broken image cannot loop at boot.

  • --ephemeral puts the manifest, the tar and the root on the disk in slot tmpfs, which must be a RAM disk, and sets start-on-boot=no. Nothing is written to flash (measured), and nothing survives a reboot. A router without that disk fails doctor, whose fix adds one:

    /disk/add type=tmpfs tmpfs-max-size=64M slot=tmpfs
  • --disk tmpfs without --ephemeral puts the same files on the tmpfs disk and keeps start-on-boot=yes, which doctor warns about. Add --start-on-boot no, or use --ephemeral.

After a reboot, an --ephemeral install’s container is still configured and stopped, and its manifest went with the disk (tested). uninstall --ephemeral removes the rest by its tag.

Setting Value Flag
name= not written, so RouterOS names the container --container-name
file= or remote-image= the uploaded tar, or the whole reference, registry host included --agent-tar, --remote-image
interface= the veth --veth
root-dir= mikroscope/<name> on the disk --disk, --ephemeral, --name
envlist= <name>-env --name
logging= yes, so what the agent prints reaches the router log none
start-on-boot= yes; no with --ephemeral --start-on-boot: auto, yes or no
restart-policy= on-failure none
restart-max-count= 5 --restart-max-count, 0–100
restart-interval= 10s --restart-interval, ^\d{1,4}[smh]$
memory-max= 64M, enforced as the container’s cgroup limit --memory-max
privileged= yes --privileged=false
ignore-remote-image-change= yes none
comment= the tag --name
  • --start-on-boot auto is no with --ephemeral and yes otherwise.
  • privileged=yes drops the container’s user namespace, so the kernel log, /proc/slabinfo and the MTD ECC counters are readable. It does not widen the network or PID namespace; Privileged mode has the detail.
  • The agent catches SIGTERM; RouterOS kills a container that does not, at once. The agent stops within RouterOS’s default stop time of 10 s.

RouterOS extracts the image when the container is added, and the tar has no use after that. On the tar route, install:

  1. adds the container;
  2. waits until RouterOS reports it stopped, which is when the extraction is done, for up to --extract-timeout (default 120s, 10–600 s);
  3. deletes the tar;
  4. starts the container.

On timeout it stops with mikroscope: the image was not extracted within 120 s; mikroscope.tar stays. The tar stays with the container, and uninstall removes the two together. A tar left behind would be what uninstall has to find later, in a /file index that can lag a container removal by minutes.

The container is created with ignore-remote-image-change=yes. With no, RouterOS watches the image, and removing the tar makes it stop, remove and re-extract the container minutes later (verified).

Until the tar is deleted, it and the root extracted from it share the disk, so doctor asks for twice the image plus 4 MiB. With --remote-image nothing is uploaded: RouterOS pulls the layers, there is no tar to wait for or delete, and doctor asks for the extracted root, 7 MiB, plus 4 MiB. The root still goes where --disk and --ephemeral say.

install writes the install manifest first, mikroscope/<name>.manifest.txt beside the container root, and uninstall deletes it last. It records how the install was made and every object it created:

mikroscope-manifest=1
name=mikroscope
tag=mikroscope:mikroscope (managed by mikroscope)
disk=
veth=veth-mikroscope
subnet=172.30.10.0/30
port=9123
iface-list=LAN
addr-list=LANs
expose=
container-name=
remote-image=registry-1.docker.io/jmrplens/mikroscope-agent:1.6.1
token=no
dir=mikroscope
file=mikroscope/mikroscope.manifest.txt
object=/interface/veth name=veth-mikroscope
object=/ip/address interface=veth-mikroscope
object=/interface/list/member interface=veth-mikroscope list=LAN
object=/ip/firewall/address-list list=LANs address=172.30.10.0/30
object=/container/envs list=mikroscope-env
object=/container interface=veth-mikroscope
dir=mikroscope/mikroscope
  • The header lines are the install’s shape, under the CLI’s flag names. status, upgrade and uninstall read them, so they need no shape flag, and refuse one that contradicts them.
  • token= says only whether a token was set, never its value. The manifest holds no secret.
  • dir=, file= and object= list what the install created, in creation order: a path, or a menu and a selector that, with the tag, selects the object.
  • Every install route writes it: the CLI’s install and upgrade, and the plan --rsc script.
  • An install without one, made by an older CLI or --ephemeral after a reboot, is read from its tagged objects instead.

The envlist holds the agent’s configuration and the ownership marker, and nothing else:

The entries install writes into the agent's envlist
KeyWrittenFromHolds
MIKROSCOPE_TAGalways--namethe ownership marker mikroscope:<name> (managed by mikroscope), written first and removed last; the agent ignores it
RATE_HZalways--rate, default 10, 1–100the sampler rate, in Hz
BUFFER_Salways--buffer, default 60, 10–3600the ring's length, in seconds
PORTalways--port, default 9123, 1–65535the agent's HTTP port
ADDRalways--subnetthe agent's address, the .2 of the /30; the agent binds only there
MEM_LIMIT_MBalways--mem-limit-mb, 8–1024the agent's Go soft memory limit, in MiB; derived from the ring (rate × buffer × line, × 2.5, at least 16 MiB, at most three quarters of --memory-max while that still holds the ring) unless --mem-limit-mb gives it
FLOOR_HZonly when above 0--floor-hz, default 0, 0–1000one cadence for every level source, in Hz
CAPTURE_MBalways--capture-mb, default 4, 0–256the triggered-capture budget, in MiB; 0 turns captures off
TRIGGERSonly when set--triggersthe trigger conditions; unset, the agent uses its default set
TOKENonly when set--tokenthe bearer token the agent requires, from --token or MIKROSCOPE_TOKEN, with or without --expose

No sink address, no sink token and no API credential goes into it. Treat everything in it, the token included, as readable by any RouterOS user with read: such a user can list every container’s envlist over the API (verified). The plan prints the token masked as (token). Security model says which credential lives where, and Environment variables lists the variables the agent reads beyond these.

Move --memory-max and --mem-limit-mb with --rate and --buffer:

  • The ring holds rate × buffer lines of about 3.5 kB each.
  • The Go soft limit wants about twice the ring and has to sit comfortably under memory-max. --mem-limit-mb 0, the default, derives it: 16 MiB for 10 Hz and a 60 s ring under 64M.
  • The agent’s startup check counts 3 456 B a line plus --capture-mb. Above memory-max it refuses to start; above half of --mem-limit-mb it warns.

The defaults held at 10, 50 and 100 Hz: --buffer 60, the derived --mem-limit-mb and --memory-max 64M (measured). What a tight limit costs is on Agent cost, and each rate on Rate ceiling.