As the Podman machine function becomes more used—particularly on Macs—there have been many questions about how this all works. Some of what is tossed around on the internet is pure speculation, so this article aims to eliminate any speculation.
Many people do not realize that containers are really Linux. As such, Linux containers cannot run natively on macOS. Therefore, the containers must run in a Linux virtual machine (VM), and a Podman client interacts with that VM. This is in line with all solutions for running containers on macOS.
The technology behind a Podman machine is:
- QEMU plus HVF acceleration: Runs a virtualized Linux distribution using native macOS virtualization
- Fedora CoreOS (FCOS): The virtualized Linux distribution
- Ignition: Configures the FCOS VM (similar to cloud-init)
- gvisor-tap-vsock: A proxy application that sets up port mapping on the host according to instructions from a custom Container Network Interface (CNI) plugin on the VM
- SSH: The Podman client securely communicates with the Linux VM using secure shell (SSH) keys
Understanding how all these components work together requires a more granular inspection. The first step is to make sure you have a Podman client on your host system. For example, you can do this on a Mac using Homebrew with
brew install podman. Once you've installed the client, issue
podman machine init to create a Linux VM for your containers.
I describe the init process in the illustration below. After you run the
init command (A), Podman checks for the latest version of FCOS, and if that version is not already local, it downloads it (B). Once the image is downloaded, the image is uncompressed, resized, and two relevant files are written: The machine description and the ignition file (C).
The machine description is a text file that describes the attributes of the VM that it will create. It is in JSON format and written to the host's filesystem. The ignition file, which ultimately is used to customize the FCOS operating system, is also written into the host's filesystem. Note that no VM is started or even created yet; just its description.
The next step is to issue the
podman machine start command. The start process describes the rest of any Podman machine internals, shown in the illustration below.
start subcommands runs, the machine configuration file is read in, and Podman then checks to ensure that this machine is not already running (D). Based on the configuration file, a
qemu command is assembled, and the then VM runs. The ignition file is injected into the VM during this first boot and then run in the boot process. Several configuration changes are made (E). Once the VM boots, an application called
gvproxy starts on the host operating system. The
gvproxy application manages port mapping between the host and VM; for example, "binding" a port for an HTTP application (F). And then finally, Podman socket-activated services are set up for privileged and unprivileged users (G).
[ Learn more about using auto-updates and rollbacks in Podman. ]
Understanding a Podman run
Once the VM is running, the Podman client on the host operating system is ready for use. The Podman client interacts with the socket-activated services on the host VM using SSH and SSH keys generated during
To see a typical flow of how Podman works with a started Podman machine, you can run a container that exposes ports. For example:
podman run -dt -p 8080:80 nginx
This command loosely translates to: Run a container based on the
nginx image with a
tty in detached mode and map the host port of
8080 to the container port of
80. When the host computer issues this command, the command is sent to the VM's socket through
If the image is not already in the user's local image storage, Podman pulls (fetches) the image from an image registry. The only notable difference between this scenario and the scenario where Podman is running entirely on the host is that the VM routes its traffic through the host system. Once the image is pulled successfully, the container runs on the VM. This step is not remarkably different from running everything on the host.
[ Get this free book from Red Hat and O'Reilly - Kubernetes operators: automating the container orchestration platform. ]
Finally, if the running container has port mappings, Podman inside the VM tells the host about them using a custom CNI plugin to initiate the communication. The plugin sends port information to the host, where
gvproxy then does the port mapping between the host and the VM/container. Using
gvproxy is entirely unique to the Podman machine scenario.
Here are answers to some of the questions we receive about specific details of our implementation.
Why did you use QEMU, given all the other options out there?
QEMU works on macOS and Linux. This allows us to cover two operating systems with a single technology.
How should I run Podman on Windows?
We recommend running Podman in Windows Subsystem for Linux (WSL), which Windows fully integrates. You can also use the remote client to connect to a Linux server with Podman.
What about accessing the service sockets directly from the host?
We are working on this.
Does that include the socket for Docker so that I can run
Does it work on Apple silicon too?
My company does not let me use Brew to install applications. What should I do?
We are working through alternative packaging. No timetable yet, but stay tuned.
Where is the graphical user interface (GUI)?
We have a strategy for a GUI and hope to begin work soon. Did you know you could use Cockpit as well?
I want a system tray or menu bar app for this.
We are working on this as well.
How do I update the operating system running in the VM?
The system tray or menu bar app will provide that functionality. In the meanwhile, you may do it manually by consulting how to update FCOS. You could also
rm your current machine and initialize a new one. If there is a more recent image available, it's downloaded. Removing a machine results in losing your containers.
I want to be able to bind mount content from the host into the Linux VM.
We are working on this as well. It's not tied to the GUI work, and we expect to deliver it in subsequent Podman releases.