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
Digging deeper
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.
When the 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 machine init
.
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 ssh
.
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.
FAQs
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 docker-compose
?
Yes.
Does it work on Apple silicon too?
Yes.
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.
About the author
Brent Baude has been working in hardware and software engineering for 27 years as an employee of IBM and Red Hat. Of late, he has specialized in Containers. His current role is that of Podman Architect.
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Original shows
Entertaining stories from the makers and leaders in enterprise tech
Products
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Cloud services
- See all products
Tools
- Training and certification
- My account
- Customer support
- Developer resources
- Find a partner
- Red Hat Ecosystem Catalog
- Red Hat value calculator
- Documentation
Try, buy, & sell
Communicate
About Red Hat
We’re the world’s leading provider of enterprise open source solutions—including Linux, cloud, container, and Kubernetes. We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.
Select a language
Red Hat legal and privacy links
- About Red Hat
- Jobs
- Events
- Locations
- Contact Red Hat
- Red Hat Blog
- Diversity, equity, and inclusion
- Cool Stuff Store
- Red Hat Summit