I’ve spent some of the last weeks working on a replacement for runC, the most used/known OCI runtime for running containers. It might not be very well known, but it is a key component for running containers. Every Docker container ultimately runs through runC.
Having containers running through some common specs allow some pieces to be replaced without having any difference in behavior.
The OCI runtime specs describe how a container looks like once it is running, for instance it lists all the mount points, the capabilities left to the process, the process that must be executed, the namespaces to create and so on.
While the rest of the containers ecosystem is written in Go, from Docker to Kubernetes, I think that for such a low level tool C still makes more sense. runC itself uses C for its lower level tasks forking itself once the configuration done and setting up the environment in C before launching the container process.
I’ve tried running sequentially 100 times a container that runs only /bin/true and the results are quite good:
| | crun | runC | % | | 100 /bin/true (no network namespace) | 0m4.449s | 0m7.514s | 40.7% | | 100 /bin/true (new network namespace) | 0m15.850s | 0m18.986s | 16.5% |
Most of the time for running a container seems to be in the creation of a network namespace. I had expected some costs in the Go->C process handling but I am surprised by the results when the network namespace is not used as crun is almost double as fast as runC.
For the parsing of the OCI spec file crun uses https://github.com/giuseppe/libocispec.
crun is still experimental and some features are missing, but if you are intested you can take a look here: https://github.com/giuseppe/crun/ and open a PR if you have any improvements