Run Podman Containers Under Systemd with Quadlet
Introduction
Quadlet provides a way to run containers under systemd within Oracle Linux. You define the container to run under a [Container]
section in a familiar format to the standard Podman command line syntax and leverage all the benefits of the [Unit]
and [Service]
options of systemd. The advantage to using systemd to run your containers is that systemd is integrated into the operating system, so you can have containers that start when the system starts or set the order and dependency between a multi-container configuration.
Quadlet replaces an older method Podman used to integrate with systemd. That method consists of creating a container, generating a service file, moving the service file, and then enabling the service. In many cases, users would spend time writing these steps into Bash scripts and then have to maintain those scripts and the generated files. Depending on a user's perspective, Quadlet simplifies this task.
Objectives
In this tutorial, you'll learn to:
- Create a .container file
- Start the new container service
- Test the container
- Update the container
Prerequisites
Minimum of a single Oracle Linux system
Each system should have Oracle Linux installed and configured with:
- A non-root user account with sudo access
- Podman and cURL packages
- Cgroup v2
- Access to the Internet
Deploy Oracle Linux
Note: If running in your own tenancy, read the linux-virt-labs
GitHub project README.md and complete the prerequisites before deploying the lab environment.
Open a terminal on the Luna Desktop.
Clone the
linux-virt-labs
GitHub project.git clone https://github.com/oracle-devrel/linux-virt-labs.git
Change into the working directory.
cd linux-virt-labs/ol
Install the required collections.
ansible-galaxy collection install -r requirements.yml
Deploy the lab environment.
ansible-playbook create_instance.yml -e localhost_python_interpreter="/usr/bin/python3.6" -e use_podman=true -e update_all=true -e os_version="9"
The free lab environment requires the extra variable
local_python_interpreter
, which setsansible_python_interpreter
for plays running on localhost. This variable is needed because the environment installs the RPM package for the Oracle Cloud Infrastructure SDK for Python, located under the python3.6 modules.The default deployment shape uses the AMD CPU and Oracle Linux 8. To use an Intel CPU or Oracle Linux 9, add
-e instance_shape="VM.Standard3.Flex"
or-e os_version="9"
to the deployment command.Important: Wait for the playbook to run successfully and reach the pause task. At this stage of the playbook, the installation of Oracle Linux is complete, and the instances are ready. Take note of the previous play, which prints the public and private IP addresses of the nodes it deploys and any other deployment information needed while running the lab.
Confirm Podman Works
The container-tools package in Oracle Linux provides the latest versions of Podman, Buildah, Skopeo, and associated dependencies.
Open a terminal and connect via SSH to the ol-node-01 instance.
ssh oracle@<ip_address_of_instance>
Check the version of Podman.
podman -v
Confirm the Podman CLI is working.
podman run quay.io/podman/hello
Example Output:
[oracle@ol-server ~]$ podman run quay.io/podman/hello Trying to pull quay.io/podman/hello:latest... Getting image source signatures Copying blob f82b04e85914 done Copying config dbd85e09a1 done Writing manifest to image destination Storing signatures !... Hello Podman World ...! .--"--. / - - \ / (O) (O) \ ~~~| -=(,Y,)=- | .---. /` \ |~~ ~/ o o \~~~~.----. ~~ | =(X)= |~ / (O (O) \ ~~~~~~~ ~| =(Y_)=- | ~~~~ ~~~| U |~~ Project: https://github.com/containers/podman Website: https://podman.io Documents: https://docs.podman.io Twitter: @Podman_io
Create a Quadlet
A Quadlet is just the creation of a .container file in a specific directory containing a [Container]
section describing the container startup options.
Create the users's container systemd directory.
mkdir -p ~/.config/containers/systemd
Create a .container file.
cat << EOF | tee ~/.config/containers/systemd/test-ol.container > /dev/null [Unit] Description=My First Quadlet [Container] Image=ghcr.io/oracle/oraclelinux:9 AutoUpdate=registry Exec=sleep 60 [Service] Restart=always TimeoutStartSec=900 [Install] WantedBy=multi-user.target default.target EOF
This Quadlet runs the Oracle Linux container and performs a
sleep 60
in the container. Once thesleep 60
completes, the container exits, and then systemd restarts it. Other options exist for the[Container]
section, and a list is available in the upstream documentation.See systemd.unit(5) man page for more information on the
[Service]
,[Unit]
and[Install]
options.Enable lingering for the user.
sudo loginctl enable-linger oracle
Inform systemd of the new unit file.
systemctl --user daemon-reload
This step creates the test-ol.service based on the test-ol.container file.
Start the service.
systemctl --user start test-ol.service
The service runs
podman
to download the Oracle Linux image and then issues thesleep 60
inside the container image.Check the status of the service.
systemctl --user status test-ol.service
Repeat this command to see the container stop and restart after running
sleep 60
. You can also check the logs by runningsudo journalctl _SYSTEMD_USER_UNIT=test-ol.service
.Update the container.
With the
AutoUpdate=registry
entry in the[Container]
section, you enable thepodman auto-update
feature to update the container images. However, if you want this to happen automatically rather than manually, you must also enable the required service.systemctl --user enable podman-auto-update
Manually, you can run
podman auto-update --dry-run
to see if an update is available. Since we just downloaded the latest image a few minutes ago, there are no updates, and thus, there is nothing to do. However, if there is an update, you can remove the--dry-run
option andpodman
will pull the latest image and restart the container.
Next Steps
This tutorial shows how to leverage Quadlet to manage a minimal container using systemd. Learn more by reading through the documentation and creating additional containers that leverage storage and have multi-container dependencies.