Containerization is powering the next wave to the cloud, with Docker as the software for interacting with the container ecosystem. Per the 31st of January 2022 Docker Desktop will, however, no longer be free for large enterprises. Podman is one of the tools that seeks to replace Docker and has gained a lot of traction in the past months. In this blog I will dive deeper into Podman and what I like about it, but let us start first with Docker!
Docker was released in 2013 and since then gained massive adoption as the containerization solution. Docker did not invent containers, but they greatly simplified developing and working with containers and that made it a success. The product Docker even became so popular that its name is often used interchangeably with containers (e.g. Docker image instead of container image).
After previous (failed) attempts to monetize on Docker related offerings, the company behind Docker decided to reshape its open source offering. The open source version of Docker used to include Docker and Docker Desktop, but as per the 31st of January 2022 Docker Desktop will no longer be free for large enterprises. For small businesses (fewer than 250 employees AND less than $10 million in annual revenue), personal use, education, and non-commercial open source projects Docker Desktop remains free.
Docker is the well known containerization technology and remains free, but what is Docker Desktop? As mentioned, Docker did not invent containers, but they simplified working with low-level Linux kernel features (such as cgroups and namespaces) that together formed a container. These Linux kernel features are not available on Windows and MacOS and that is where Docker Desktop comes into play. Docker Desktop is an application for non-Linux machines with multiple features, but the most important feature is spinning up a Linux VM on a host machine to enable Docker to run and seamlessly integrate with the host machine.
This recent decision regarding Docker Desktop thus only affects non-Linux users. It should be noted that Windows users can also use WSL2 to run Docker on Linux such that using Docker Desktop is not necessary, but this is not a common setup in my experience.
The news on Docker Desktop resulted in mixed reactions from the Technology sector and drew more attention towards competitors of Docker. One of those competitors is the fully open-source tool Podman, that also receives backing by Red Hat. Podman, just like Docker, is a container engine – also known as high-level container runtime, or container runtime in the Kubernetes community. The container engine is the tool that facilitates the core container operations: user interaction via an API, pulling images from a container registry and running containers (often through delegation to a low-level container runtime).
Besides the core container engine functionality, Docker provides container image builder features too. Podman decided to adhere to the Unix philosophy “Make each program do one thing well’ and therefore focuses on container engine functionality. Limited container image building features are, however, available in Podman by sourcing code from Buildah, a Red Hat backed container image builder.
So why should you consider Podman? Personally I did because of the following reasons:
- Compatibility: Podman mimics Docker’s CLI, so you can use the commands
podman exec(including all their options) in the same way as you did on Docker to interact with container. This is possible since the internal container engine steps taken by both tools are similar, which is the result of adhering to many of the same standards. I dive deeper into these standards in the Compatibility section.
- Podman machine: Like Docker, Podman uses specific Linux kernel features to create containers and therefore necessitates a Linux VM on non-Linux machines. Windows users can install Podman on WSL2, but for MacBook users (like myself) Podman is shipped together with an integrated Linux VM (Podman machine) for free. In the Podman machine section I will discuss this further.
- Architecture: Podman has a different architecture than Docker that does not rely on a daemon. While it is not as performant, it is more security oriented as it allows non root execution by default. More on this setup in the Architecture section.
The container ecosystem is governed by multiple standards. Specifically for container engines such as Docker and Podman the following standards are relevant:
- OCI image specification: standardizes how container images are structured and how they should be built. An image should contain:
- an image manifest: JSON file denoting references to the filesystem layers and image configuration that the container image will use.
- a set of filesystem layers: compressed tar file per layer, with the first layer being a tar file with the content of the base image (i.e. filesystem) and all the subsequent layers being the incremental file(system) updates applied per layer. These tar files are unpacked when pulled onto disk by the container engine.
- an image configuration: JSON file denoting the configurable arguments of the container such as entrypoint, cmd, environment variables, labels, exposed ports etc.
- OCI runtime specification: standardizes how to run a container from an unpacked image on disk. Container engines commonly delegate this task to a low-level container runtime. OCI provides a reference implementation of a low-level container runtime named “runc” (originally developed by Docker) for this purpose which is used by many container engines including Docker and Podman.
- CNI and CNM: standardizes how a container engine can add networking to containers via different network plugins. CNI is the mainstream networking standard that is, among others, used by Podman and Kubernetes. Docker decided to create its own networking model named CNM, but this standard is less popular than CNI.
Both Podman and Docker adhere to the above OCI standards for container engines which ensure that their input (i.e. the image structure) and output (i.e. container creation) are the same. The container networking standards followed by Podman and Docker do vary, but both standards produce the same output (i.e. add networking to a container). As a result Podman can be interchanged with Docker without any problems.
Podman is fully open-source, which enables large adoption of the tool and allows for fast-paced improvements based on community requests and efforts. This was demonstrated in 2021 when the Podman machine was integrated into the Podman source code. At the moment Podman machine consist of the following components:
- QEMU plus HVF: Virtualization software
- Fedora CoreOS: The virtualized Linux distribution
- Ignition: Configuration management software for Fedora
- gvisor-tap-vsock: Arranges port mapping from VM to host machine
That said, the Podman machine setup is still pretty basic compared to Docker Desktop. Currently it is for example not possible to mount files from a MacOS host to a container without mounting them to Podman machine first. Luckily there is an on-going investigation by the community to further develop Podman machine to a Podman Desktop solution that is more on par with Docker Desktop!
While Docker and Podman are both container engines, they are built in a different way. Docker uses a client-server model, where the Docker CLI communicates to a Docker daemon that spawns all containers as child processes. Podman uses a traditional fork-exec model where the Podman CLI spawns the containers as child processes of the user.
The Docker daemon is responsible for interaction with the container engine and storing all the state and lock information on containers in memory. The setup with an in-memory daemon is advantageous from a performance point of view, but creates a single point of failure since fatal errors in the Docker daemon will affect running containers (either terminated or orphaned). Additionally, the daemon approach is less secure from an audit perspective since all containers (independent of the user) get assigned the user ID of the Docker daemon.
Podman on the other hand is daemonless. The user interacts directly with the container ecosystem through lower level tools such as libpod (creating containers) and conmon (attaching to and monitoring running containers). Every container created by Podman gets assigned the ID of the user and has its own conmon instance such that there is no single point of failure. State and lock information on containers is stored on the filesystem of the host and is accessible by the Podman CLI.
Until recently Podman’s daemonless setup also translated into a security advantage over Docker: rootless mode. Via user namespaces rootless mode allows non-root users on the host machine to run root containers. This reduces Podman’s attack surface since malicious containers cannot obtain root permissions on the host machine. Podman by default runs rootless, but does support users running Podman as root by elevating their permissions. In the majority of the situations Docker runs using a daemon with root privileges, but since December 2020 it also supports rootless execution (via a separate installation though). As rootless Podman is a topic on its own I refer to the following blogs for more detailed information: How does rootless Podman work and Podman and user namespaces.
Podman is a container engine that is fully open-source, OCI compliant and secure by design. In the light of Docker’s recent business model update, these characteristics of Podman, together with its mimicked Docker CLI, make Podman an attractive container engine alternative to Docker that is ready-to-use. If I made you enthusiastic about Podman, then I would recommend heading to Podman’s installation instruction page to give it a go!.