Image
![IT Automation ebook](/sysadmin/sites/default/files/styles/image_cta/public/2021-07/SysAdminGuidetoITAutomation-e-book-medium.jpg?itok=8_5VlQhF)
In previous articles, my containers team colleagues Dan Walsh and Brent Baude shared some cool Podman features to try, including flags to modify how to run containers and various Podman commands to simplify how users interact with containers.
Now it's my turn to highlight features that can be useful when automating Podman and its containers and pods. If you're hungry for some more exclusive and surprisingly useful Podman features, please read on.
Podman's fork-exec architecture makes running containers with systemd as simple as writing a unit file. This allows systemd to manage the container as a service, which can be useful for containers that you want to automatically start on system boot or restart if the container fails.
[ Download the systemd commands cheat sheet. ]
For example, create a containerized webserver:
$ podman run -d --name myserver -p 8000:80 nginx
F1daddc385d7a3cf8ac57ef12e7bfe7825ee96c8bc5abdf8f2439db6c3c916a2
It's probably a good idea to ensure the web server is always up and running because little is more frustrating than trying to reach a web page that is down. Therefore, running this container as a systemd service is a good idea because systemd can detect if the Podman process exits and automatically restart the container.
To do this, you need to create a systemd unit file and make systemd aware of it. The command podman generate systemd
automatically creates the unit file from the existing container:
$ mkdir -p ~/.config/systemd/user/
$ podman generate systemd --new myserver > ~/.config/systemd/user/myserver.service
Restart the systemd daemon and start the container using systemd:
$ systemctl --user daemon-reload
$ systemctl --user start myserver.service
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7444bcf61e17 docker.io/library/nginx:latest nginx -g daemon o... 4 seconds ago Up 5 seconds ago 0.0.0.0:8000->80/tcp myserver
If the containerized webserver fails, systemd will automatically restart the container. Note that the default restart policy for podman generate systemd
is "on failure," but you can easily adjust it using the --restart-policy
flag. The podman generate systemd
command is not limited to containers; it can also create unit files for pods.
Starting with Podman v4.2, you can also run Kubernetes workloads in systemd with Podman.
The podman top
command displays information about a container's running processes. By default, running podman top
outputs data similar to running ps -ef
inside the container:
$ podman top myserver
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
root 1 0 0.000 5.244439467s ? 0s nginx: master process nginx -g daemon off;
nginx 26 1 0.000 5.244536883s ? 0s nginx: worker process
The podman top
command also takes format descriptors. Podman supports all AIX format descriptors for ps
. For example, display the PID, User, and %CPU information:
$ podman top myserver %p %U %C
PID USER %CPU
1 root 0.000
26 nginx 0.000
Podman implements additional format descriptors that are more useful in a container context. These are host format descriptors that describe information on the process running inside the container from the host's perspective. For example, the hpid
and hgroup
format descriptors show the PID and the process' group on the host:
$ podman top myserver user pid hpid group hgroup
USER PID HPID GROUP HGROUP
root 1 2016 root 1000
nginx 26 2042 nginx 100100
Other host format descriptors include different permissions such as SELinux labels, seccomp policy, and permitted capabilities:
$ podman top myserver user pid label seccomp capprm
USER PID LABEL SECCOMP PERMITTED CAPS
root 1 system_u:system_r:container_t:s0:c270,c795 filter CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT
nginx 26 system_u:system_r:container_t:s0:c270,c795 filter none
Host format descriptors are especially useful when trying to debug a container from the host's perspective because they give insight into how the processes in the container are set up and behave.
[ Download now: Podman basics cheat sheet. ]
Often, container images on registries will be updated due to a newer release or a simple rebuild. If a container runs a certain image, it might be useful to have the most recent build of the image running. Auto-update allows Podman to keep containers current by pulling newer versions of images and restarting containers automatically as needed. The auto-update function is available only for containers run by systemd unit files.
Auto-update can be demonstrated by intentionally pulling an older version of the Fedora image and tagging it as fedora:latest
:
$ podman pull fedora:35
$ podman tag fedora:35 registry.fedoraproject.org/fedora:36
Now, create a container with auto-update enabled and use the "outdated" Fedora image. To do this, you need to label the container to auto-update when the registry has a newer image:
$ podman create --name mycontainer --label io.containers.autoupdate=registry registry.fedoraproject.org/fedora:36 sleep infinity
3c7bd3d4f0c9fa315a071e8cdc2f85c529d6455e2acfb5f8a06752669eb84713
Because auto-update works only with containers managed with systemd, you need to use the podman generate systemd
command to create a unit file:
$ mkdir -p ~/.config/systemd/user/
$ mkdir -p ~/.config/systemd/user/
$ podman generate systemd --new mycontainer > ~/.config/systemd/user/mycontainer.service
$ systemctl --user daemon-reload
$ systemctl --user start mycontainer.service
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb84d78f375c registry.fedoraproject.org/fedora:36 sleep infinity 2 seconds ago Up 2 seconds ago mycontainer
Now, if you run podman auto-update
, Podman will detect that the local image is outdated, pull the latest version from the registry, and restart the systemd service:
$ podman auto-update
Trying to pull registry.fedoraproject.org/fedora:36...
Getting image source signatures
Copying blob 878a8677dead skipped: already exists
Copying config 307241a058 done
Writing manifest to image destination
Storing signatures
UNIT CONTAINER IMAGE POLICY UPDATED
mycontainer.service bb84d78f375c (mycontainer) registry.fedoraproject.org/fedora:36 registry true
Most Linux distributions ship Podman with an auto-update systemd timer and an auto-update service. This configuration allows you to set time and event triggers for auto-updates, so you do not have to run the podman auto-update
command manually. For a more in-depth view of auto-update, please see How to use auto-updates and rollbacks in Podman.
Automatically updating containers is convenient for containers that need to be on the latest version of an image. However, some users may want to decide when (and if) they want to pull images when running containers or building images. Podman's run
, create
, and build
commands have a --pull
flag that allows you to specify when to pull images from remote registries. By default, the pull policy is set to "missing," which means that Podman will pull an image if it does not exist in local storage.
The -–pull
command-line option has three valid values: always
, missing
, and never
. When pull is set to always
, Podman will always attempt to pull an image and fail if the image cannot be pulled—even if the image already exists in local storage. The missing
value implies Podman will pull only if the image does not exist already in local storage. And for the most stability, you can use never
. This value ensures Podman will never pull from a registry and will only use images found in your local storage.
$ podman build --pull=never .
STEP 1/2: FROM alpine
Error: error creating build container: alpine: image not known
Podman's REST API is well-loved and powerful for managing containers. If you have read the API documentation, you've seen there are a bunch of sections with the compat label. Initially, it may look like there are duplicate endpoints but with some differences in parameters and body schemas.
[ Getting started with containers? Check out this no-cost course: Deploying containerized applications: A technical overview. ]
Podman's API actually comes in two flavors: libpod and docker-compat. When writing our REST API, we realized that Podman has many features that Docker does not have, including pod management, manifest actions, and a bunch of extra options for container, image, network, and volume management.
At the same time, we want our API to be compatible with Docker's API because many applications already use the Docker API, and many developers have existing scripts designed for Docker API. So, we did just that: Our compat API is nearly identical to Docker's API, which means you can run almost any script or application against Podman's compat API for easy migration!
And if you want to take advantage of powerful and exclusive Podman features, the libpod API is the place to go. Even better, both sets of API endpoints can be used at the same time.
Podman is chock full of cool and interesting features that extend beyond just building and running containers. These five Podman features come in handy when automating tasks with Podman.
The podman generate systemd
command makes writing unit files painless, and auto-update
ensures that your image is always, well, up-to-date. The podman top
format descriptors make it easy to debug and monitor processes inside the container, especially using host options. The --pull=never
flag guarantees stability in which image is used when running or building containers. Finally, the dual-mode API allows users to migrate to Podman and take advantage of Podman's more unique features.
These commands, flags, and API flavors simplify and help automate day-to-day container workflows.
Ashley Cui is a software engineer at Red Hat, working on Podman, Buildah, and other container tools. More about me