I’d like to dig deep, on diskimage-builder – the OpenStack tool for creating customized images to boot. In this three part series, I’ll be primarily doing this to create UEFI bootable baremetal images. We’ll start with RHEL 7.5, as this is my favorite. Join me!
Down with the DIB
So you want to UEFI boot bare metal nodes in OpenStack? You want to build a customized image of RHEL to do this? There are many ways to achieve this, from the janky to the kinda janky – to the fully automated and rocking way. We’re going for the later here. We don’t have much time for jank, we’re looking to build a RHEL 7.5 image with diskimage-builder. For the sake of my fingers, I have a lot of jazz to play after this, let’s just refer to diskimage-builder as DIB. Plus – we all know there aren’t enough acronyms in this field.
DIB has a fairly large scope, as it portends to be able to allow you to build bootable images for the following Linux distros:Centos 6, 7
Debian 8 (“jessie”)
Fedora 26, 27
RHEL 6, 7
Ubuntu 12.04 (“precise”), 14.04 (“trusty”)
openSUSE Leap 42.2, 42.3 and Tumbleweed (opensuse-minimal only)
That’s a whole-lotta Linux there. Of course, here, we only really care about Fedora, CentOS and RHEL. I may be able to show you the Ubuntu version of this, but let’s see how far we can get.
Ordinarily, you’d think this process would be pretty straight forward, but as with many open source tools, the amount of complexity is directly proportionate to the amount of options you get. And here, my dear Linux friends, we have a ton of options.
It’s nice to have goals
So I’m thinking the best way to approach this is to scope this to a few specific goals. Here’s what I have in mind:
- Create a bootable UEFI RHEL 7 image
- Register it with the Red Hat customer portal during the build
- Subscribe to some repos
- Install some packages
- Run some custom code therein
- Create a baremetal instance – booting off of UEFI
These are our goals, let’s get to them and see where this leads us. Our voodoo will be strong, as we have lot of ground to cover — and many elements to explore.
First up, let’s make sure we start in the right place. I’m building here from my Red Hat OpenStack 13 Director environment. DIB is part of this environment, so building here won’t require us to install anything. Additionally, we’ll be uploading our images into glance in the undercloud, and just booting a baremetal node with ironic to test.
Let’s start by creating a working directory in the stack user’s home:
$ mkdir -p ~/scripts/dib
Next, we’ll just create a simple bash script to run our build:
# Red Hat portal creds
# our method for registering the image
# repos that will be enabled in the image
# auto attach the pool repos
# local image location - download the RHEL 7.5 KVM image from http://access.redhat.com
# build the image
openstack overcloud image build --config-file ./rhel7.yaml
Ok – let’s step through this:
- We’re sourcing our portal credentials, which should be in an external file called secret.sh, in the following format:
1234#!/bin/bashexport REG_POOL_ID='<your-pool-id>'export REG_PASSWORD='<your-portal-pass>'export REG_USER='<your-portal-username>'
- Next, we set the set the
- We create a comma separated list of repos we’d like to enable using the
REG_REPOSvariable – these are examples of the bare minimum for RHEL 7
- We set
REG_AUTO_ATTACHto true. This sets our image up to use the pool-id and repos
- Next, we want to get the latest RHEL 7.5 KVM image from https://access.redhat.com, save it locally, and refer to it using the
- Set the subscription’s registered machine name for this image using the
- Finally, we kick off the build using the
openstack overcloud image buildcommand, referencing our custom
rhel7.yaml template looks like this:
This is yaml, so it’s important that you obey the yaml syntax structure. Let’s go over each of the attributes:
imagename – This is what your resulting image will be called
type – the ouput format of your image – we wan’t qcow2 for OpenStack
arch – this is the architecture you’ll be booting this image on – amd64 is ours
distro – this is a
DIB keyword that specifically refers to Red Hat Enterprise Linux 7
elements – A list of elements you’d like to enable for your image.
DIB uses this construct to modify your image and customize it. The full list of available elements can be found here: https://docs.openstack.org/diskimage-builder/latest/elements.html
Rather than go into detail on each one of these, I’ll leave it to the reader to do so in their spare time. This is quite a lot of information, some of which is specific to the
distrothat you’re using. I suggest you look at some of these to gain better insight into this process. Suffice it to say that
baremetal are key elements here. Specifically,
baremetalwill build three binaries for us – a qcow2 image, a vmlinuz image and an initrd image. We’ll load all of these into glance and use them to UEFI boot our baremetal node.
packages – A list of package names we’d like to install into the image. These are synonymous with
yum install package-name
options – A list of options to pass to
disk-image-create command. Here, we set the minimum in GB that the tool will use in tmpfs to build the image.
environment – These will set specific environment variables for us – in this case, our filesystem and python version. For this image, these are safe defaults.
Time to build
So, we have our yaml, our build script and our base image. Let’s go ahead and run build-rhel.sh to build our image.
$ sh ./build-rhel.sh
I prefer to run tmux before I do this, in case anything happens to our terminal session, be it local or remote. You can also use screen, if you’re more accustomed to it.
Once this image builds, and it will take a while, you should end up with a few files:
rhel-7.5.qcow2 – this is the actual image of the filesystem
rhel-7.5.initrd – the initial ramdisk image you’ll boot on your baremetal uefi boot
rhel-7.5.vmlinuz – the compressed linux kernel image, used on your baremetal node
Get thee into Glance
So we have our image, and we’re ready to test it on a baremetal node. What need to do first, is to load it into glance in the undercloud. Additionally, we’ll need to associate our initrd and vmlinuz images with our qcow2 as well. This can be accomplished thusly:
NOTE: I’m loading these into my undercloud here – you can do the same with your overcloud, just be sure to source the right rc file in the stack user’s home directory
Let’s start with the kernel:
$ KERNEL_ID=$(openstack image create --file ./rhel-7.5.vmlinuz --public --container-format aki --disk-format aki -f value -c id rhel-7.5.vmlinuz)
We’re setting the variable
KERNEL_ID to be our rhel-7.5.vmlinuz file.
Next, let’s work with the initial ramdisk:
$ RAMDISK_ID=$(openstack image create --file ./rhel-7.5.initrd --public \
--container-format ari \
--disk-format ari -f value -c \
This will set the
RAMDISK_ID to our newly created rhel-7.5.initrd file.
Finally, we’ll load our image into glance:
$ source ~/stackrc
$ openstack image create --file ./images/rhel-7.5.qcow2 \
--public --container-format bare \
--disk-format qcow2 --property kernel_id=$KERNEL_ID \
--property ramdisk_id=$RAMDISK_ID rhel-7.5
We should see something list return, or using the command
openstack image list
| ID | Name | Status |
| 44baad76-2975-44f1-b4f4-f63cbe8dd5aa | bm-deploy-kernel | active |
| b7c9dbf0-0aa6-4721-9e6f-1b9c83df571a | bm-deploy-ramdisk | active |
| 13fa5447-06b7-4a7f-83c3-5a0ef570f505 | overcloud-full | active |
| 4ea56372-0864-4fc1-b0f4-aa2abd0021e6 | overcloud-full-initrd | active |
| ff5d4629-4d15-412b-9927-35adb9937c86 | overcloud-full-vmlinuz | active |
| 73b38dcf-256f-4f48-b065-11abb808ef6a | rhel-7.5 | active |
| f2789f70-644f-48e4-8ef8-a91f0cd268bc | rhel-7.5.initrd | active |
| f9950ca2-4020-40db-b300-7b21c3c1c81e | rhel-7.5.vmlinuz | active |
Boot me up, Scotty
Ok, so we’re ready to boot with our image and test UEFI booting a baremetal node in Red Hat OpenStack 13. I’m going to use our compute flavor, as I’ve already introspected my baremetal node and tagged it as a compute node:
openstack server create --flavor compute --image rhel-7.5 --network ctlplane --key-name default myrhel
You should now be able to see this boot at the console. Good times!
I’d be remiss if I didn’t mention a couple of items –
- If you kill your build, or if it fails on you, you will end up with a bunch of tmpfs filesystems taking up all of your memory. If you don’t unmount these prior to re-starting your next build, you’ll end up in a world of hurt. I actually took down my undercloud by doing this. Your best course of action is lazy unmount them like so –
sudo umount -l /tmp/dib*
- Watch your disk space here – you don’t want to fill up your root partition on the undercloud. This can cause all sorts of whacky stuff to happen and potentially destroy your undercloud.
df -his your friend
- Chmod 0600 your secrets file. As we’re doing this with bash and have this file with your secrets as an open text file – at least chmod it with reasonable defaults to keep it unreadable by prying eyes. Better yet, remove it after your build.
There’s a lot to take in here, and a lot more to come. I’ve decided to break this into three different posts. This is just an introduction of sorts. Stay tuned with a post on developing your own elements for DIB, as well as a final post about integrating Ansible – Red Hat’s awesome orchestration tool.