1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
-
+
-
+
-
-
|
# Motivation
The [RouterOS `container.npk` feature](https://help.mikrotik.com/docs/display/ROS/Container) is highly useful, but it is a custom development written in-house by MikroTik, not a copy of Docker Engine or any of the other server-grade container engines.(^Podman, LXC/LXD, etc.) Because of the stringent resource constraints on the bulk of MikroTik’s devices, it is exceptionally small, thus unavoidably very thinly featured compared to its big-boy competition. If we can use installed size as a proxy for expected feature set size, we find:
* **Docker Engine**: 422 MiB(^Version 27.1.1, according to `dnf remove docker-ce…` after installing these packages [per the instructions](https://docs.docker.com/engine/install/rhel/#install-docker-engine).)
* **`containerd`+`nerdctl`**: 174 MiB(^Version 2.0.0-rc1 of `nerdctl` plus the `containerd` from the Docker Engine CE install according to `sudo dnf remove containerd` and `du -sh nerdctl`.)
* **Podman**: 107 MiB(^Version 4.9.4 on EL9, according to `sudo dnf remove podman conmon crun`.)
* **systemd-nspawn**: 1.3 MiB(^This is the bare-bones OCI image runner built into systemd, with a feature set fairly close to that of `container.npk`. The size above is for version 252 of this program’s parent `systemd-container` package as shipped on EL9.)
* **`container.npk`**: _0.0626 MiB_(^Version 7.15.2, according to `/system/package/print`.)
And this is fine! RouterOS serves a particular market, and its developers are working within those constraints. The intent here is to provide a mapping between what people expect of a fully-featured container engine and what you actually get in RouterOS. Where it makes sense, I try to provide workarounds for missing features and guidance to alternative methods where RouterOS’s way merely *works* differently.
# <a id="general"></a>General Observations
# <a id="global"></a>Global Limitations
Allow me to begin with a distilled version of the details below, both to satisfy the **tl;dr** crowd and to set broad expectations for the rest of my readers.
Allow me to begin with the major limitations visible at a global level in the RouterOS `container.npk` feature, both to satisfy the **tl;dr** crowd and to set broad expectations for the rest of my readers:
The major things lacking in RouterOS’s `container.npk` feature are:
* a local image cache(^One knock-on effect of this not covered above is that removing and reinstalling a container requires RouterOS to re-download the image, even when done back-to-back, even if you never start the container between and thereby cause it to make changes to the expanded image’s files.)
* a CoW/overlay file system(^This is not a verified fact, but an inference based on the observation that if RouterOS _did_ have this facility underlying its containers, I would expect to find equivalents to Docker’s `commit` and `diff` commands. This pairs with the lack of an image cache: no CoW means no need for a baseline source to compute deltas against.)
* image building(^RouterOS's container runtime is closer in nature to the `runc` command underlying `containerd` than to the broader Docker Engine product. An even closer match is the lightweight `crun` command at the heart of Podman, and even more so the elementary runner that ships with systemd, variously called either [`systemd-nspawn`][sdnsp] or [`systemd-container`][sdcnt], depending on the tastes of whoever is packaging it.)
* orchestration
* JSON and REST APIs
* per-container limit controls:(^The only configurable resource limit is on maximum RAM usage, and it’s global, not settable on a per-container basis.)
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
-
+
|
The answer is that if you want a RouterOS container to do anything tricky like that, you need to write your own `ENTRYPOINT` script.
Another bit of fallout from all this is that there can be no equivalent to commands like “`docker run --attach std…`” under RouterOS due to lack of a termios/pty subsystem visible at the RouterOS CLI level.
But let us move on from `run`.
Given the size of the output from `docker create --help`, it should not be surprising that the bulk of that is either not available in RouterOS or exists in a very different form. Most of these limitations stem from the list of [generalities above](#general). For instance, the lack of any CPU usage limit features means there is no equivalent under `/container` for the several `docker create --cpu*` options. Rather than go into these options one by one, I’ll cover the ones where the answers cannot be gleaned through a careful reading of the rest of this article:
Given the size of the output from `docker create --help`, it should not be surprising that the bulk of that is either not available in RouterOS or exists in a very different form. Most of these limitations stem from [the list above](#global). For instance, the lack of any CPU usage limit features means there is no equivalent under `/container` for the several `docker create --cpu*` options. Rather than go into these options one by one, I’ll cover the ones where the answers cannot be gleaned through a careful reading of the rest of this article:
* **`--env`**: The equivalent is this RouterOS command pair:
/container/envs/add name=NAME …
/container/add envlist=NAME …
This is in fact closer to the way the **`--env-file`** option works, except that under RouterOS, this particular “file” isn’t stored under `/file`!
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
-
+
|
## <a id="build"></a>`build`/`buildx`
RouterOS provides a bare-bones container runtime only, not any of the image building toolchain.
## <a id="commit"></a>`commit`
Given the [generalities above](#general), it should be no surprise that RouterOS has no way to commit changes made to the current image layer to a new layer.
Given the [global limitations](#global), it should be no surprise that RouterOS has no way to commit changes made to the current image layer to a new layer.
## <a id="compose"></a>`compose`
RouterOS completely lacks multi-container orchestration features, including lightweight single-box ones like [Compose](https://docs.docker.com/compose/) or [Kind](https://kind.sigs.k8s.io) virtual clusters.
|