Podman
podman is a daemonless container engine for developing, managing, and running OCI Containers on Linux, aiming to be a drop-in replacement for Docker.
For most user applications running Docker images, setting alias docker=podman
should be enough for most pipelines to switch to podman.
There are several tools to provide the parts of the Docker stack not directly provided by Podman, such as buildah for building images and and skopeo for distributing them[1].
Installation
Kernel
The runc upstream provides a method of listing required kernel configuration via check-config.sh script, but note that some of the config options from the check-config.sh
script are deprecated and will be safe to ignore.
Rootless mode
Configure the kernel
user_namespaces(7) have to be enabled in order to use rootless mode. Many Docker images make use of FUSE and overlayfs, which also need to be enabled. The tun
kernel module also needs to be available and loaded for rootless mode to access networking.
General setup --->
-*- Namespaces support --->
[*] User namespace
File systems --->
<*> FUSE (Filesystem in Userspace) support
<*> Overlay filesystem support
Device Drivers --->
-*- Network device support --->
-*- Network core driver support --->
<*/M> Universal TUN/TAP device driver support
Load required modules
If the tun
module is not built into the kernel, it needs to be loaded manually:
tun
Configure subuid/subgid
podman requires the user to have a range of UIDs listed in /etc/subuid and /etc/subgid files. These UIDs are used for mapping the container UIDs to the host UIDs via user namespaces.
Refer to the Subuid subgid page for further information.
USE flags
USE flags for app-containers/podman A tool for managing OCI containers and pods with Docker-compatible CLI
+seccomp
|
Enable seccomp (secure computing mode) to perform system call filtering at runtime to increase security of programs |
apparmor
|
Enable support for the AppArmor application security system |
btrfs
|
Enables btrfs support (graph driver) in Podman |
selinux
|
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur |
systemd
|
Enable use of systemd-specific libraries and features like socket activation or session tracking |
wrapper
|
Install wrapper which lets use podman for command `docker` |
Emerge
It is recommended to use app-containers/crun as the OCI runtime provider, bug #723080.
root #
emerge --ask --oneshot app-containers/crun app-containers/podman
root #
emerge --ask app-containers/podman
Configuration
Files
- /etc/containers/registries.conf - specifies which container registries should be searched for images (see /etc/containers/registries.conf.example for example defaults)
- /etc/containers/policy.json - defines policies for image validation (see /etc/containers/policy.json.example for example defaults)
- /etc/conf.d/podman - configuration file for the podman OpenRC service
Example: specify the TCP socket for the API service daemon
#SOCKET="unix:///run/podman/podman.sock"
SOCKET="tcp://localhost:12979" # this port is an example, choose whatever you want
Usage
The podman tool aims to be a drop-in replacement for docker client provided by Docker. For example, docker run becomes podman run and docker build becomes podman build.
All Container Pod-related actions are accessible via podman pod command.
Managing and using images
Here are some basic usage examples. Detailed information can be found in the podman-search(1), podman-pull(1), podman-images(1). and podman-run(1) man pages.
Search for available images
To search for available images, use podman search:
user $
podman search gentoo
NAME DESCRIPTION docker.io/osuosl/gentoo docker.io/osuosl/gentoo-ppc64le docker.io/osuosl/gentoo-i686 docker.io/centerforopenneuroscience/opfvta Gentoo based container for a reproducible an... docker.io/gentoo/stage3 Official Gentoo stage3 images. docker.io/gentoo/portage Official Gentoo Portage snapshot. Designed t... ...
Download an image
To download an image, use podman pull:
user $
podman pull docker.io/gentoo/stage3
Trying to pull docker.io/gentoo/stage3:latest... Getting image source signatures Copying blob 93476f02ccbb done | Copying config eb88956325 done | Writing manifest to image destination eb8895632523167a51c60f247fbce008ca99bd54924c26f3ec3371c20524d88c
List local images
To list images available locally, run podman images:
user $
podman images
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/gentoo/stage3 latest eb8895632523 3 days ago 1.34 GB
Run command in a temporary container
To use an image to interactively run a command in a new container, removing that container once it's exited:
user $
podman run --interactive --tty --rm docker.io/gentoo/stage3:latest /usr/bin/bash
The --interactive
and --tty
options can be abbreviated as -i
and -t
, respectively.
Managing and using containers
All existing containers, running or not, can be listed via podman container:
user $
podman container list -a
Without the -a
option, only running containers will be listed.
Containers can be created, but not started, by using the create; subcommand if a name is not supplied, a name will be generated automatically.
user $
podman create --interactive --tty --name gentoo-bash docker.io/gentoo/stage3:latest /usr/bin/bash
Containers can be started, restarted and stopped via the start, restart and stop subcommands, e.g.:
user $
podman start gentoo-bash
Running containers can be listed via the ps subcommand:
user $
podman ps
Adding the -a
option will list all containers, running or not.
A container can be deleted via the rm subcommand:
user $
podman rm gentoo-bash
Detailed information can be found in the podman-container(1), podman-create(1), podman-start(1), podman-ps(1), and podman-rm(1) man pages.
Example: A systemd container for the root user on an OpenRC system
Create a container named "gentoo-systemd", fetching the base image if necessary, that will run that image's init command:
root #
podman create --interactive --tty --name gentoo-systemd docker.io/gentoo/stage3:systemd /usr/sbin/init
Set the password for the root user by mounting the container's root filesystem and using passwd(1) to change it:
root #
podman mount gentoo-systemd
root #
passwd -R [mount directory]
root #
podman unmount gentoo-systemd
Start the container and immediately attach to it:
root #
podman start --attach gentoo-systemd
This should result in a boot sequence and a login prompt. Once logged in, confirm that systemd is PID 1 by running systemctl status.
Rootless containers under OpenRC
The following configuration might have security issues, as described in Talk:Podman.
On systemd-based systems, Podman uses systemd slices to allow Podman to run rootless, i.e. as a non-privileged user.
On OpenRC-based systems, some extra configuration is required, and an extra option needs to be added to the podman start
command line.
Create a new group, cgroup
:
root #
groupadd cgroup
Add the non-privileged user to this group:
root #
usermod -aG cgroup larry
As root, create a file in /etc/local.d called e.g. 01-podman-rootless.start - modifying the leading number if that number is already in use - with the following contents[2]:
#!/bin/sh
# Allow users in the 'cgroup' group to use Podman containers rootless.
mount --make-rshared /
chown root:cgroup /sys/fs/cgroup
chmod 775 /sys/fs/cgroup
chown root:cgroup /sys/fs/cgroup/cgroup.{procs,subtree_control,threads}
chmod 664 /sys/fs/cgroup/cgroup.{procs,subtree_control,threads}
Make that file executable by root:
root #
chmod 744 /etc/local.d/01-podman-rootless.start
Reboot the system.
After logging in as the non-privileged user, run the groups(1) command to confirm that the user is in the cgroup
group.
The user should then be able to run containers by adding the --cgroup-manager=cgroupfs
option to the podman start
command line:
user $
podman --cgroup-manager=cgroupfs start --attach gentoo-systemd
Nvidia in rootless containers
The nvidia-container-toolkit::guru package is available in the GURU repository. The repository can be enabled with the help of app-eselect/eselect-repository utility; refer to the eselect/repository page for information about how to enable and sync a repository.
Once the guru repository is set up, install the package:
root #
emerge --ask app-containers/nvidia-container-toolkit
Generate the CDI specification file.
root #
nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
Enable sharing user groups inside containers in user configuration file.
[containers]
annotations=["run.oci.keep_original_groups=1",]
Exposing containers to local network
By default, podman works in bridge mode, with a separate cni-podman0 bridge; requests are translated to the local network via NAT. However, the root user can give pods/containers real IP addresses on the local network using macvlan mode.
First enable and start the cni-dhcp daemon:
root #
rc-update add cni-dhcp default
root #
rc-service cni-dhcp start
Add a new network configuration for podman to support macvlan networks:
{
"cniVersion": "0.4.0",
"name": "macvlan",
"plugins": [
{
"type": "macvlan",
"master": "br0",
"isGateway": true,
"ipam": {
"type": "dhcp"
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
},
{
"type": "firewall"
},
{
"type": "tuning"
}
]
}
The above assumes there is an externally configured bridge br0 already in existence; an example of such a configuration is available on the Network bridge page. It is also possible to use an existing Ethernet device (e.g. enp5s0f0) and attach to it.
Now create a pod with the newly-configured network:
root #
podman pod create --name homeserver --network macvlan
To validate that the pod has the proper configuration, an Alpine test container can be run inside the pod:
root #
podman run -dt --pod homeserver --name alpine_test docker.io/library/alpine:latest top
root #
podman exec alpine_test ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host proto kernel_lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 3A:09:C6:B8:7F:DB brd ff:ff:ff:ff:ff:ff inet 192.168.2.121/24 brd 192.168.2.255 scope global dynamic noprefixroute enp5s0 valid_lft 85793sec preferred_lft 74993sec inet6 fe80::ab3d:b093:a223:776a/64 scope link noprefixroute valid_lft forever preferred_lft forever inet6 fe80::8c32:bb30:5827:8c34/64 scope link valid_lft forever preferred_lft forever
Troubleshooting
Not enough namespaces
If running a container results in the message:
error creating libpod runtime: there might not be enough IDs available in the namespace
then increase the number of user namespaces via the relevant kernel parameter, either temporarily via sysctl(8):
root #
sysctl user.max_user_namespaces=15076
or permanently via a line in /etc/sysctl.d/local.conf:
user.max_user_namespaces=15076
Slow storage in the rootless mode
Check the used storage driver:
user $
podman info
If the reported storage driver is vfs
, you might want to switch to a faster overlayfs
.
See also
- Docker — a container-based virtualization system
- Virtualization — the concept and technique that permits running software in an environment separate from a computer operating system.
External resources
- podman(1)
- podman-create(1)
- podman-container(1)
- podman-images(1)
- podman-mount(1)
- podman-ps(1)
- podman-pull(1)
- podman-restart(1)
- podman-rm(1)
- podman-run(1)
- podman-search(1)
- podman-start(1)
- podman-stop(1)
- podman-unmount(1)
References
- ↑ A Comprehensive Container Runtime Comparison, Retrieved on January 18, 2021
- ↑ Linux kernel user's and administrator's guide: "Control Group v2" / "Delegation"