Mirantis Container Runtime Boosts Performance with Support for crun
)
Mirantis Container Runtime (MCR) can now run containers faster than ever before. Starting with MCR 25.0.9, MCR supports using crun
as an alternative container runtime!
What is a container runtime?
Whew! A question more complicated than it seems! After all, the product itself is called “Mirantis Container Runtime,” although technically it encompasses more than just a container runtime — it also includes the Moby containerization framework, Docker CLI, encryption modules, and more.
In this case, when we say crun
is an alternative container runtime, “container runtime” refers to a specific bit of the MCR software stack that actually launches the executing container. In the most traditional case, this involves setting up a bunch of Linux kernel stuff that lets a process pretend it’s the only process in the world. You give the runtime an OCI bundle, and it spins it up.
What is crun?
The default and original container runtime is runc
. In the beginning, there was onlyrunc
.
Then, somebody said, “Well, all the Linux kernel stuff is C, so why should this low-level sausage-making piece be in Go?” and thus crun
was born.
crun
is an OCI-compliant re-implementation of runc
in the C programming language. It does the same things as runc
. It takes the same commands with the same arguments and the same inputs, and it runs the same containers. From a functional standpoint, crun
behaves identically to runc
to such a degree that one way to use crun
is to just rename it to runc
and replace the original runc
binary.
However, crun
has a smaller binary size, requires less memory, and offers performance advantages, as we confirmed by testing older and newer versions of MCR.
How to enable crun
Using crun
requires a bit of configuration. Mirantis provides the crun-ee
package in its repositories, which ships our tested version of crun
. Just install that package with your package manager. Then, edit the daemon.json
file to add crun
as a runtime. You can also, optionally, configure crun
as the default runtime.
{
"default-runtime": "crun",
"runtimes": {
"crun": {
"path": "/usr/bin/crun"
}
}
}
If crun
is the default runtime, then just pass the --runtime
flag when starting your containers:
$ docker run --runtime crun
Performance comparison
We did some quick performance testing to compare crun
to runc
on MCR 25.0.9 (and also to MCR 23.0.17, which uses runc
). crun
and runc
are both run-and-done processes. They set up a container process, and then they exit; they have no ongoing effect on the performance of the container once it’s started. So, to compare them, we ran tests that start
and exec
containers, which are the operations that involve these runtimes. The tests were run on RHEL 9.5, on AWS m4.large instances. Like all things performance-related, your mileage may vary.
The results are pretty impressive. crun
outperforms runc
in tests for both starting a bunch of containers and execing into running containers a bunch of times. I got a chance to play with some R, so I've got this on some nice graphs for you.
Running containers
This test involved running 50 containers, using the time
command to measure how long each operation took. Starting with 0 containers running, containers were launched one after another, timing each run. Without removing the container, another container was started, until 50 total were started. This was repeated 10 times for each runtime. Each point represents the Real Time for the nth container started, not the cumulative time to start n containers.
crun
outperforms runc
, especially as the number of running containers climbs.
Exec into running containers
For this test, we started a container, and then ran a docker exec
command, timing each run. We did 50 execs for each case. This data is displayed on box plots, with outliers excluded. This kind of graph shows the quartiles of our results. Again, crun
outperforms runc
.
Ok, but ultimately, why support crun?
Here’s the real juicy part of this blog: crun
is the easiest runtime for Mirantis to officially extend support to. If we’re going to support alternative container runtimes, then crun
is the obvious place to start. But we’re definitely not finished here. Now that we’ve got the proof-of-concept in the form of crun
, we can start exploring other alternative container runtimes. And while crun
is just the mirror-universe of runc
, other container runtimes introduce really cool functionality and features. Keep your ear to the ground for the wave of alternative runtime support headed your way in future releases of MCR.
To learn more, please see the MCR docs.