Unleashing the Power of Podman: A Docker Alternative

Posted by Andrew Denner on November 21, 2024 · 15 mins read

Unleashing the Power of Podman: A Docker Alternative

By Andrew Denner

Senior Software Developer and President of the Central Iowa Linux User’s Group


Introduction

Welcome to an exploration of Podman, a powerful and versatile containerization tool that serves as a compelling alternative to Docker. As Linux users and enthusiasts, we are always on the lookout for tools that enhance our workflows, improve security, and offer flexibility. Podman does just that, and in this blog post, we’ll delve deep into its functionalities, compare it with Docker, and explore how it integrates with tools like Kubernetes, Docker Compose, and systemd.

About the Author

I’ve been a Linux user since 2003, navigating through various distributions from Gentoo to CentOS and currently favoring Ubuntu for its convenience. As a Senior Software Developer and the President of the Central Iowa Linux User’s Group (CIALUG), I have a passion for exploring new technologies and sharing knowledge with the community.


Revisiting the Open Container Initiative Universe

Before we dive into Podman, let’s briefly revisit the Open Container Initiative (OCI). The OCI is an open governance structure formed under the Linux Foundation for the express purpose of creating open industry standards around container formats and runtimes. Docker was instrumental in starting this initiative, which aims to standardize container technology and promote interoperability among different tools.


From Docker to Podman: Understanding the Landscape

What is Docker?

Docker revolutionized containerization by bundling together various Linux kernel features such as namespaces, control groups, and network devices, making it easier to create, deploy, and run applications using containers. However, Docker operates as a client-server application, running a daemon (dockerd) as root by default. This design has raised security concerns because if the Docker daemon is compromised, it could potentially lead to root access on the host system.

Introducing Podman

Podman (the POD Manager) addresses some of these security concerns by offering a daemonless and rootless containerization approach. Developed by Red Hat, Podman allows users to manage containers without the need for a background service or root privileges. It directly interacts with the runC container runtime, which is part of the OCI specifications.


Architecture and Security: Podman vs. Docker

Podman’s Rootless Architecture

One of the key differences between Podman and Docker is Podman’s ability to run in rootless mode. This means that containers can be run and managed by non-root users without granting them elevated permissions. In rootless mode, Podman uses user namespaces to map container UIDs and GIDs to unprivileged host UIDs and GIDs. For instance, the root user inside the container (UID 0) might correspond to an unprivileged user on the host system (e.g., UID 100000).

Benefits of Rootless Containers

  • Enhanced Security: Reduces the risk of privilege escalation attacks.
  • User Isolation: Each user’s containers are isolated from others.
  • No Daemon Required: Eliminates the need for a root-running daemon process.

Docker’s Daemon-Based Design

Docker relies on a daemon that runs with root privileges. While Docker supports rootless mode starting from version 20.10, it still traditionally depends on the daemon process. This architecture can pose security risks because any vulnerability in the Docker daemon could potentially be exploited to gain root access on the host system.


Hands-On with Podman

Installing Podman

Podman is available for various Linux distributions, including Fedora, CentOS, Ubuntu, and Debian. Here’s how to install it on Ubuntu/Debian-based systems:

sudo apt update
sudo apt install podman

For other systems or more detailed instructions, refer to the Podman installation guide.

Running Your First Podman Container

Let’s start by running a simple hello-world container:

podman run --rm hello-world

This command pulls the hello-world image from a container registry and runs it. The --rm flag tells Podman to remove the container after it exits.

Aliasing Docker Commands to Podman

Podman is designed to be a drop-in replacement for Docker. You can create an alias or install a compatibility layer:

sudo apt install podman-docker

Now, you can use Docker commands, and they will be executed by Podman:

docker run --rm hello-world

Running Containers Rootless

To illustrate the security features, let’s attempt to mount a host directory into a container:

podman run --rm -it -v /etc:/host-etc ubuntu bash

Inside the container, try creating a file in /host-etc:

touch /host-etc/testfile

You will receive a permission denied error because the container doesn’t have the necessary privileges, demonstrating Podman’s rootless security model.

Exposing Ports and Networking

When running rootless, binding to ports below 1024 requires additional configuration. However, you can expose higher ports without issues:

podman run -p 8080:80 nginx

This command runs an Nginx server inside a container and maps port 80 inside the container to port 8080 on the host.

Binding to Privileged Ports

To bind to ports below 1024, you can use network capabilities or run Podman with elevated privileges (not recommended for general use):

sudo podman run -p 80:80 nginx

Integrating with Kubernetes: Podman Play Kube

Running Kubernetes Pods with Podman

Podman can run Kubernetes YAML files directly using the play kube command. This allows you to test and develop Kubernetes applications locally without setting up a full Kubernetes cluster.

Example: Deploying a WordPress Application

Create a wordpress.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: wordpress-pod
spec:
  containers:
  - name: wordpress
    image: wordpress
    ports:
    - containerPort: 80
      hostPort: 8080
  - name: mysql
    image: mysql:5.7
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: examplepassword
    - name: MYSQL_DATABASE
      value: wordpress

Run the pod using Podman:

podman play kube wordpress.yaml

This command will create and start the containers defined in the YAML file.

Managing Pods

List running pods:

podman pod ps

Stop a pod:

podman pod stop wordpress-pod

Remove a pod:

podman pod rm wordpress-pod

Podman and Docker Compose Compatibility

Using Docker Compose Files with Podman

Podman supports Docker Compose files via the podman-compose tool. This allows you to run setups defined in docker-compose.yaml files without modification.

Installing Podman-Compose

Podman-Compose can be installed using pip:

pip install podman-compose

Alternatively, it may be available in your distribution’s repositories.

Running a Docker Compose Setup

Given a docker-compose.yaml file, you can start your services with:

podman-compose up

Example: Running a Multi-Container Application

Suppose you have a docker-compose.yaml file for a web application with multiple services (e.g., frontend, backend, database). Podman-Compose will parse this file and create the necessary pods and containers.

Caveats and Compatibility

While Podman-Compose aims to be compatible with Docker Compose, there may be some differences and limitations. Be sure to test your setup thoroughly.


Podman and systemd Integration

Managing Containers with systemd

Podman can generate systemd unit files that enable you to manage containers as system services. This is particularly useful for services that need to start automatically on boot or require supervision.

Generating systemd Unit Files

Start by creating and running a container:

podman run -d --name mywebapp -p 8080:80 nginx

Generate the systemd unit file:

podman generate systemd --name mywebapp --files --new

This command creates a container-mywebapp.service file.

Deploying the Unit File

Copy the service file to the systemd directory:

sudo cp container-mywebapp.service /etc/systemd/system/

Reload systemd to recognize the new service:

sudo systemctl daemon-reload

Enable and start the service:

sudo systemctl enable container-mywebapp
sudo systemctl start container-mywebapp

Now, your container will start automatically on boot and can be managed using systemctl commands.


Security Enhancements with SELinux

Understanding SELinux

Security-Enhanced Linux (SELinux) is a security architecture integrated into the Linux kernel that provides mandatory access control (MAC). It was developed by the NSA and released to the open-source community. SELinux helps to enforce security policies that limit what resources users and processes can access.

Podman and SELinux Labels

When running containers on an SELinux-enabled system, you may encounter permission issues due to the strict access controls. Podman can handle SELinux contexts using the --security-opt flag and volume options.

Mounting Volumes with Correct Labels

When mounting volumes, use the :z or :Z options to modify the SELinux labels:

  • :z – shared content among multiple containers.
  • :Z – private content for the container.

Example:

podman run -v /mydata:/data:Z myimage

Inspecting Security Contexts

You can inspect a container’s security context using:

podman inspect --format '\{\{\.ProcessLabel\}\}' mycontainer

Practical Examples and Use Cases

Running a Development Environment

Podman is excellent for setting up development environments without installing all dependencies on your host system. For example, you can run a container with Node.js and mount your project directory:

podman run --rm -it -v "$(pwd)":/app -w /app node:14 bash

Building Container Images

Podman can build images from a Dockerfile using the build command:

podman build -t myimage .

This uses the same syntax and process as Docker, ensuring compatibility.


Addressing Common Issues and Rough Edges

SELinux Troubles

If you encounter issues where a container cannot access mounted volumes, it’s likely due to SELinux contexts. Ensure you use the correct volume mount options (:Z or :z).

Networking Limitations

Running rootless containers may have networking limitations, such as binding to privileged ports or interacting with certain network interfaces. You may need additional configuration or to run the container as root in these cases.

Podman on Non-Linux Systems

While Podman is designed for Linux, there are ways to run it on macOS and Windows, typically via virtualization or compatibility layers. The experience may not be as seamless as Docker Desktop, but solutions like Podman Machine can help.


Conclusion

Podman offers a robust, secure, and flexible alternative to Docker, particularly appealing for users and organizations concerned with security and looking for a daemonless containerization solution. Its compatibility with Docker commands and integration with tools like Kubernetes, Docker Compose, and systemd make it a powerful tool in the container ecosystem.

While there may be some rough edges and a learning curve, especially when dealing with SELinux and rootless configurations, the benefits in security and flexibility are well worth the effort.


Additional Resources


About the Central Iowa Linux User’s Group

The Central Iowa Linux User’s Group (CIALUG) meets on the third Wednesday of each month at 7 PM. We welcome Linux enthusiasts of all levels to join us for discussions, presentations, and networking. Visit cialug.org for more information and meeting details.


Connect with me on social media and visit my blog at denner.co for more insights into Linux, containerization, and open-source technologies.


By embracing tools like Podman, we continue to advance the open-source ecosystem, promoting security, flexibility, and innovation. Happy containerizing!


This post is created from a presentation I originally gave to the St Louis Linux Users Group My slide deck and Video