Skip to content

Containerizing applications

An alternative to packaging your software with RPM is to install your application or service in a Linux container. Deploying applications as containers can be advantageous because the container isolates the application from the OS, as well as from other containers. This means that you can build the application against a different base OS that is not necessarily compatible with AutoSD, with the exception of the kernel application binary interface (ABI). With this framework, you can have multiple applications that use different environments running on a single system.

In addition, containers have other advantages, such as the ability for each container to use different versions of dependencies and the improved robustness, security, and flexibility that comes from the kernel-level application isolation. This isolation forms the mixed-criticality architecture of the AutoSD application environment.

Mixed-criticality workloads

The isolation aspects of containers support separated services and align with the requirement for well-defined interfaces between containers.

Building a container image for your software

A container image is a lightweight, standalone software package that includes the code, tools, libraries, and settings required to run a piece of software. The configuration for a container image is stored in a file called a Containerfile.

Prerequisites

  • Podman
  • An RPM package (auto-apps) in an RPM package repository (/var/tmp/my_repo)

Procedure

  1. Create a Containerfile that includes the RPM package that you created in Packaging your application source code with RPM:

    FROM centos:stream9
    
    COPY /var/tmp/my_repo /tmp/my_repo
    
    RUN dnf install -y /tmp/my_repo/auto-apps.rpm && dnf clean all
    
  2. Run podman build in the same directory as your Containerfile to build the container image, and name the container image auto-apps:

    podman build -t auto-apps .
    
  3. Start a container from your auto-apps container image, and verify that your RPM package is present:

    podman run -it auto-apps
    rpm -q auto-apps
    

    The output of the rpm -q command displays the version of your package:

    auto-apps-0.1
    

Now that you have a functional auto-apps container image, you can embed your containerized applications in the AutoSD image with OSBuild.

Embedding containerized applications in the AutoSD image

OSBuild pulls containers from an image registry at build time and embeds them in the AutoSD image. Using container image IDs, which you must add to the sources section of the manifest, the org.osbuild.skopeo pipeline stage installs the container images in the operating system (OS) image in the default read-write location for containers, /var/lib/containers/storage. However, you can also use the containers-storage option to install your container in /usr/share/containers/storage.

Generally, the /usr/share/containers/storage directory is for containers that you want to add during the OS image build, and the /var/lib/containers/storage directory is for containers that you want to install later in the running environment.

Prerequisites

Procedure

  1. Retrieve the ID of the auto-apps container image:

    podman image inspect auto-apps | jq -r '.[0].Id'
    
  2. Include the ID of the container image in a new org.osbuild.containers-storage object in a new sources section of your manifest file:

      sources:
        org.osbuild.containers-storage:
          items:
            sha256:<your-container-image-ID>: {}
    
  3. Configure your OSBuild manifest to pull the container image into your OS image at build time:

    1. Include the ID of the container image in a new org.osbuild.skopeo stage in the rootfs pipeline of your manifest file:

      - type: org.osbuild.skopeo
          inputs:
            images:
              type: org.osbuild.containers-storage
              origin: org.osbuild.source
              references:
                sha256:<your-container-image-ID>:
                  name: localhost/auto-apps:latest
      
    2. Include the containers-storage option to place the container image in /usr/share/containers/storage, rather than the default, /var/lib/containers/storage:

      - type: org.osbuild.skopeo
          inputs:
            images:
              type: org.osbuild.containers-storage
              origin: org.osbuild.source
              references:
                sha256:<your-container-image-ID>:
                  name: localhost/auto-apps:latest
          options:
            destination:
              type: containers-storage
              storage-path:
                mpp-eval: containers_extra_store
      

When you build your OS image, OSBuild copies the auto-apps container image to your OS image. Your containerized auto-apps application is available at localhost/auto-apps. You must also create container configuration files and configure OSBuild to copy these files to the /etc/containers/systemd directory in your OS image. For more information about these container configuration files, see Running containers from systemd.

Next steps

Additional resources

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. 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

Procedure

  1. Create Quadlet unit files for the radio-service and engine-service services in your sample application auto-apps:

    radio.container file

    [Unit]
    Description=Demo radio service container
    Requires=routingmanagerd.socket
    Wants=engine.service
    
    [Container]
    Image=localhost/auto-apps
    Volume=/run/vsomeip:/run/vsomeip
    Exec=/usr/bin/radio-service
    
    [Service]
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    engine.container file

    [Unit]
    Description=Demo engine service container
    Requires=routingmanagerd.socket
    
    [Container]
    Image=localhost/auto-apps
    Volume=/run/vsomeip:/run/vsomeip
    Exec=/usr/bin/engine-service
    Image=localhost/auto-apps
    Volume=/run/vsomeip:/run/vsomeip
    Exec=/usr/bin/engine-service
    
    [Service]
    Restart=always
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
  2. Configure your OSBuild manifest to copy the Quadlet unit files to the /etc/containers/systemd/ directory during the OS image build process. Modify the manifest file and include a new org.osbuild.copy stage in the rootfs pipeline that contains the paths to your Quadlet unit files:

    - type: org.osbuild.copy
      inputs:
        inlinefile1:
          type: org.osbuild.files
          origin: org.osbuild.source
          mpp-embed:
            id: radio.container
            path: ../files/radio.container
        inlinefile2:
          type: org.osbuild.files
          origin: org.osbuild.source
          mpp-embed:
            id: engine.container
            path: ../files/engine.container
      options:
        paths:
    - from:
            mpp-format-string: input://inlinefile1/{embedded['radio.container']}
          to: tree:///etc/containers/systemd/radio.container
    - from:
            mpp-format-string: input://inlinefile2/{embedded['engine.container']}
          to: tree:///etc/containers/systemd/engine.container
    

    Note

    The path: option resolves a relative path. In this example, your Quadlet unit files are in the ../files directory.

Additional resources


© Red Hat