Skip to content

Deploying sample apps in containers

Containers in automotive

The automotive industry is moving towards a new architectural concept called software-defined vehicles (SDV). Part of this is a software model that is similar to the micro-server architecture used in the cloud. In this model, the various services and applications running in the car are separate, isolated entities that expose well-defined interfaces. The whole system is then made of a large collection of such services that interact using some form of networking protocol. In automotive this most commonly uses SOME/IP, which is a message based protocol with a pub/sub model running on top of IP and/or Unix domain sockets.

While the SDV model can be implemented with traditional methods, it lends itself extremely well to the use of containers because the isolation aspects of containers match well to the separated services and the requirement of well-defined interfaces between containers, similar to microservices.

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.

Sample container image

To demonstrate how to implement this, we have the quadlet_radio_engine.aib.yml manifest that you can use to build an OS image that includes containerized sample applications.

The sample-apps consists of two SOME/IP services:

  • radio-service, which simulates a radio
  • engine-service that simulates other parts of the car.

There is also a command line application radio-client, which talks to the services displaying the current status and allowing you to control the radio. For more details about these apps, see the sample-apps README.

The image uses the COVESA vsomeip implementation of SOME/IP as packaged in Fedora, and rebuilt in COPR. In particular, the image starts the vsomeip routing manager (non-contained), using systemd socket activation with a custom SELinux policy that controls access.

After you boot the OS image, two container-based systemd sample services are running: radio.service and engine.service.

Building a virtual machine that contains the sample apps

Follow these steps to build and run a virtual machine OS image that contains the sample apps.

Prerequisites

Procedure

  1. Create and go to a new directory called sample-auto-apps:

    $ mkdir sample-auto-apps && cd sample-auto-apps
    
  2. Create and save a file called radio.container that contains the following code:

    [Unit]
    Description=Demo radio service container
    Requires=routingmanagerd.socket
    After=routingmanagerd.socket
    Wants=engine.service
    
    [Container]
    Image=localhost/auto-apps
    Exec=/usr/bin/radio-service
    Volume=/run/vsomeip:/run/vsomeip
    
    [Service]
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
  3. Create and save a file called engine.container that contains the following code:

    [Unit]
    Description=Demo engine service container
    Requires=routingmanagerd.socket
    After=routingmanagerd.socket
    
    [Container]
    Image=localhost/auto-apps
    Exec=/usr/bin/engine-service
    Volume=/run/vsomeip:/run/vsomeip
    
    [Service]
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
  4. Create and go to a new subdirectory called quadlet_radio_engine:

    $ mkdir quadlet_radio_engine && cd quadlet_radio_engine
    
  5. Create and save a build manifest file named quadlet_radio_engine.aib.yml, that contains the following YAML code:

    name: quadlet_radio_engine
    
    content:
      repos:
        - id: copr-sample-apps
          baseurl: https://download.copr.fedorainfracloud.org/results/alexl/cs9-sample-images/centos-stream-9-$arch/
      rpms:
        - podman
        - containernetworking-plugins
        - 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
    
      # Required for testing the image only:
      systemd:
        enabled_services:
          # Enable ssh daemon
          - sshd.service
          # Enable the dlt daemon
          - dlt
    
    auth:
      # "password"
      root_password: $6$xoLqEUz0cGGJRx01$H3H/bFm0myJPULNMtbSsOFd/2BnHqHkMD92Sfxd.EKM9hXTWSmELG8cf205l6dktomuTcgKGGtGDgtvHVXSWU.
      # Required for testing the image only:
      sshd_config:
        PasswordAuthentication: true
        PermitRootLogin: true
    
  6. Export the current system’s CPU architecture as a variable:

    $ arch=$(arch)
    
  7. Run the following command to build the OS image:

       automotive-image-builder --verbose \
        --include=.. \
        build \
        --distro autosd9 \
        --target qemu \
        --mode image \
        --build-dir=_build \
        --export image \
        quadlet_radio_engine.aib.yml \
        quadlet_radio_engine.$arch.img
    
  8. Boot the OS image as a virtual machine (VM) in QEMU:

    $ sudo automotive-image-runner --nographics quadlet_radio_engine.x86_64.img
    
  9. Log in to the VM as the root user with the password password.

  10. Verify that the auto-apps container exists:

    # podman image list
    
  11. Verify that the radio service is running:

    # systemctl status radio.service
    
  12. Verify that the engine service is running:

    # systemctl status engine.service
    
  13. When you are done, run the following command to shut down the VM and return to your local terminal:

    # poweroff
    

Technical details

Embedding container images with Automotive image builder

Automotive image builder can build OS images that include embedded container images. Typically these container images are pulled from a container image registry at build-time, although it is also possible to construct images on the fly as part of the OS image building process.

You can specify what container images to embed in the built OS image in the container_images section of the aib.yml manifest file. Use this section to specify which image to pull from a specified registry.

For example, adding the following code to the content section of the build manifest file pulls a the auto-apps container image from the registry.gitlab.com/centos/automotive/sample-images/demo/auto-apps in the host partition of the built OS image:

  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

For more information about building OS images that include embedded containerized application images, see Containerizing applications.

Running containers from systemd

After a container is embedded in a system image, it can be started manually with podman run <image-name>. However, it doesn’t automatically start at boot. In order to be started automatically, you must create a systemd service that starts the container, at the right time, in the right way.

The sample images use quadlet to set up the systemd services. This is a tool that takes an easy to understand and maintain container unit description and automatically generates (at boot time) and uses the corresponding systemd service unit file. Using this makes it very easy to automatically start a container at system boot, you just put a file in /etc/containers/systemd

As an example of a quadlet container file, here is the radio service config.

For more information about packaging applications and embedding them in AutoSD images, see Packaging sample application source code with RPM.


© Red Hat