Running containers from systemd¶
When you embed a container in an operating system (OS) image, you can start the container manually in the booted system with the podman run
command. However, the container does not start automatically at boot time. To configure a container to start at boot time, you must create a
systemd service that starts the container at the right time, in the right way.
Quadlet is a tool that optimally runs Podman containers under systemd. Rather than creating the systemd service manually, use Quadlet to
automatically generate the corresponding systemd service unit file at boot time. Quadlet simplifies container management by allowing you
to create declarative configurations in .container files instead of lengthy, complex systemd unit files.
Quadlet unit files configure containers in both the root and QM partitions. In the AutoSD OS filesystem, store your .container files in
/etc/containers/systemd.
At a minimum, include the following sections and options in a .container file:
[Unit]
Description=<A human-readable title>
[Container]
Image=<The container image>
Exec=<The command that runs in the container>
[Install]
WantedBy=multi-user.target default.target
Include additional sections and options to meet your container requirements. Any section or option permitted in a systemd.unit file is also permitted in a Quadlet unit file.
Containers within containers¶
The QM partition is a container within the root partition of an AutoSD OS image. The QM partition houses containers that run non-critical application workloads.
To add containers to the QM partition, you create Quadlet unit files and add them to the add_files section of your
Automotive Image Builder manifest, for example:
- sshd.service
# Enable UDS socket for server-client communication
...
tag: latest
name: "localhost/ipc_client"
containers-transport: containers-storage
The example shows an ipc_client.container unit file added to the add_files section of the qm partition. The path section is the location
for all container files, /etc/containers/systemd.
You can also create Quadlet unit files directly in the manifest, for example:
qm:
...
content:
...
add_files:
- path: /etc/containers/systemd/nginx.container
text: |
[Container]
Image=localhost/nginx
PublishPort=8080:80
[Install]
WantedBy=multi-user.target
The example shows an nginx container image created directly from the manifest. The text section contains the contents of the .container file.
Configuring communication between QM containers demonstrates additional Quadlet unit file use cases.
Creating Quadlet files for sample applications¶
In this example, create Quadlet files for the sample applications that are available in the AutoSD sample-apps repository. If you want to use your own containerized software, see the Podman documentation for more information about creating your own Quadlet configuration files.
Prerequisites
- Podman is installed.
- The
automotive-image-buildertool is installed. - A container image available inside your OS image at
localhost/auto-appsembedded according to Embedding local containerized applications in the root partition. - A custom manifest file, such as the manifest file you created in Embedding RPM packages from local storage into the AutoSD image.
Procedure
-
Create a systemd socket unit and Quadlet unit files for the
radio-serviceandengine-serviceservices in your sample applicationauto-apps:engine.container file[Unit] Description=Demo engine service container # routingmanagerd.socket is not included in vsomeip3 3.5.11, so let's use routingmanagerd.service for now Requires=routingmanagerd.service After=routingmanagerd.service [Container] Image=localhost/auto-apps Exec=/usr/bin/engine-service Volume=/run/vsomeip:/run/vsomeip Volume=/run/root-ipc-demo:/run/root-ipc-demo [Service] Restart=always [Install] WantedBy=multi-user.targetradio.socket file[Unit] Description=example systemd unix socket [Socket] ListenStream=%t/root-ipc-demo/root_ipc.socket RuntimeDirectory=root-ipc-demo [Install] WantedBy=sockets.targetradio.container file[Unit] Description=Demo radio service container # routingmanagerd.socket is not included in vsomeip3 3.5.11, so let's use routingmanagerd.service for now Requires=routingmanagerd.service After=routingmanagerd.service Requires=radio.socket After=radio.socket Wants=engine.service [Container] Image=localhost/auto-apps Exec=/usr/bin/radio-service Volume=/run/vsomeip:/run/vsomeip Volume=/run/root-ipc-demo:/run/root-ipc-demo [Service] Restart=always [Install] WantedBy=multi-user.target
Note
Requires=radio.socket is a hard dependency that prevents the radio service from starting until the socket unit is active.
After=radio.socket is an ordering dependency: the radio service starts only after the socket unit has started.
Requires=routingmanagerd.service is a hard dependency that prevents the radio service from starting until the routing manager service is active.
Wants=engine.service is a soft dependency. Ideally, the engine service activates the radio service,
but if the engine service is not activated, systemd still permits the radio service to start.
-
Create an Automotive Image Builder manifest named
root-root.aib.ymlthat contains the following code, which copies the Quadlet unit files to the/etc/containers/systemd/directory during the OS image build process:Manifest configuration to copy Quadlet unit files# root-root IPC communications demo name: root-root-IPC-communications content: repos: - id: epel metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-10&arch=$arch rpms: - podman - netavark - aardvark-dns - vsomeip3-routingmanager - dlt-daemon # For testing the image only: - openssh-server - openssh-clients container_images: # Get the auto-apps container image from gitlab - source: registry.gitlab.com/centos/automotive/sample-images/demo/auto-apps tag: latest name: localhost/auto-apps add_files: - path: /etc/containers/systemd/radio.container source_path: ./radio.container - path: /etc/containers/systemd/engine.container source_path: ./engine.container - path: /etc/systemd/system/radio.socket source_path: ./radio.socket # Required for testing the image only: systemd: enabled_services: # Enable ssh daemon - sshd.service # Enable the dlt daemon - dlt # Enable the IPC socket - radio.socket auth: # "password" root_password: $6$xoLqEUz0cGGJRx01$H3H/bFm0myJPULNMtbSsOFd/2BnHqHkMD92Sfxd.EKM9hXTWSmELG8cf205l6dktomuTcgKGGtGDgtvHVXSWU. # Required for testing the image only: sshd_config: PasswordAuthentication: true PermitRootLogin: trueNote
The
source_path:option resolves a relative path. In this example, the Quadlet unit files are in the same directory as the manifest. -
Run
aib-dev buildto build a disk image: -
Verify that the script has created an AutoSD image file named
root-root.<arch>.qcow2in your present working directory. -
Assuming that you have installed QEMU, boot the AutoSD image in a virtual machine, substituting the name of your
.qcow2image file (if necessary): -
After the image boots in QEMU, log in with the user name
rootand the passwordpassword.
Additional resources