RHCSA Rapid Track
Course update
An updated version of this course is available that uses a newer version of Red Hat Enterprise Linux in the lab environment. Therefore, the RHEL 9.0 version of the lab environment will retire on December 31, 2024. Please complete any work in this lab environment before it is removed on December 31, 2024. For the most up-to-date version of this course, we recommend moving to the RHEL 9.3 version.
Configure a container as a systemd service, and configure a container service to start at boot time.
You can run a container to complete a system task or to obtain the output of a series of commands.
You also might want to run containers that run a service indefinitely, such as web servers or databases.
In a traditional environment, a privileged user typically configures these services to run at system boot, and manages them with the systemctl command.
As a regular user, you can create a systemd unit to configure your rootless containers.
You can use this configuration to manage your container as a regular system service with the systemctl command.
Managing containers based on systemd units is mainly useful for basic and small deployments that do not need to scale.
For more sophisticated scaling and orchestration of many container-based applications and services, you can use an enterprise orchestration platform that is based on Kubernetes, such as Red Hat OpenShift Container Platform.
To discuss the topics in this lecture, imagine the following scenario.
As a system administrator, you are tasked to configure the webserver1 container that is based on the http24 container image to start at system boot.
You must also mount the /app-artifacts directory for the web server content and map the 8080 port from the local machine to the container.
Configure the container to start and stop with systemctl commands.
As a regular user, you can enable a service with the systemctl command.
The service starts when you open a session (graphical interface, text console, or SSH), and it stops when you close the last session.
This behavior differs from a system service, which starts when the system boots and stops when the system shuts down.
By default, when you create a user account with the useradd command, the system uses the next available ID from the regular user ID range.
The system also reserves a range of IDs for the user's containers in the /etc/subuid file.
If you create a user account with the useradd command --system option, then the system does not reserve a range for the user containers.
As a consequence, you cannot start rootless containers with system accounts.
You decide to create a dedicated user account to manage containers.
You use the useradd command to create the appdev-adm user, and use redhat as the password.
[user@host ~]$sudo useradd appdev-adm[user@host ~]$sudo passwd appdev-admChanging password for user appdev-adm. New password:redhatBAD PASSWORD: The password is shorter than 8 characters Retype new password:redhatpasswd: all authentication tokens updated successfully.
You then use the su command to switch to the appdev-adm user, and you start to use the podman command.
[user@host ~]$su appdev-admPassword:redhat[appdev-adm@host ~]$podman infoERRO[0000] XDG_RUNTIME_DIR directory "/run/user/1000" is not owned by the current user [appdev-adm@host ~]$
Podman is a stateless utility and requires a full login session.
Podman must be used within an SSH session, and cannot be used in a sudo or an su shell.
So you exit the su shell and log in to the machine via SSH.
[appdev-adm@host ~]$exit[user@host ~]$exit[user@example ~]$ssh appdev-adm@host[appdev-adm@host ~]$
You then configure the container registry and authenticate with your credentials.
You run the http container with the following command.
[appdev-adm@host ~]$podman run -d --name webserver1 -p 8080:8080 -v \~/app-artifacts:/var/www/html:Z registry.access.redhat.com/ubi8/httpd-24cde4a3d8c9563fd50cc39de8a4873dcf15a7e881ba4548d5646760eae7a35d81 [appdev-adm@host ~]$podman psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cde4a3d8c956 registry.access.redhat.com/ubi8/httpd-24:latest /usr/bin/run-http... 4 seconds ago Up 5 seconds ago 0.0.0.0:8080->8080/tcp webserver1
Note
Remember to provide the right access to the directory that you mount from the host file system to the container.
For any error when running a container, you can use the podman container logs command for troubleshooting.
You can manually define systemd services in the ~/.config/systemd/user/ directory.
The file syntax for user services is the same as for the system services files.
For more details, review the systemd.unit(5) and systemd.service(5) man pages.
Use the podman generate systemd command to generate systemd service files for an existing container.
The podman generate systemd command uses a container as a model to create the configuration file.
The podman generate systemd command --new option instructs the podman utility to configure the systemd service to create the container when the service starts, and to delete the container when the service stops.
Important
Without the --new option, the podman utility configures the service unit file to start and stop the existing container without deleting it.
You use the podman generate systemd command with the --name option to display the systemd service file that is modeled for the webserver1 container.
[appdev-adm@host ~]$podman generate systemd --name webserver1...output omitted... ExecStart=/usr/bin/podman start webserver1ExecStop=/usr/bin/podman stop -t 10 webserver1
ExecStopPost=/usr/bin/podman stop -t 10 webserver1 ...output omitted...
On start, the | |
On stop, the |
You then use the previous command with the addition of the --new option to compare the systemd configuration.
[appdev-adm@host ~]$podman generate systemd --name webserver1 --new...output omitted... ExecStartPre=/bin/rm -f %t/%n.ctr-id ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace -d --name webserver1 -p 8080:8080 -v /home/appdev-adm/app-artifacts:/var/www/html:Z registry.access.redhat.com/ubi8/httpd-24ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
...output omitted...
On starting, the | |
On stopping, | |
After |
You verify the output of the podman generate systemd command, and run the previous command with the --files option to create the systemd user file in the current directory.
Because the webserver1 container uses persistent storage, you choose to use the podman generate systemd command with the --new option.
You then create the ~/.config/systemd/user/ directory and move the file to this location.
[appdev-adm@host ~]$podman generate systemd --name webserver1 --new --files/home/appdev-adm/container-webserver1.service [appdev-adm@host ~]$mkdir -p ~/.config/systemd/user/[appdev-adm@host ~]$mv container-webserver1.service ~/.config/systemd/user/
Now that you created the systemd user file, you can use the systemctl command --user option to manage the webserver1 container.
First, you reload the systemd daemon to make the systemctl command aware of the new user file.
You use the systemctl --user start command to start the webserver1 container.
Use the name of the generated systemd user file for the container.
[appdev-adm@host ~]$systemctl --user daemon-reload[appdev-adm@host ~]$systemctl --user start container-webserver1.service[appdev-adm@host ~]$systemctl --user status container-webserver1.service● container-webserver1.service - Podman container-webserver1.service Loaded: loaded (/home/appdev-adm/.config/systemd/user/container-webserver1.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2022-04-28 21:22:26 EDT; 18s ago Docs: man:podman-generate-systemd(1) Process: 31560 ExecStartPre=/bin/rm -f /run/user/1003/container-webserver1.service.ctr-id (code=exited, status=0/SUCCESS) Main PID: 31600 (conmon) ...output omitted... [appdev-adm@host ~]$podman psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 18eb00f42324 registry.access.redhat.com/ubi8/httpd-24:latest /usr/bin/run-http... 28 seconds ago Up 29 seconds ago 0.0.0.0:8080->8080/tcp webserver1 Created symlink /home/appdev-adm/.config/systemd/user/default.target.wants/container-webserver1.service → /home/appdev-adm/.config/systemd/user/container-webserver1.service.
Important
When you configure a container with the systemd daemon, the daemon monitors the container status and restarts the container if it fails.
Do not use the podman command to start or stop these containers.
Doing so might interfere with the systemd daemon monitoring.
The following table summarizes the directories and commands that are used between systemd system and user services.
Table 16.3. Comparing System and User Services
| Storing custom unit files | System services |
/etc/systemd/system/
|
| User services |
~/.config/systemd/user/
| |
| Reloading unit files | System services |
#
|
| User services |
$
| |
| Starting and stopping a service | System services |
# |
| User services |
$ | |
| Starting a service when the machine starts | System services |
#
|
| User services |
$ |
At this point, the systemd service configuration is ready to run a container for a given user.
However, the systemd service stops the container after a certain time if the user logs out from the system.
This behavior occurs because the systemd service unit was created with the --user option, which starts a service at user login and stops it at user logout.
You can change this default behavior, and force your enabled services to start with the server and stop during the shutdown, by running the loginctl enable-linger command.
You use the loginctl command to configure the systemd user service to persist after the last user session of the configured service closes.
You then verify the successful configuration with the loginctl show-user command.
[user@host ~]$loginctl show-user appdev-adm...output omitted...Linger=no[user@host ~]$loginctl enable-linger[user@host ~]$loginctl show-user appdev-adm...output omitted...Linger=yes
To revert the operation, use the loginctl disable-linger command.
You can also configure containers to run as root and manage them with systemd service files.
One advantage of this approach is that you can configure the service files to work the same as common systemd unit files, rather than as a particular user.
The procedure to set the service file as root is similar to the previously outlined procedure for rootless containers, with the following exceptions:
Do not create a dedicated user for container management.
The service file must be in the
/etc/systemd/systemdirectory instead of in the~/.config/systemd/userdirectory.You manage the containers with the
systemctlcommand without the--useroption.Do not run the
loginctl enable-lingercommand as therootuser.
For a demonstration, see the YouTube video from the Red Hat Videos channel that is listed in the References at the end of this section.
References
loginctl(1), systemd.unit(5), systemd.service(5), subuid(5), and podman-generate-systemd(1) man pages
Managing Containers in Podman with Systemd Unit Files
For more information, refer to the Running Containers as Systemd Services with Podman chapter in the Red Hat Enterprise Linux 9 Building, Running, and Managing Containers guide at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/building_running_and_managing_containers/index