For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/de/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/de/llms-full.txt, and this page is available as Markdown at https://docs.ovhcloud.com/de/guides/hosted-private-cloud/opcp/how-to-create-centos-image.md.

Building CentOS Stream images with Disk Image Builder for OPCP

Als Markdown ansehen

Find out how to build custom CentOS Stream 8 and 9 OpenStack images with diskimage-builder (DiB) for On-Prem Cloud Platform

Objective

Disk Image Builder (DiB) is the OpenStack tool used to build custom operating system disk images. This guide shows how to build CentOS Stream 8 and CentOS Stream 9 images that are ready to be imported into OpenStack Glance and used on your On-Prem Cloud Platform (OPCP).

This guide explains how to install DiB, prepare custom elements that work around a known CentOS issue, and run the build for both CentOS Stream 8 and CentOS Stream 9.

For a different example using Debian and Ansible-based customization, see Building a custom Debian image for OPCP.

Info

In this guide we use Debian 12 as the build host to produce CentOS images, but you can use another Linux distribution (adjustments may be required). You can also adapt the paths and commands shown here to match your needs.

Requirements

  • Root permissions on the build host
  • At least 10 GB of free disk space
  • A Debian 12 (or compatible) Linux environment to run the build from
  • Access to the internet to download packages and the upstream CentOS mirrors

Instructions

Step 1: Install the build requirements

Install the components required by DiB to build CentOS, Debian and Ubuntu based images:

apt update
apt install -y \
  dosfstools \
  python3 \
  python3-venv \
  python3-pip \
  virtualenv \
  kpartx \
  debootstrap \
  lvm2 \
  squashfs-tools \
  git \
  qemu-utils \
  qemu-system-x86 \
  curl
Info

git is needed to clone the DiB repository, qemu-utils provides the qemu-img tooling used to handle qcow2 images, qemu-system-x86 provides qemu-system-x86_64 used in Step 7 to test the result, and curl is used to download packages and mirror content during the build.

Step 2: Install Disk Image Builder

Create and activate a Python virtual environment:

virtualenv ~/env-diskimage-builder
source ~/env-diskimage-builder/bin/activate

Clone the DiB repository on a specific tag and install it. In this example we use version 3.42.0:

git clone --depth 1 --branch 3.42.0 https://opendev.org/openstack/diskimage-builder ~/diskimage-builder
pip install -e ~/diskimage-builder

Check that disk-image-create is available:

disk-image-create --version

Step 3: Create the folder tree

Create the working directories used by the build:

mkdir -p ~/dib                  # main folder
mkdir -p ~/dib/tmp-build-dir    # temporary folder used during the build
mkdir -p ~/dib/elements         # folder storing the custom elements used by DiB
mkdir -p ~/dib/env              # folder storing the custom variables per OS distribution

Step 4: Define the custom elements

CentOS builds require two custom elements that work around current limitations of the upstream DiB elements.

Custom element: block-device-efi-custom

The default block-device-efi element creates an ESP (EFI System Partition) that is larger than needed. Create a custom element based on it and resize the partition from 550 MiB to 512 MiB:

cp -pR ~/diskimage-builder/diskimage_builder/elements/block-device-efi ~/dib/elements/block-device-efi-custom
sed -i -e 's/550/512/' ~/dib/elements/block-device-efi-custom/block-device-default.yaml

Custom element: centos-custom

The default centos element has an issue that is not fixed yet. Create a custom element based on it to apply the required hotfix:

cp -pR ~/diskimage-builder/diskimage_builder/elements/centos ~/dib/elements/centos-custom

sed -i \
  -e 's/centos.repo/*.repo/' \
  -e 's/centos-addons.repo/*.repo/' \
  -e 's/CentOS-Stream-BaseOS.repo/*.repo/' \
  -e 's/CentOS-Stream-AppStream.repo/*.repo/' \
  -e 's/CentOS-Stream-Extras.repo/*.repo/' \
  -e 's/CentOS-Stream-PowerTools.repo/*.repo/' \
  -e 's/CentOS-Linux-BaseOS.repo/*.repo/' \
  -e 's/CentOS-Linux-AppStream.repo/*.repo/' \
  -e 's/CentOS-Linux-Extras.repo/*.repo/' \
  -e 's/CentOS-Linux-PowerTools.repo/*.repo/' \
  -e 's/CentOS-Linux-Plus.repo/*.repo/' \
  ~/dib/elements/centos-custom/pre-install.d/00-02-set-centos-mirror

Step 5: Build a CentOS Stream 8 image

Info

For CentOS Stream 8, the default user created by cloud-init is centos.

Create the environment variables

mkdir -p ~/dib/env/centos8

cat <<EOF > ~/dib/env/centos8/main.env
export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive, OpenStack"
export DIB_GRUB_TIMEOUT=10
export DIB_DISTRIBUTION_MIRROR=http://vault.centos.org/centos
export DIB_RELEASE=8-stream
export DIB_BOOTLOADER_DEFAULT_CMDLINE="nofb nomodeset gfxpayload=text rd.auto"
export DIB_DRACUT_ENABLED_MODULES="
- name: crypt
  packages:
    - cryptsetup
- name: lvm
  packages:
    - lvm2
- name: mdraid
  packages:
    - mdadm
"
EOF

Run the build

Unset any previously defined variable, source the environment file, then run the build:

unset DIB_CLOUD_INIT_DATASOURCES
unset DIB_GRUB_TIMEOUT
unset DIB_DISTRIBUTION_MIRROR
unset DIB_RELEASE
unset DIB_BOOTLOADER_DEFAULT_CMDLINE
unset DIB_DRACUT_ENABLED_MODULES

source ~/dib/env/centos8/main.env

cd ~/dib

export TMPDIR="$(pwd)/tmp-build-dir"
export ELEMENTS_PATH="$(pwd)/elements"

disk-image-create --no-tmpfs -t qcow2 --image-size 16GB -a amd64 \
  dracut-regenerate block-device-efi-custom bootloader \
  cloud-init-datasources centos-custom \
  -o my-centos8-image

Once the build completes, check the output files:

ls my-centos8-image*
my-centos8-image.qcow2

my-centos8-image.d:
dib-manifests

Step 6: Build a CentOS Stream 9 image

Info

For CentOS Stream 9, the default user created by cloud-init is cloud-user.

Create the environment variables

mkdir -p ~/dib/env/centos9

cat <<EOF > ~/dib/env/centos9/main.env
export DIB_GRUB_TIMEOUT=10
export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive, OpenStack"
export DIB_RELEASE=9-stream
export DIB_BOOTLOADER_DEFAULT_CMDLINE="nofb nomodeset gfxpayload=text rd.auto"
export DIB_DRACUT_ENABLED_MODULES="
- name: crypt
  packages:
    - cryptsetup
- name: lvm
  packages:
    - lvm2
- name: mdraid
  packages:
    - mdadm
"
EOF

Run the build

unset DIB_CLOUD_INIT_DATASOURCES
unset DIB_GRUB_TIMEOUT
unset DIB_DISTRIBUTION_MIRROR
unset DIB_RELEASE
unset DIB_BOOTLOADER_DEFAULT_CMDLINE
unset DIB_DRACUT_ENABLED_MODULES

source ~/dib/env/centos9/main.env

cd ~/dib

export TMPDIR="$(pwd)/tmp-build-dir"
export ELEMENTS_PATH="$(pwd)/elements"

disk-image-create --no-tmpfs -t qcow2 --image-size 16GB -a amd64 \
  dracut-regenerate block-device-efi-custom bootloader \
  cloud-init-datasources centos-custom \
  -o my-centos9-image

Once the build completes, check the output files:

ls my-centos9-image*
my-centos9-image.qcow2

my-centos9-image.d:
dib-manifests

Step 7 (optional): Test the image locally

Before uploading the image, you can boot it locally with QEMU to make sure it starts correctly:

qemu-system-x86_64 -nographic \
  -m 2048 \
  -drive file=my-centos9-image.qcow2,if=virtio,format=qcow2

Step 8: Upload the image to OpenStack

Import the generated qcow2 image into Glance:

openstack image create \
  --disk-format qcow2 \
  --container-format bare \
  --file my-centos9-image.qcow2 \
  my-centos9-image

You can now create a Bare Metal (Ironic) or Compute (Nova) instance from the newly created image.

Troubleshooting

The image does not boot (emergency mode) or the build fails on grub2-probe

Symptoms

The error can show up in two different places:

During the build, at the grub step:

/usr/sbin/grub2-probe: error: ../grub-core/kern/fs.c:120:unknown filesystem.

When booting an instance, the boot does not complete and drops into "emergency" mode. journalctl shows filesystem errors:

/dev/vda3 has unsupported feature(s): FEATURE_C12
e2fsck: Get a newer version of e2fsck!
fsck failed with exit status 12

Cause

The issue is related to the version of e2fsprogs, used by the mke2fs, e2fsck and grub2-probe commands.

disk-image-builder formats the root partition with the mkfs.ext4 of the build machine, not the one from the target image. If the build host runs a recent e2fsprogs (version above 1.47), some ext4 features are enabled by default when the filesystem is created:

  • metadata_csum_seed
  • orphan_file

These features are too recent for the e2fsprogs/grub2 shipped with CentOS 8 or 9, which causes the errors described above.

Solution

Disable these features when the filesystem is created, using the --mkfs-options option of disk-image-create:

disk-image-create --no-tmpfs -t qcow2 --image-size 16GB -a amd64 \
  --mkfs-options "-O ^metadata_csum_seed,^orphan_file" \
  dracut-regenerate block-device-efi-custom bootloader \
  cloud-init-datasources centos-custom \
  -o my-centos-image

Go further

If you need training or technical assistance to implement our solutions, contact your sales representative or click on this link to get a quote and ask our Professional Services experts to assist you on the specific use case of your project.

Join our community of users.

War diese Seite hilfreich?