Ce contenu n'est pas disponible dans la langue sélectionnée.
Chapter 12. Porting containers to systemd using Podman
Podman (Pod Manager) is a simple daemonless tool fully featured container engine. Podman provides a Docker-CLI comparable command line that makes the transition from other container engines easier and enables the management of pods, containers, and images.
Originally, Podman was not designed to provide an entire Linux system or manage services, such as start-up order, dependency checking, and failed service recovery. systemd was responsible for a complete system initialization. Due to Red Hat integrating containers with systemd, you can manage OCI and Docker-formatted containers built by Podman in the same way as other services and features are managed in a Linux system. You can use the systemd initialization service to work with pods and containers.
With systemd unit files, you can:
-
Set up a container or pod to start as a
systemdservice. - Define the order in which the containerized service runs and check for dependencies (for example making sure another service is running, a file is available or a resource is mounted).
-
Control the state of the
systemdsystem by using thesystemctlcommand.
You can generate portable descriptions of containers and pods by using systemd unit files.
12.1. Auto-generating a systemd unit file using Quadlets Copier lienLien copié sur presse-papiers!
With Quadlet, you describe how to run a container in a format that is very similar to regular systemd unit files. The container descriptions focus on the relevant container details and hide technical details of running containers under systemd. Create the <CTRNAME>.container unit file in one of the following directories:
-
For root users:
/usr/share/containers/systemd/or/etc/containers/systemd/ -
For rootless users:
$HOME/.config/containers/systemd/,$XDG_CONFIG_HOME/containers/systemd/,/etc/containers/systemd/users/$(UID), or/etc/containers/systemd/users/
Quadlet is available beginning with Podman v4.6.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Create the
mysleep.containerunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the
[Container]section you must specify:-
Image- container mage you want to tun Exec- the command you want to run inside the containerThis enables you to use all other fields specified in a
systemdunit file.
-
Create the
mysleep.servicebased on themysleep.containerfile:systemctl --user daemon-reload
$ systemctl --user daemon-reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Check the status of the
mysleep.service:systemctl --user status mysleep.service
$ systemctl --user status mysleep.service ○ mysleep.service - The sleep container Loaded: loaded (/home/username/.config/containers/systemd/mysleep.container; generated) Active: inactive (dead)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Start the
mysleep.service:systemctl --user start mysleep.service
$ systemctl --user start mysleep.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Check the status of the
mysleep.service:Copy to Clipboard Copied! Toggle word wrap Toggle overflow List all containers:
podman ps -a
$ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 421c8293fc1b registry.access.redhat.com/ubi10-minimal:latest sleep 1000 30 seconds ago Up 10 seconds ago systemd-mysleepCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that the name of the created container consists of the following elements:
-
a
systemd-prefix a name of the
systemdunit, that issystemd-mysleepThis naming helps to distinguish common containers from containers running in
systemdunits. It also helps to determine which unit a container runs in. If you want to change the name of the container, use theContainerNamefield in the[Container]section.
-
a
12.2. Enabling systemd services Copier lienLien copié sur presse-papiers!
When enabling the service, you have different options.
Procedure
Enable the service:
To enable a service at system start, no matter if user is logged in or not, enter:
systemctl enable <service>
# systemctl enable <service>Copy to Clipboard Copied! Toggle word wrap Toggle overflow You have to copy the
systemdunit files to the/etc/systemd/systemdirectory.To start a service at user login and stop it at user logout, enter:
systemctl --user enable <service>
$ systemctl --user enable <service>Copy to Clipboard Copied! Toggle word wrap Toggle overflow You have to copy the
systemdunit files to the$HOME/.config/systemd/userdirectory.To enable users to start a service at system start and persist over logouts, enter:
loginctl enable-linger <username>
# loginctl enable-linger <username>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
12.3. Auto-starting containers using systemd Copier lienLien copié sur presse-papiers!
You can control the state of the systemd system and service manager by using the systemctl command. You can enable, start, stop the service as a non-root user. To install the service as a root user, omit the --user option.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Reload
systemdmanager configuration:systemctl --user daemon-reload
# systemctl --user daemon-reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the service
container.serviceand start it at boot time:systemctl --user enable container.service
# systemctl --user enable container.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Start the service immediately:
systemctl --user start container.service
# systemctl --user start container.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of the service:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can check if the service is enabled by using the
systemctl is-enabled container.servicecommand.
Verification
List containers that are running or have exited:
podman ps
# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f20988d59920 registry.access.redhat.com/ubi10-minimal:latest top 12 seconds ago Up 11 seconds ago funny_zhukovskyCopy to Clipboard Copied! Toggle word wrap Toggle overflow
To stop container.service, enter:
systemctl --user stop container.service
# systemctl --user stop container.service
12.4. Advantages of using Quadlets over the podman generate systemd command Copier lienLien copié sur presse-papiers!
You can use the Quadlets tool, which describes how to run a container in a format similar to regular systemd unit files.
Quadlet is available beginning with Podman v4.6.
Quadlets have many advantages over generating unit files by using the podman generate systemd command, such as:
-
Easy to maintain: The container descriptions focus on the relevant container details and hide technical details of running containers under
systemd. -
Automatically updated: Quadlets do not require manually regenerating unit files after an update. If a newer version of Podman is released, your service is automatically updated when the
systemclt daemon-reloadcommand is executed, for example, at boot time. - Simplified workflow: Thanks to the simplified syntax, you can create Quadlet files from scratch and deploy them anywhere.
- Support standard systemd options: Quadlet extends the existing systemd-unit syntax with new tables, for example, a table to configure a container.
Quadlet supports a subset of Kubernetes YAML capabilities. For more information, see the support matrix of supported YAML fields. You can generate the YAML files by using one of the following tools:
-
Podman:
podman generate kubecommand -
OpenShift:
oc generatecommand with the--dry-runoption -
Kubernetes:
kubectl createcommand with the--dry-runoption
Quadlet supports these unit file types:
Container units: Used to manage containers by running the
podman runcommand.-
File extension:
.container -
Section name:
[Container] -
Required fields:
Imagedescribing the container image the service runs
-
File extension:
Kube units: Used to manage containers defined in Kubernetes YAML files by running the
podman kube playcommand.-
File extension:
.kube -
Section name:
[Kube] -
Required fields:
Yamldefining the path to the Kubernetes YAML file
-
File extension:
Network units: Used to create Podman networks that may be referenced in
.containeror.kubefiles.-
File extension:
.network -
Section name:
[Network] - Required fields: None
-
File extension:
Volume units: Used to create Podman volumes that may be referenced in
.containerfiles.-
File extension:
.volume -
Section name:
[Volume] - Required fields: None
-
File extension:
12.5. Generating a systemd unit file using Podman Copier lienLien copié sur presse-papiers!
Podman allows systemd to control and manage container processes. You can generate a systemd unit file for the existing containers and pods by using podman generate systemd command. It is recommended to use podman generate systemd because the generated units files change frequently (via updates to Podman) and the podman generate systemd ensures that you get the latest version of unit files.
Starting with Podman v4.6, you can use the Quadlets that describe how to run a container in a format similar to regular systemd unit files and hides the complexity of running containers under systemd.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Create a container (for example
myubi):podman create --name myubi registry.access.redhat.com/ubi10:latest sleep infinity
$ podman create --name myubi registry.access.redhat.com/ubi10:latest sleep infinity 0280afe98bb75a5c5e713b28de4b7c5cb49f156f1cce4a208f13fee2f75cb453Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use the container name or ID to generate the
systemdunit file and direct it into the~/.config/systemd/user/container-myubi.servicefile:podman generate systemd --name myubi > ~/.config/systemd/user/container-myubi.service
$ podman generate systemd --name myubi > ~/.config/systemd/user/container-myubi.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the content of generated
systemdunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
Restart=on-failureline sets the restart policy and instructssystemdto restart when the service cannot be started or stopped cleanly, or when the process exits non-zero. -
The
ExecStartline describes how we start the container. -
The
ExecStopline describes how we stop and remove the container.
-
The
12.6. Automatically generating a systemd unit file using Podman Copier lienLien copié sur presse-papiers!
By default, Podman generates a unit file for existing containers or pods. You can generate more portable systemd unit files by using the podman generate systemd --new. The --new flag instructs Podman to generate unit files that create, start and remove containers.
Starting with Podman v4.6, you can use the Quadlets that describe how to run a container in a format similar to regular systemd unit files and hides the complexity of running containers under systemd.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Pull the image you want to use on your system. For example, to pull the
httpd-24image:podman pull registry.access.redhat.com/ubi10/httpd-24
# podman pull registry.access.redhat.com/ubi10/httpd-24Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: List all images available on your system:
podman images
# podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/ubi10/httpd-24 latest 8594be0a0b57 2 weeks ago 462 MBCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
httpdcontainer:podman create --name httpd -p 8080:8080 registry.access.redhat.com/ubi10/httpd-24
# podman create --name httpd -p 8080:8080 registry.access.redhat.com/ubi10/httpd-24 cdb9f981cf143021b1679599d860026b13a77187f75e46cc0eac85293710a4b1Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Verify the container has been created:
podman ps -a
# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cdb9f981cf14 registry.access.redhat.com/ubi10/httpd-24:latest /usr/bin/run-http... 5 minutes ago Created 0.0.0.0:8080->8080/tcp httpdCopy to Clipboard Copied! Toggle word wrap Toggle overflow Generate a
systemdunit file for thehttpdcontainer:podman generate systemd --new --files --name httpd
# podman generate systemd --new --files --name httpd /root/container-httpd.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Display the content of the generated
container-httpd.servicesystemdunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Unit files generated by using the --new option do not expect containers and pods to exist. Therefore, they perform the podman run command when starting the service (see the ExecStart line) instead of the podman start command. For example, see section Generating a systemd unit file using Podman.
The
podman runcommand uses the following command-line options:-
The
--conmon-pidfileoption points to a path to store the process ID for theconmonprocess running on the host. Theconmonprocess terminates with the same exit status as the container, which allowssystemdto report the correct service status and restart the container if needed. -
The
--cidfileoption points to the path that stores the container ID. -
The
%tis the path to the run time directory root, for example/run/user/$UserID. The
%nis the full name of the service.Copy unit files to
/etc/systemd/systemfor installing them as a root user:cp -Z container-httpd.service /etc/systemd/system
# cp -Z container-httpd.service /etc/systemd/systemCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable and start the
container-httpd.service:systemctl daemon-reload systemctl enable --now container-httpd.service
# systemctl daemon-reload # systemctl enable --now container-httpd.service Created symlink /etc/systemd/system/multi-user.target.wants/container-httpd.service/etc/systemd/system/container-httpd.service. Created symlink /etc/systemd/system/default.target.wants/container-httpd.service /etc/systemd/system/container-httpd.service. Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
The
Verification
Check the status of the
container-httpd.service:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
12.7. Automatically starting pods using systemd Copier lienLien copié sur presse-papiers!
You can start multiple containers as systemd services. Note that the systemctl command should only be used on the pod and you should not start or stop containers individually via systemctl, as they are managed by the pod service along with the internal infra-container.
Starting with Podman v4.6, you can use the Quadlets that describe how to run a container in a format similar to regular systemd unit files and hides the complexity of running containers under systemd.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Create an empty pod, for example named
systemd-pod:podman pod create --name systemd-pod
$ podman pod create --name systemd-pod 11d4646ba41b1fffa51c108cbdf97cfab3213f7bd9b3e1ca52fe81b90fed5577Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: List all pods:
podman pod ps
$ podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID 11d4646ba41b systemd-pod Created 40 seconds ago 1 8a428b257111 11d4646ba41b1fffa51c108cbdf97cfab3213f7bd9b3e1ca52fe81b90fed5577Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create two containers in the empty pod. For example, to create
container0andcontainer1insystemd-pod:*podman create --pod systemd-pod --name container0 registry.access.redhat.com/ubi*10 top *podman create --pod systemd-pod --name container1 registry.access.redhat.com/ubi*10 top
$ *podman create --pod systemd-pod --name container0 registry.access.redhat.com/ubi*10 top $ *podman create --pod systemd-pod --name container1 registry.access.redhat.com/ubi*10 topCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: List all pods and containers associated with them:
podman ps -a --pod
$ podman ps -a --pod CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD ID PODNAME 24666f47d9b2 registry.access.redhat.com/ubi10:latest top 3 minutes ago Created container0 3130f724e229 systemd-pod 56eb1bf0cdfe k8s.gcr.io/pause:3.2 4 minutes ago Created 3130f724e229-infra 3130f724e229 systemd-pod 62118d170e43 registry.access.redhat.com/ubi10:latest top 3 seconds ago Created container1 3130f724e229 systemd-podCopy to Clipboard Copied! Toggle word wrap Toggle overflow Generate the
systemdunit file for the new pod:podman generate systemd --files --name systemd-pod
$ podman generate systemd --files --name systemd-pod /home/user1/pod-systemd-pod.service /home/user1/container-container0.service /home/user1/container-container1.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that three
systemdunit files are generated, one for thesystemd-podpod and two for the containerscontainer0andcontainer1.Display
pod-systemd-pod.serviceunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
Requiresline in the[Unit]section defines dependencies oncontainer-container0.serviceandcontainer-container1.serviceunit files. Both unit files will be activated. -
The
ExecStartandExecStoplines in the[Service]section start and stop the infra-container, respectively.
-
The
Display
container-container0.serviceunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
The
BindsToline line in the[Unit]section defines the dependency on thepod-systemd-pod.serviceunit file -
The
ExecStartandExecStoplines in the[Service]section start and stop thecontainer0respectively.
-
The
Display
container-container1.serviceunit file:cat container-container1.service
$ cat container-container1.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Copy all the generated files to
$HOME/.config/systemd/userfor installing as a non-root user:cp pod-systemd-pod.service container-container0.service container-container1.service $HOME/.config/systemd/user
$ cp pod-systemd-pod.service container-container0.service container-container1.service $HOME/.config/systemd/userCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the service and start at user login:
systemctl enable --user pod-systemd-pod.service
$ systemctl enable --user pod-systemd-pod.service Created symlink /home/user1/.config/systemd/user/multi-user.target.wants/pod-systemd-pod.service/home/user1/.config/systemd/user/pod-systemd-pod.service. Created symlink /home/user1/.config/systemd/user/default.target.wants/pod-systemd-pod.service /home/user1/.config/systemd/user/pod-systemd-pod.service. Copy to Clipboard Copied! Toggle word wrap Toggle overflow Note that the service stops at user logout.
Verification
Check if the service is enabled:
systemctl is-enabled pod-systemd-pod.service
$ systemctl is-enabled pod-systemd-pod.service enabledCopy to Clipboard Copied! Toggle word wrap Toggle overflow
12.8. Automatically updating containers using Podman Copier lienLien copié sur presse-papiers!
The podman auto-update command allows you to automatically update containers according to their auto-update policy. The podman auto-update command updates services when the container image is updated on the registry. To use auto-updates, containers must be created with the --label "io.containers.autoupdate=image" label and run in a systemd unit generated by podman generate systemd --new command.
Podman searches for running containers with the "io.containers.autoupdate" label set to "image" and communicates to the container registry. If the image has changed, Podman restarts the corresponding systemd unit to stop the old container and create a new one with the new image. As a result, the container, its environment, and all dependencies, are restarted.
Starting with Podman v4.6, you can use the Quadlets that describe how to run a container in a format similar to regular systemd unit files and hides the complexity of running containers under systemd.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Start a
myubicontainer based on theregistry.access.redhat.com/ubi10/ubi-initimage:podman run --label "io.containers.autoupdate=image" \ --name myubi -dt registry.access.redhat.com/ubi10/ubi-init top
# podman run --label "io.containers.autoupdate=image" \ --name myubi -dt registry.access.redhat.com/ubi10/ubi-init top bc219740a210455fa27deacc96d50a9e20516492f1417507c13ce1533dbdcd9dCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: List containers that are running or have exited:
podman ps -a
# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76465a5e2933 registry.access.redhat.com/10/ubi-init:latest top 24 seconds ago Up 23 seconds ago myubiCopy to Clipboard Copied! Toggle word wrap Toggle overflow Generate a
systemdunit file for themyubicontainer:podman generate systemd --new --files --name myubi
# podman generate systemd --new --files --name myubi /root/container-myubi.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Copy unit files to
/usr/lib/systemd/systemfor installing it as a root user:cp -Z ~/container-myubi.service /usr/lib/systemd/system
# cp -Z ~/container-myubi.service /usr/lib/systemd/systemCopy to Clipboard Copied! Toggle word wrap Toggle overflow Reload
systemdmanager configuration:systemctl daemon-reload
# systemctl daemon-reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow Start and check the status of a container:
systemctl start container-myubi.service systemctl status container-myubi.service
# systemctl start container-myubi.service # systemctl status container-myubi.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow Auto-update the container:
podman auto-update
# podman auto-updateCopy to Clipboard Copied! Toggle word wrap Toggle overflow
12.9. Automatically updating containers using systemd Copier lienLien copié sur presse-papiers!
As mentioned in section Automatically updating containers using Podman,
you can update the container by using the podman auto-update command. It integrates into custom scripts and can be invoked when needed. Another way to auto update the containers is to use the pre-installed podman-auto-update.timer and podman-auto-update.service systemd service. The podman-auto-update.timer can be configured to trigger auto updates at a specific date or time. The podman-auto-update.service can further be started by the systemctl command or be used as a dependency by other systemd services. As a result, auto updates based on time and events can be triggered in various ways to meet individual needs and use cases.
Starting with Podman v4.6, you can use the Quadlets that describe how to run a container in a format similar to regular systemd unit files and hides the complexity of running containers under systemd.
Prerequisites
-
The
container-toolsmeta-package is installed.
Procedure
Display the
podman-auto-update.serviceunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Display the
podman-auto-update.timerunit file:Copy to Clipboard Copied! Toggle word wrap Toggle overflow In this example, the
podman auto-updatecommand is launched daily at midnight.Enable the
podman-auto-update.timerservice at system start:systemctl enable podman-auto-update.timer
# systemctl enable podman-auto-update.timerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Start the
systemdservice:systemctl start podman-auto-update.timer
# systemctl start podman-auto-update.timerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: List all timers:
systemctl list-timers --all
# systemctl list-timers --all NEXT LEFT LAST PASSED UNIT ACTIVATES Wed 2020-12-09 00:00:00 CET 9h left n/a n/a podman-auto-update.timer podman-auto-update.serviceCopy to Clipboard Copied! Toggle word wrap Toggle overflow You can see that
podman-auto-update.timeractivates thepodman-auto-update.service.