Podman

From Gentoo Wiki
Jump to:navigation Jump to:search

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.

KERNEL Enable support for podman
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:

FILE /etc/modules-load.d/networking.confLoad tun module
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

FILE /etc/conf.d/podman
#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

Warning
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]:

FILE /etc/local.d/01-podman-rootless.start
#!/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.

FILE ~/.config/containers/containers.conf
[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:

FILE /etc/cni/net.d/88-macvlan.conflist
{
  "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:

FILE /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 Choosing a storage driver

See also

External resources

References