OpenStack Ironic Images and Flavors

Building images and crafting flavors is non-trivial. I've searched the world wide web for prebuilt images which universally work with Ironic and sadly there's nothing out there. So without further ado here is how you can build your own images and create a flavor.

Building Ironic Images

Building images using the Disk Image Builder (DIB) is by far the easiest way to craft Images for Ironic. If you are deploying this all within an OpenStack-Ansible deployment ecosystem the installation tools and the subsequent running of these tools need to be installed and executed outside of a container. I'd recommend using a compute or cinder node because OpenStack client access will have already been setup on those nodes.

Install required apt packages
apt-get install -y qemu uuid-runtime curl kpartx

Install the disk-image-builder (DIB)

pip install diskimage-builder --isolated

If you're deployment will be using HP servers (Proliant) you're going to want to include the HP tools in your disk image.

# Export a few variables used to provide debug access to the deploy image
DIB_DEV_USER_USERNAME=debug-user  
DIB_DEV_USER_PASSWORD=secrete  
DIB_DEV_USER_PWDLESS_SUDO=yes

# This URL is subject to change, in the after now
#  it may be different. Please set this accordingly.
export DIB_HPSSACLI_URL="http://downloads.hpe.com/pub/softlib2/software1/pubsw-linux/p1857046646/v109216/hpssacli-2.30-6.0.x86_64.rpm"

# If you're running Ironic <=newton you should use the
#  newton version of IPA.
export IRONIC_AGENT_VERSION="stable/newton"

# NOTE THIS IS USING "fedora" ON PURPOSE.
#  The proliant tools only have a pre-built RPM.
#  While you can provision other Linux Operating
#  systems the "deploy image" will NEED to be "fedora".
disk-image-create --install-type source -o ironic-deploy ironic-agent fedora devuser proliant-tools

Create Ubuntu deploy images and upload them into glance
# Export a few variables used to provide debug access to the deploy image
DIB_DEV_USER_USERNAME=debug-user
DIB_DEV_USER_PASSWORD=secrete
DIB_DEV_USER_PWDLESS_SUDO=yes

# Create the deploy image and initramfs
disk-image-create --install-type source -o ironic-deploy ironic-agent ubuntu devuser

# Upload the deploy image kernel
glance image-create --name ironic-deploy.kernel \
                    --visibility public \
                    --disk-format aki \
                    --property hypervisor_type=baremetal \
                    --protected=True \
                    --container-format aki < ironic-deploy.kernel

# Upload the user image initramfs
glance image-create --name ironic-deploy.initramfs \
                    --visibility public \
                    --disk-format ari \
                    --property hypervisor_type=baremetal \
                    --protected=True \
                    --container-format ari < ironic-deploy.initramfs
Create Ubuntu user images and upload them into glance.

When the images are uploaded to glance the image will use have the property hypervisor_type=baremetal set allowing image and hypervisor isolation from the very beginning.

# Set the release
export DIB_RELEASE=xenial
export DISTRO_NAME=ubuntu

# Create the image
DIB_CLOUD_INIT_DATASOURCES="Ec2, ConfigDrive, OpenStack" disk-image-create -o baremetal-$DISTRO_NAME-$DIB_RELEASE $DISTRO_NAME baremetal bootloader

# Upload the user image vmlinuz and store uuid
VMLINUZ_UUID="$(glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE.vmlinuz \
                                    --visibility public \
                                    --disk-format aki \
                                    --property hypervisor_type=baremetal \
                                    --protected=True \
                                    --container-format aki < baremetal-$DISTRO_NAME-$DIB_RELEASE.vmlinuz | awk '/\| id/ {print $4}')"

# Upload the user image initrd and store uuid
INITRD_UUID="$(glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE.initrd \
                                   --visibility public \
                                   --disk-format ari \
                                   --property hypervisor_type=baremetal \
                                   --protected=True \
                                   --container-format ari < baremetal-$DISTRO_NAME-$DIB_RELEASE.initrd | awk '/\| id/ {print $4}')"

# Create image
glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE \
                    --visibility public \
                    --disk-format qcow2 \
                    --container-format bare \
                    --property hypervisor_type=baremetal \
                    --property kernel_id=${VMLINUZ_UUID} \
                    --protected=True \
                    --property ramdisk_id=${INITRD_UUID} < baremetal-$DISTRO_NAME-$DIB_RELEASE.qcow2

If you're building a Ubuntu image using Trusty (14.04) you may need to install extra packages to enable your hardware. In my case I need to use the Xenial LTS kernel.

# Set the release
export DIB_RELEASE=trusty
export DISTRO_NAME=ubuntu

# Create the image
DIB_CLOUD_INIT_DATASOURCES="Ec2, ConfigDrive, OpenStack" disk-image-create -o baremetal-$DISTRO_NAME-$DIB_RELEASE $DISTRO_NAME baremetal bootloader -p linux-image-generic-lts-xenial

# Upload the user image vmlinuz and store uuid
VMLINUZ_UUID="$(glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE.vmlinuz \
                                    --visibility public \
                                    --disk-format aki \
                                    --property hypervisor_type=baremetal \
                                    --protected=True \
                                    --container-format aki < baremetal-$DISTRO_NAME-$DIB_RELEASE.vmlinuz | awk '/\| id/ {print $4}')"

# Upload the user image initrd and store uuid
INITRD_UUID="$(glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE.initrd \
                                   --visibility public \
                                   --disk-format ari \
                                   --property hypervisor_type=baremetal \
                                   --protected=True \
                                   --container-format ari < baremetal-$DISTRO_NAME-$DIB_RELEASE.initrd | awk '/\| id/ {print $4}')"

# Create image
glance image-create --name baremetal-$DISTRO_NAME-$DIB_RELEASE \
                    --visibility public \
                    --disk-format qcow2 \
                    --container-format bare \
                    --property hypervisor_type=baremetal \
                    --property kernel_id=${VMLINUZ_UUID} \
                    --protected=True \
                    --property ramdisk_id=${INITRD_UUID} < baremetal-$DISTRO_NAME-$DIB_RELEASE.qcow2

Creating an Ionic flavor

Ironic flavor types are very specific to the node that is being run. In this example I'm creating a flavor with the following specifications:

Name b1.medium
ID 5150
RAM 256GB
DISK 78GB
VCPUs 48
nova flavor-create b1.medium 5150 254802 78 48

Once the flavor is created we're going to append some metadata to it so that it's compatible with our CPU archetecture and it allows for local boot after a node has been provisioned.

nova flavor-key b1.medium set cpu_arch=x86_64
nova flavor-key b1.medium set capabilities:boot_option="local"

# THIS IS NOT REQUIRED, USE THIS IF YOU NEED A GPT PARTITION TABLE
nova flavor-key b1.medium set capabilities:disk_label="gpt"

With the images uploaded, the flavor(s) created, you are now ready to enroll nodes into Ironic.