The hidden magic of Podman's crun

Posted on Sun 26 January 2025 in Containers

What's a crun, anyway?

The success of Docker rests on one major aspect: convenience. Both docker and its major alternative Podman have revolutionized the way applications are deployed and managed. They did this by providing a ridiculously easy way to obtain images of single applications up to whole operating systems, and deploy playground containers or fully preconfigured network stacks with just a single command.

The actual work of running the containers, however, is performed by a different tool called the OCI runtime. For docker, this is usually runc. Podman has their own implementation, called crun - which on first glance looked like the same thing to me. That got me wondering: why would there be a choice in this tool, if there's not much difference? Of course, this abstraction makes sense when thinking about other host OS (Windows, recently also FreeBSD). What struck me much more, however, was Kata containers, a runtime that runs the container in a VM - interesting!

Security

On the technical side, the key difference between containers and VMs is the isolation:

Architecture comparison of containers and vms

Part of what makes containers so practical and fast is, that they are just regular programs running on your regular kernel. VMs however run on virtual hardware: a "real OS" on simulated GPU, RAM, filesystems, network, etc. It's easy to see that there's a conceptual difference between programs talking to the host kernel, or a fully isolated sandbox. Getting the abstraction of VMs, while keeping the convenience of containers, sounds simply awesome!

Boost podman with krun

Luckily, there's not only Kata containers, which currently seems to work only with docker. crun, podman's own OCI runtime, has support for similar functionality. The magic comes from libkrun and its companion libkrunfw. Together, they provide a simple and low-overhead way of running Linux VMs on KVM. Simply install both of them, then recompile crun with ./configure --with-libkrun <...>. This will provide krun, an alias to crun, that will behave exactly the same as you're used to - except your container runs in a VM!

With the default runtime, the container sees my host kernel:

$ podman run --rm --runtime=crun alpine uname -a
Linux 095cdcb8326f 6.12.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 18 Jan 2025 02:26:57 +0000 x86_64 Linux

Using krun, we've now placed another kernel and a hypervisor between the workload and our host:

$ podman run --rm --runtime=krun alpine uname -a
Linux 379fb7c481d8 6.6.59 #1 SMP PREEMPT_DYNAMIC Thu Nov  7 05:07:35 PM CET 2024 x86_64 Linux

Now there's just hoping that sooner or later, this becomes part of the regular podman/crun packages. For Arch Linux, there's already AUR packages for libkrun and libkrunfw - and I've been so free to add an alternative crun-krun package for the last step.

Update Jan 2026: it's now enabled in the regular crun package in arch, yay!

Happy secure containering!