Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / Container Guide / Podman overview
Applies to Container Guide

6 Podman overview

Podman is short for Pod Manager Tool. It is a daemonless container engine for managing Open Container Initiative (OCI) containers on a Linux system, and it offers a drop-in alternative for Docker. Podman’s notable feature is out-of-the-box support for rootless containers offering a reduced attack surface when running containers. Podman can be used to create OCI-compliant container images using a Dockerfile and a range of commands identical to Docker Open Source Engine. For example, the podman build command performs the same task as docker build. In other words, Podman provides a drop-in replacement for Docker Open Source Engine.

Moving from Docker Open Source Engine to Podman does not require any changes in the established workflow. There is no need to rebuild images, and you can use the exact same commands to build and manage images as well as run and control containers.

Podman differs from Docker Open Source Engine the following ways:

  • Podman does not use a daemon, so the container engine interacts directly with an image registry, containers, and an image storage when needed.

  • Podman features native systemd integration: Allowing to control containers via systemd units which can be created for existing containers as well as generate units that can start containers if they do not exist in the system. Moreover, Podman can run systemd inside containers.

  • Podman does not require root privileges to create and run containers. This means that Podman can run in under the root user as well as in an unprivileged environment. Moreover, a container created by an unprivileged user cannot get higher privileges on the host than the container’s creator.

  • Podman can be configured to search multiple registries by reading /etc/containers/registries.conf file.

  • Podman can deploy applications from Kubernetes manifests

  • Podman supports launching systemd inside a container and requires no potentially dangerous workarounds.

Last but not least, Podman enables you to organize your containers into pods. Pods share the same network interface. A typical use case for organizing a group of containers into a pod is a container that runs a database and a container with a client that accesses the database. For further information about pods, refer to Section 13.2, “Single Container Host with Podman”.

6.1 Podman installation

To install Podman, make sure you have the SLE Containers Module enabled (see Section 5.1, “SLE Containers Module”), run the command sudo zypper in podman. Then run podman info to check whether Podman has been installed successfully.

Podman will by default try to launch containers as the current user. For unprivileged users that implies launching containers in rootless mode. Support for rootless containers is enabled for all newly created users in SLE by default and no additional steps are necessary.

In case Podman fails to launch containers in rootless mode, check whether the an entry for the current user is present in /etc/subuid:

 ❯ grep $(id -nu) /etc/subuid
user:10000:65536

When no entry is found, add the required sub-UID and sub-GID entries via the following command:

> sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(id -nu)

To enable the change, reboot the machine or stop the session of the current user. To do the latter, run loginctl list-sessions | grep USER and note the session ID. Then run loginctl kill-session SESSION_ID to stop the session.

The usermod command above defines a range of local UIDs to which the UIDs allocated to users inside the container are mapped on the host. Note that the ranges defined for different users must not overlap. It is also important that the ranges do not reuse the UID of an existing local user or group. By default, adding a user with the useradd command on SLES 15 SP4 automatically allocates sub-UID and sub-GID ranges.

When using rootless containers with Podman, it is recommended to use cgroups v2. cgroups v1 are limited in terms of functionality compared to v2. For example cgroups v1 allow every user to modify all existing control groups, and not just their own. Additionally, Podman is unable to read container logs properly with cgroups v1 and the systemd log driver. To enable cgroups v2, add the following to the kernel cmdline: systemd.unified_cgroup_hierarchy=1

Running a container with Podman in rootless mode on SLES may fail, because the container needs read access to the SCC credentials. For example, running a container with the command podman run -it --rm registry.suse.com/suse/sle15 bash and then executing zypper ref results in the following error message:

Refreshing service 'container-suseconnect-zypp'.
Problem retrieving the repository index file for service 'container-suseconnect-zypp':
[container-suseconnect-zypp|file:/usr/lib/zypp/plugins/services/container-suseconnect-zypp]
Warning: Skipping service 'container-suseconnect-zypp' because of the above error.
Warning: There are no enabled repositories defined.
Use 'zypper addrepo' or 'zypper modifyrepo' commands to add or enable repositories

To solve the problem, grant the current user the required access rights by running the following command on the host:

> sudo setfacl -m u:$(id -nu):r /etc/zypp/credentials.d/*

Log out and log in again to apply the changes.

To give multiple users the required access, create a dedicated group using the groupadd GROUPNAME command. Then use the following command to change the group ownership and rights of files in the /etc/zypp/credentials.d/ directory.

> sudo chgrp GROUPNAME /etc/zypp/credentials.d/*
> sudo chmod g+r /etc/zypp/credentials.d/*

You can then grant a specific user write access by adding them to the created group.

6.1.1 Tips and tricks for rootless containers

Podman remaps user IDs with rootless containers. In the following example, Podman remaps the current user to the default user in the container:

❯ podman run --rm -it registry.suse.com/bci/bci-base id
uid=0(root) gid=0(root) groups=0(root)

Note that even if you are root in the container, you cannot gain superuser privileges outside of it.

This user remapping can have undesired side effects when sharing data with the host, where the shared files belong to different user IDs in the container and on the host. The issue can be solved using the the command line flag --userns=keep-id that makes it possible to keep the current user id in the container:

❯ podman run --userns=keep-id --rm -it registry.suse.com/bci/bci-base id
uid=1000(user) gid=1000(users) groups=1000(users)

The flag --userns=keep-id has a similar effect when used with bind mounts:

 ❯ podman run --rm -it -v $(pwd):/share/ registry.suse.com/bci/bci-base stat /share/
  File: /share/
  Size: 318             Blocks: 0          IO Block: 4096   directory
Device: 2ch/44d Inode: 3506170     Links: 1
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-05-03 12:52:18.636392618 +0000
Modify: 2023-05-03 12:52:17.178380923 +0000
Change: 2023-05-03 12:52:17.178380923 +0000
 Birth: 2023-05-03 12:52:15.852370288 +0000

 ❯ podman run --userns=keep-id --rm -it -v $(pwd):/share/ registry.suse.com/bci/bci-base stat /share/
  File: /share/
  Size: 318             Blocks: 0          IO Block: 4096   directory
Device: 2ch/44d Inode: 3506170     Links: 1
Access: (0755/drwxr-xr-x)  Uid: ( 1000/     user)   Gid: ( 1000/     users)
Access: 2023-05-03 12:52:18.636392618 +0000
Modify: 2023-05-03 12:52:17.178380923 +0000
Change: 2023-05-03 12:52:17.178380923 +0000
 Birth: 2023-05-03 12:52:15.852370288 +0000

Podman stores the containers' data in the storage graph root (default is ~/.local/share/containers/storage). Because of the way Podman remaps user IDs in rootless containers, the graph root may contain files that are not owned by your current user but by a user ID in the sub-UID region assigned to your user. As these files do not belong to your current user, they can be inaccessible to you.

To read or modify any file in the graph root, enter a shell as follows:

 ❯ podman unshare bash

 ❯ id
uid=0(root) gid=0(root) groups=0(root),65534(nobody)

Note that podman unshare performs the same user remapping as podman run does when launching a rootless container. You cannot gain elevated privileges via podman unshare.

Refrain from modifying files in the graph root as this can corrupt Podman’s internal state and render your containers, images and volumes inoperable.

6.1.2 Caveats of rootless containers

Because unprivileged users cannot configure network namespaces on Linux, Podman relies on a userspace network implementation called slirp4netns. It emulates the full TCP-IP stack and can cause a heavy performance degradation for workloads relying on high network transfer rates. This means that rootless containers suffer from slow network transfers.

On Linux, unprivileged users cannot open ports below port number 1024. This limitation also applies to Podman, so by default, rootless containers cannot expose ports below port number 1024. You can remove this limitation using the following command:

sysctl net.ipv4.ip_unprivileged_port_start=0

or make it persistent via:

sysctl -w net.ipv4.ip_unprivileged_port_start=0

Note that this allows all unprivileged applications to bind to ports below 1024.

6.1.3 Podman-docker

Since Podman is compatible with Docker Open Source Engine, it features the same command-line interface. You can also install the package podman-docker that allows you to use an emulated docker CLI with podman. For example, the docker pull command, that fetches a container image from a registry, executes podman pull instead. The docker build command executes podman build, etc.

Podman also features a Docker Open Source Engine compatible socket that can be launched via:

 ❯ sudo systemctl start podman.socket

The Podman socket can be used by applications designed to communicate with Docker Open Source Engine to launch containers transparently via Podman. The Podman socket can be used to launch containers via docker compose, without running Docker Open Source Engine.

6.2 Obtaining container images

6.2.1 Configuring container registries

One of the advantages of Podman over Docker Open Source Engine is that Podman can be configured to search multiple container registries. To make Podman search the SUSE Registry first and use Docker Hub as a fallback, add the following configuration to the /etc/containers/registries.conf file:

unqualified-search-registries = ["registry.suse.com", "docker.io"]

Note that this step can be skipped on SLE or openSUSE. On both distributions, SUSE Registry and registry.opensuse.org have priority over Docker Hub.

6.2.3 Downloading (pulling) images

The podman pull command pulls an image from an image registry:

# podman pull <registry>[:<port>]/[<namespace>/]<name>:<tag>

For instance

# podman pull registry.suse.com/bci/bci-base

Note that if you do not specify a tag, the tag latest will be used.

6.3 Renaming images and images tag

One can freely tag images, i.e set a custom name, it’s mostly used for setting a more intuitive name or to identify specific images.

Pulling the bci-base image from registry.suse.com:

localhost:~ # podman pull registry.suse.com/bci/bci-base
Trying to pull registry.suse.com/bci/bci-base:latest...
Getting image source signatures
Copying blob bf6ca87723f2 done
Copying config 34578a383c done
Writing manifest to image destination
Storing signatures
34578a383c7b6fdcb85f90fbad59b7e7a16071cf47843688e90fe20ff64a684

List our pulled images:

localhost:~ # podman images
REPOSITORY                      TAG         IMAGE ID      CREATED        SIZE
registry.suse.com/bci/bci-base  latest      34578a383c7b  22 hours ago   122 MB

Rename the bci-base image to my-base:

podman tag 34578a383c7b my-base
podman images
REPOSITORY                      TAG         IMAGE ID      CREATED        SIZE
registry.suse.com/bci/bci-base  latest      34578a383c7b  22 hours ago   122 MB
localhost/my-base               latest      34578a383c7b  22 hours ago   122 MB

Add a custom tag to my-base, let’s say this is version 1 of my image

podman tag 34578a383c7b my-base:1
podman images
REPOSITORY                      TAG         IMAGE ID      CREATED        SIZE
registry.suse.com/bci/bci-base  latest      34578a383c7b  22 hours ago   122 MB
localhost/my-base               latest      34578a383c7b  22 hours ago   122 MB
localhost/my-base               1           34578a383c7b  22 hours ago   122 MB

Note that the default tag latest is still present.

6.4 Running images

Similar to Docker Open Source Engine, Podman can run containers in an interactive mode, allowing you to inspect and work with an image. To run suse/sle15 in interactive mode, use the following command:

> podman run --rm -ti suse/sle15

6.5 Building images with Podman

Podman can build images from a Dockerfile. The podman build command behaves as docker build, and it accepts the same options.

Podman’s companion tool Buildah provides an alternative way to build images. For further information about Buildah, refer to Chapter 14, Buildah overview.