Chapter 4. Operating system images for using with the Red Hat Edge Manager


Image-based operating systems allow the operating system and its configuration and applications to be versioned, deployed, and updated as a single unit. Using an image-based operating system reduces operational risks by doing the following:

  • Minimizing potential drift between what is tested and what is deployed to a large number of devices.
  • Minimizing the risk of failed updates that require expensive maintenance or replacement through transactional updates and rollbacks.

The Red Hat Edge Manager focuses on image-based Linux operating systems that run bootable container images (bootc).

For more information, see bootc.

Important

The bootc tool does not update package-based operating systems.

4.1. The image building process

  1. Choose a base bootc operating system image, such as a Fedora, CentOS, or RHEL image.
  2. Create a container file that layers the following items onto the base bootc image:

    • The Red Hat Edge Manager agent and configuration.
    • Optional: Any drivers specific to your target deployment environment.
    • Optional: Host configuration, for example, certificate authority bundles, and application workloads that are common to all deployments.
  3. Build, publish, and sign a bootc operating system image using podman and skopeo.
  4. Create an operating system disk image by using bootc-image-builder.
  5. Build, publish, and sign an operating system disk image using skopeo.
Note

The operating system disk image has partitions, volumes, the file system, and the initial bootc image. You only need to create the operating system disk image once, during provisioning. For later device updates, you only need the bootc operating system image, which has the files in the file system.

4.2. Special considerations for building images

Add the configuration to the operating system image at build time. Adding the configuration at build time ensures that the configurations are tested, distributed, and updated together. In cases when build-time configuration is not feasible or desirable, you can dynamically configure devices at runtime instead with the Red Hat Edge Manager.

Dynamic runtime configuration is preferable in the following cases:

  • You have a configuration that is deployment or site-specific, such as a hostname or a site-specific network credential.
  • You have secrets that are not secure to distribute with the image.
  • You have application workloads that need to be added, updated, or deleted without reboot or they are on a faster cadence than the operating system.

4.2.2. Configuration in the /usr directory

Place configuration files in the /usr directory if the configuration is static and the application or service supports that configuration. By placing the configuration in the /usr directory, the configuration remains read-only and fully defined by the image.

Do not place the configuration in the /usr directory in the following cases:

  • The configuration is deployment or site-specific.
  • The application or service only supports reading configuration from the /etc directory.
  • The configuration might need to be changed at runtime.

4.2.3. Drop-in directories

Use drop-in directories to add, replace, or remove configuration files that the service aggregates. Do not directly edit your configuration files because it can cause deviations from the target configuration.

Note

You can identify drop-in directories by the .d/ at the end of the directory name. For example, /etc/containers/certs.d, /etc/cron.d, and /etc/NetworkManager/conf.d.

4.2.4. Operating system images with scripts

Avoid executing scripts or commands that change the file system. The bootc or the Red Hat Edge Manager can overwrite the changed files which can cause a deviation or failed integrity checks..

Instead, run such scripts or commands during image building so changes are part of the image. You can also use the configuration management mechanisms of the Red Hat Edge Manager.

To prepare your device to be managed by the Red Hat Edge Manager, build a bootc operating system image that has the Red Hat Edge Manager agent. Then build an operating system disk image for your devices.

For more information, see the following sections:

4.3.1. Prerequisites

See the following prerequisites for building a bootc operating system image:

4.3.2. Installing the Red Hat Edge Manager CLI

To install the Red Hat Edge Manager CLI, complete the following steps:

Procedure

  1. Enable the subscription manager for the repository appropriate for your system by running the following command:

    sudo subscription-manager repos --enable ansible-automation-platform-2.5-for-rhel-9-x86_64-rpms
    Copy to Clipboard Toggle word wrap

    For a full list of available repositories for the Red Hat Edge Manager, see the Additional resources section.

  2. Install the flightctl CLI with your package manager by running the following command:

    sudo dnf install flightctl
    Copy to Clipboard Toggle word wrap

If you set up the OAuth application manually, you also need to make sure that one utility xdg-open, x-www-browser, or www-browser is available, for example, by installing xdg-utils.

How you log in the Red Hat Edge Manager depends on whether you choose the automatic or manual method when you initially set up the application.

Procedure

  • If you use the automatic setup you can create a personal access token, even only with Read scope (under the profile icon in the top right corner of your Ansible Automation Platform UI > User details > Tokens tab) and then use this token to log in directly through the CLI, with the following example syntax:

    flightctl login https://<your-edge-manager-ip-or-domain>:3443 --token=<your-aap-oauth-token> --insecure-skip-tls-verify
    Copy to Clipboard Toggle word wrap
  • If you use the manual setup, use the Client ID to log in through a web-based process, with the following example syntax:

    flightctl login https://<your-edge-manager-ip-or-domain>:3443 --web --client-id=<your-aap-client-id> --insecure-skip-tls-verify
    Copy to Clipboard Toggle word wrap
    • This opens in a web browser and asks you to approve.

      The --insecure-skip-tls-verify parameter is used only if you have not generated your own valid certificates.

Next steps

Use the following commands to help you with the CLI:

  • To output a list of available commands, use:

    flightctl
    Copy to Clipboard Toggle word wrap
  • To output both the flightctl CLI version and the back-end Red Hat Edge Manager version, use:

    flightctl version
    Copy to Clipboard Toggle word wrap
Important

To ensure supportability and proper functionality, the version of the flightctl CLI must match the version of the Red Hat Edge Manager in use. Mismatched versions are not supported.

If you want to include an agent configuration in the image, complete the following steps:

Procedure

  1. Log in to the flightctl CLI by following the steps in Logging into the Red Hat Edge Manager through the CLI.

    Note

    The CLI uses the certificate authority pool of the host to verify the identity of the Red Hat Edge Manager service. The verification can lead to a TLS verification error when using self-signed certificates, if you do not add your certificate authority certificate to the pool. You can bypass the server verification by adding the --insecure-skip-tls-verify flag to your command.

  2. Get the enrollment credentials in the format of an agent configuration file by running the following command:

    flightctl certificate request --signer=enrollment --expiration=365d --output=embedded > config.yaml
    Copy to Clipboard Toggle word wrap
    Note
    • The --expiration=365d option specifies that the credentials are valid for a year.
    • The --output=embedded option specifies that the output is an agent configuration file with the enrollment credentials embedded.

    The returned config.yaml contains the URLs of the Red Hat Edge Manager service, the certificate authority bundle, and the enrollment client certificate and key for the agent. See the following example:

    enrollment-service:
      authentication:
        client-certificate-data: LS0tLS1CRUdJTiBD...
        client-key-data: LS0tLS1CRUdJTiBF...
      service:
        certificate-authority-data: LS0tLS1CRUdJTiBD...
        server: https://agent-api.flightctl.127.0.0.1.nip.io:7443
      enrollment-ui-endpoint: https://ui.flightctl.127.0.0.1.nip.io:8081
    Copy to Clipboard Toggle word wrap

4.3.5. Optional: Using image pull secrets

If your device relies on containers from a private repository, you must configure a pull secret for the registry. Complete the following steps:

Procedure

  1. Depending on the kind of container image you use, place the pull secret in one or both of the following system paths on the device:

    • Operating system images use the /etc/ostree/auth.json path.
    • Application container images use the /root/.config/containers/auth.json path.

      Important

      The pull secret must exist on the device before the secret can be consumed.

  2. Ensure that the pull secrets use the following format:

    {
      "auths": {
        "registry.example.com": {
          "auth": "base64-encoded-credentials"
        }
      }
    }
    Copy to Clipboard Toggle word wrap

For more information, see the Additional resources section.

Build the operating system image with the bootc that contains the Red Hat Edge Manager agent. You can optionally include the following items in your operating system image:

  • The agent configuration for early binding
  • Any drivers
  • Host configuration
  • Application workloads that you need

Complete the following steps:

Procedure

  1. Create a Containerfile file with the following content to build a RHEL 9-based operating system image that includes the Red Hat Edge Manager agent and configuration:

    FROM registry.redhat.io/rhel9/rhel-bootc:<required_os_version> 
    1
    
    RUN dnf --enablerepo ansible-automation-platform-2.5-for-rhel-9-x86_64-rpms -y install flightctl-agent-0.7.2-1.el9fc  && \
        dnf -y clean all && \
        systemctl enable flightctl-agent.service && \
        systemctl mask bootc-fetch-apply-updates.timer  
    2
    Copy to Clipboard Toggle word wrap
    1
    The base image that is referenced in FROM is a bootable container (bootc) image that already has a Linux kernel, which allows you to reuse existing standard container build tools and workflows.
    2
    Disables the default automatic updates. The updates are managed by the Red Hat Edge Manager.
    Important

    If your device relies on containers from a private repository, you must place the device pull secret in the /etc/ostree/auth.json path. The pull secret must exist on the device before the secret can be consumed.

    • Optional: To enable podman-compose application support, add the following section to the Containerfile file:

      RUN dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \
          dnf -y install podman-compose && \
          dnf -y clean all && \
          systemctl enable podman.service
      Copy to Clipboard Toggle word wrap
    • Optional: If you created the config.yaml for early binding, add the following section to the Containerfile:

      ADD config.yaml /etc/flightctl/
      Copy to Clipboard Toggle word wrap

    For more information, see Optional: Requesting an enrollment certificate for early binding.

  2. Define the Open Container Initiative (OCI) registry by running the following command:

    OCI_REGISTRY=registry.redhat.io
    Copy to Clipboard Toggle word wrap
  3. Define the image repository that you have permissions to write to by running the following command:

    OCI_IMAGE_REPO=${OCI_REGISTRY}/<your_org>/<your_image>
    Copy to Clipboard Toggle word wrap
  4. Define the image tag by running the following command:

    OCI_IMAGE_TAG=v1
    Copy to Clipboard Toggle word wrap
  5. Build the operating system image for your target platform:

    sudo podman build -t ${OCI_IMAGE_REPO}:${OCI_IMAGE_TAG} .
    Copy to Clipboard Toggle word wrap

To sign the bootc operating system image by using Sigstore, complete the following steps:

Procedure

  1. Generate a Sigstore key pair named signingkey.pub and signingkey.private:

    skopeo generate-sigstore-key --output-prefix signingkey
    Copy to Clipboard Toggle word wrap
  2. Configure container tools such as Podman and Skopeo to upload Sigstore signatures together with your signed image to your OCI registry:

    sudo tee "/etc/containers/registries.d/${OCI_REGISTRY}.yaml" > /dev/null <<EOF
    docker:
        ${OCI_REGISTRY}:
            use-sigstore-attachments: true
    EOF
    Copy to Clipboard Toggle word wrap
  3. Log in to your OCI registry by running the following command:

    sudo podman login ${OCI_REGISTRY}
    Copy to Clipboard Toggle word wrap
  4. Sign and publish the operating system image by running the following command:

    sudo podman push \
        --sign-by-sigstore-private-key ./signingkey.private \
        ${OCI_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

4.3.8. Building the operating system disk image

Build the operating system disk image that contains the file system for your devices.

Complete the following steps:

Procedure

  1. Create a directory called output by running the following command:

    mkdir -p output
    Copy to Clipboard Toggle word wrap
  2. Use bootc-image-builder to generate an operating system disk image of type iso from your operating system image by running the following command:

    sudo podman run --rm -it --privileged --pull=newer \
        --security-opt label=type:unconfined_t \
        -v "${PWD}/output":/output \
        -v /var/lib/containers/storage:/var/lib/containers/storage \
        registry.redhat.io/rhel9/bootc-image-builder:latest \
        --type iso \
        ${OCI_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

When the bootc-image-builder completes, you can find the ISO disk image at the ${PWD}/output/bootiso/install.iso path.

Sign and publish your disk image to your Open Container Initiative (OCI) registry. Optionally, you can compress and publish the disk image as an OCI artifact to the same OCI registry as your bootc images, which facilitates a unified hosting and distribution of bootc and disk images. To publish your ISO disk image to a repository named after your bootc image with /diskimage-iso appended.

Prerequisites

Sign and publish your disk image to your OCI registry by completing the following steps:

Procedure

  1. Change the owner of the directory where the ISO disk image is located from root to your current user by running the following command:

    sudo chown -R $(whoami):$(whoami) "${PWD}/output"
    Copy to Clipboard Toggle word wrap
  2. Define the OCI_DISK_IMAGE_REPO environmental variable to be the same repository as your bootc image with /diskimage-iso appended by running the following command:

    OCI_DISK_IMAGE_REPO=${OCI_IMAGE_REPO}/diskimage-iso
    Copy to Clipboard Toggle word wrap
  3. Create a manifest list by running the following command:

    sudo podman manifest create \
        ${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap
  4. Add the ISO disk image to the manifest list as an OCI artifact by running the following command:

    sudo podman manifest add \
        --artifact --artifact-type application/vnd.diskimage.iso \
        --arch=amd64 --os=linux \
        ${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG} \
        "${PWD}/output/bootiso/install.iso"
    Copy to Clipboard Toggle word wrap
  5. Sign the manifest list with your private Sigstore key and push the image to the registry by running the following command:

    sudo podman manifest push --all \
         --sign-by-sigstore-private-key ./signingkey.private \
        ${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG} \
        docker://${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

4.3.10. Additional resources

4.3.11. Requirements for specific target platforms

See the following platform considerations:

When building operating system images and disk images for Red Hat OpenShift Virtualization, you can follow the generic image building process with the following changes:

  • Using late binding by injecting the enrollment certificate or the agent configuration through cloud-init when provisioning the virtual device.
  • Adding the open-vm-tools guest tools to the image.
  • Building a disk image of type qcow2 instead of iso.

Complete the generic steps with changes to the following steps:

Procedure

  1. Build an operating system image based on RHEL 9 that includes the Red Hat Edge Manager agent and VM guest tools but excludes the agent configuration.
  2. Create a file named Containerfile with the following content:

    FROM registry.redhat.io/rhel9/bootc-image-builder:latest
    RUN subscription-manager repos --enable ansible-automation-platform-2.5-for-rhel-9-x86_64-rpms
        dnf -y install flightctl-agent && \
        dnf -y clean all && \
        systemctl enable flightctl-agent.service
    RUN dnf -y install cloud-init open-vm-tools && \
        dnf -y clean all && \
        ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \
        systemctl enable vmtoolsd.service
    Copy to Clipboard Toggle word wrap
  3. Optional: To enable podman-compose application support, add the following section to the Containerfile file:

    RUN dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \
        dnf -y install podman-compose && \
        dnf -y clean all && \
        systemctl enable podman.service
    Copy to Clipboard Toggle word wrap

4.3.11.2. Building the bootc image

Build, sign, and publish the bootc operating system image by following the generic image building process:

Procedure

  1. Create a directory called output by running the following command:

    mkdir -p output
    Copy to Clipboard Toggle word wrap
  2. Generate an operating system disk image of type vmdk from your operating system image by running the following command:

    sudo podman run --rm -it --privileged --pull=newer \
        --security-opt label=type:unconfined_t \
        -v "${PWD}/output":/output \
        -v /var/lib/containers/storage:/var/lib/containers/storage \
        registry.redhat.io/rhel9/bootc-image-builder:latest \
        --type qcow2 \
        ${OCI_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

When the bootc-image-builder completes, you can find the disk image under ${PWD}/output/vmdk/disk.vmdk.

4.3.11.3. Building the QCoW2 disk image

Red Hat OpenShift Virtualization can download disk images from an OCI registry but it expects a container disk image instead of an OCI artifact.

Complete the following steps to build, sign, and upload the QCoW2 disk image:

Procedure

  1. Create a file called Containerfile.qcow2 with the following content:

    FROM registry.access.redhat.com/ubi9/ubi:latest AS builder
    ADD --chown=107:107 output/qcow2/disk.qcow2 /disk/ 
    1
    
    RUN chmod 0440 /disk/* 
    2
    
    FROM scratch
    COPY --from=builder /disk/* /disk/ 
    3
    Copy to Clipboard Toggle word wrap
    1
    Adds the QCoW2 disk image to a builder container to set the required 107 file ownership, which is the QEMU user.
    2
    Sets the required 0440 file permissions.
    3
    Copies the file to a scratch image.
  2. Build, sign, and publish your disk image by running the following command:

    sudo chown -R $(whoami):$(whoami) "${PWD}/output"
    OCI_DISK_IMAGE_REPO=${OCI_IMAGE_REPO}/diskimage-qcow2
    sudo podman build -t ${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG} -f Containerfile.qcow2 .
    sudo podman push --sign-by-sigstore-private-key ./signingkey.private ${OCI_DISK_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

4.3.11.4. Building images for VMware vSphere

When building operating system images and disk images for VMware vSphere, you can follow the generic image building process with the following changes:

  • Using late binding by injecting the enrollment certificate or the agent configuration through cloud-init when provisioning the virtual device.
  • Adding the open-vm-tools guest tools to the image.
  • Building a disk image of type vmdk instead of iso.

Complete the generic steps with changes to the following steps:

Procedure

  1. Build an operating system image based on RHEL 9 that includes the Red Hat Edge Manager agent and VM guest tools but excludes the agent configuration.
  2. Create a file named Containerfile with the following content:

    FROM registry.redhat.io/rhel9/bootc-image-builder:latest
    RUN subscription-manager repos --enable ansible-automation-platform-2.5-for-rhel-9-x86_64-rpms
        dnf -y install flightctl-agent && \
        dnf -y clean all && \
        systemctl enable flightctl-agent.service && \
    RUN dnf -y install cloud-init open-vm-tools && \
        dnf -y clean all && \
        ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \
        systemctl enable vmtoolsd.service
    Copy to Clipboard Toggle word wrap
  3. Create a directory called output by running the following command:

    mkdir -p output
    Copy to Clipboard Toggle word wrap
  4. Generate an operating system disk image of type vmdk from your operating system image by running the following command:

    sudo podman run --rm -it --privileged --pull=newer \
        --security-opt label=type:unconfined_t \
        -v "${PWD}/output":/output \
        -v /var/lib/containers/storage:/var/lib/containers/storage \
        registry.redhat.io/rhel9/bootc-image-builder:latest \
        --type vmdk \
        ${OCI_IMAGE_REPO}:${OCI_IMAGE_TAG}
    Copy to Clipboard Toggle word wrap

When the bootc-image-builder completes, you can find the disk image under ${PWD}/output/vmdk/disk.vmdk.

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat