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.2 Searching images in registries #
Using the podman search
command allow you to list available containers in the registries defined
in /etc/containers/registries.conf
.
To search in all registries:
podman search go
To search in a specific registry:
podman search registry.suse.com/go
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.