Create and Upload Custom Linux Image into OpenStack

|
Last Updated:
|
|

In this tutorial, you will learn how to create and upload custom Linux image into OpenStack. An image is a single file that contains a virtual disk that contains a bootable operating system. It is possible to create your own custom Linux images and upload them to OpenStack for your own use.

Create/Upload Custom Linux Image into OpenStack

By default, when you install OpenStack, it will have a single test image called CirrOS.

You can confirm the same from the OpenStack horizon;

Create and Upload Custom Linux Image into OpenStack

Or, just check available images using openstack command line tool.

source admin-openrc.sh
openstack image list

Sample output;

+--------------------------------------+--------------------------+--------+
| ID                                   | Name                     | Status |
+--------------------------------------+--------------------------+--------+
| 5cad7ba3-851b-4b87-a762-8506cf803965 | cirros-0.5.2-x86_64-disk | active |
+--------------------------------------+--------------------------+--------+

So, in most cases, you might want to create and upload your own custom Linux image into OpenStack.

You can use the images that have already been created or simply create your own custom image and upload it to openstack.

How to Create Your own Custom Linux Image for OpenStack

To create your own custom Linux image for OpenStack;

Download the installation ISO file

Download the installation ISO file for the specific Linux distro you want to use on OpenStack. For example, we will use Ubuntu 22.04 headless server image as an example in this guide.

Install virtualization tool on your host system such as KVM

You need to have virtualization tool such as KVM/VirtualBox etc installed on your host system or somewhere else that enables you to create your custom Linux image.

See example Install KVM on Oracle Linux.

Install the Linux vm on the virtualization tool such as KVM

Once you have virtualization tool and ISO file ready, you need to install the VM and customize it in preparation to upload to OpenStack.

In this guide, we are using KVM as our virtualization platform.

  • Thus, launch the virtual machine manager and create and install new Linux vm as follows;
Create and Upload Custom Linux Image into OpenStack
  • Choose the ISO installation file and select OS type as Generic if not automatically detected.
Create and Upload Custom Linux Image into OpenStack
  • Choose memory and CPU settings;
Create and Upload Custom Linux Image into OpenStack
  • Create a disk image for the virtual machine;
Create and Upload Custom Linux Image into OpenStack
  • Set the name of the VM and click “Customize Configuration before install
Create and Upload Custom Linux Image into OpenStack
  • Click Finish.
  • Change the disk bus type from IDE to VirtIO and apply the changes.
Create and Upload Custom Linux Image into OpenStack
  • Change network interface device model to VirtIO as well;
Create and Upload Custom Linux Image into OpenStack
  • Apply the changes and click Begin the installation.
  • Proceed with the VM installation as usual…
  • Under storage configuration, you can use entire disk and set it as lvm group.
  • create usernames and install SSH
  • and proceed with vm setup on KVM.

Install Cloud-init Package on the Virtual Machine

Cloud-init is the industry standard multi-distribution method for cross-platform cloud instance initialization. It enables you to resize root partition on boot automatically, access instance using ssh public key, update vm hostname to match the name given and process user data and other metadata on the vm.

Once the vm boots, login and install cloud-init package;

sudo apt install cloud-init

/etc/cloud/cloud.cfg is the cloud-init configuration file and this is how it looks by default;

cat /etc/cloud/cloud.cfg
# The top level settings are used as module
# and system configuration.
# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'
# from the distro configuration specified below
users:
   - default


# If this is set, 'root' will not be able to ssh in and they
# will get a message to login instead as the default $user
disable_root: true

# This will cause the set+update hostname module to not operate (if true)
preserve_hostname: false

# If you use datasource_list array, keep array items in a single line.
# If you use multi line array, ds-identify script won't read array items.
# Example datasource config
# datasource:
#    Ec2:
#      metadata_urls: [ 'blah.com' ]
#      timeout: 5 # (defaults to 50 seconds)
#      max_wait: 10 # (defaults to 120 seconds)




# The modules that run in the 'init' stage
cloud_init_modules:
 - migrator
 - seed_random
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - disk_setup
 - mounts
 - set_hostname
 - update_hostname
 - update_etc_hosts
 - ca-certs
 - rsyslog
 - users-groups
 - ssh

# The modules that run in the 'config' stage
cloud_config_modules:
 - snap
 - ssh-import-id
 - keyboard
 - locale
 - set-passwords
 - grub-dpkg
 - apt-pipelining
 - apt-configure
 - ubuntu-advantage
 - ntp
 - timezone
 - disable-ec2-metadata
 - runcmd
 - byobu

# The modules that run in the 'final' stage
cloud_final_modules:
 - package-update-upgrade-install
 - fan
 - landscape
 - lxd
 - ubuntu-drivers
 - write-files-deferred
 - puppet
 - chef
 - mcollective
 - salt-minion
 - reset_rmc
 - refresh_rmc_and_interface
 - rightscale_userdata
 - scripts-vendor
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user
 - ssh-authkey-fingerprints
 - keys-to-console
 - install-hotplug
 - phone-home
 - final-message
 - power-state-change

# System and/or distro specific settings
# (not accessible to handlers/transforms)
system_info:
   # This will affect which distro class gets used
   distro: ubuntu
   # Default user name + that default users groups (if added/used)
   default_user:
     name: ubuntu
     lock_passwd: True
     gecos: Ubuntu
     groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
     sudo: ["ALL=(ALL) NOPASSWD:ALL"]
     shell: /bin/bash
   network:
     renderers: ['netplan', 'eni', 'sysconfig']
   # Automatically discover the best ntp_client
   ntp_client: auto
   # Other config here will be given to the distro class and/or path classes
   paths:
      cloud_dir: /var/lib/cloud/
      templates_dir: /etc/cloud/templates/
   package_mirrors:
     - arches: [i386, amd64]
       failsafe:
         primary: http://archive.ubuntu.com/ubuntu
         security: http://security.ubuntu.com/ubuntu
       search:
         primary:
           - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
           - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
           - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
         security: []
     - arches: [arm64, armel, armhf]
       failsafe:
         primary: http://ports.ubuntu.com/ubuntu-ports
         security: http://ports.ubuntu.com/ubuntu-ports
       search:
         primary:
           - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
           - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
           - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
         security: []
     - arches: [default]
       failsafe:
         primary: http://ports.ubuntu.com/ubuntu-ports
         security: http://ports.ubuntu.com/ubuntu-ports
   ssh_svcname: ssh

In most cases, the default settings works fine.

If you want to update hosts file to use the name of the vm, add the line manage_etc_hosts: true to cloud.cfg file.

Create Custom Linux Image into OpenStack

Copy the Image to OpenStack

Shutdown the virtual machine from the virt-manager or from command line.

On the host running KVM, you can find the image details;

qemu-img info /media/kifarunix/vol02/kvm/images/ubuntu22.04.qcow2
image: /media/kifarunix/vol02/kvm/images/ubuntu22.04.qcow2
file format: qcow2
virtual size: 6 GiB (6442450944 bytes)
disk size: 3.73 GiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: true
    refcount bits: 16
    corrupt: false

Copy its image to OpenStack node;

rsync -avP path/vm-name.qcow2 username@openstack:

You can now either create OpenStack Image from Horizon or create it on command line.

Create Custom Linux Image on OpenStack Horizon

  • Login to horizon as administrator;
  • Select the project, e.g admin project and navigate to Project > Compute > Images > +Create Image or Admin > Compute > Images > +Create Image.
  • Under Image details;
    • Image Name
    • Image Description
    • Image Source > Choose the image from your host or kvm hosts as long as you can access the image.
    • Enter the image format e.g QCOW2 (Use the qemu-img info command to confirm, refer above)
    • Define image requirements, we only set minimum disk and RAM here.
    • Choose your appropriate image visibility. We leave it as public.
    • Protected: No
jellyfish openstack image
  • Under Metadata, we left the defaults.
  • Click Create Image.

After a short while, the image should now be created and available under images;

new openstack image created

Create Custom Linux Image on OpenStack CLI

Shutdown the virtual machine and copy its image to OpenStack node;

rsync -avP path/vm-name.qcow2 username@openstack:

If you are CLI centric, you can create custom Linux image on OpenStack CLI using openstack image create or glance image-create commands;

openstack image create -h
usage: openstack image create [-h] [-f {json,shell,table,value,yaml}] [-c COLUMN] [--noindent] [--prefix PREFIX] [--max-width <integer>] [--fit-width] [--print-empty]
                              [--id <id>] [--container-format <container-format>] [--disk-format <disk-format>] [--min-disk <disk-gb>] [--min-ram <ram-mb>]
                              [--file <file> | --volume <volume>] [--force] [--progress] [--sign-key-path <sign-key-path>] [--sign-cert-id <sign-cert-id>]
                              [--protected | --unprotected] [--public | --private | --community | --shared] [--property <key=value>] [--tag <tag>] [--project <project>]
                              [--import] [--project-domain <project-domain>]
                              <image-name>

Example;

openstack image create \
	--container-format bare \
	--disk-format qcow2 \
	--file ./ubuntu22.04.qcow2 \
	--progress \
	--public \
	--project admin \
	jellyfish

Sample output;

[=============================>] 100%
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Field            | Value                                                                                                                                         |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| container_format | bare                                                                                                                                          |
| created_at       | 2022-10-11T21:17:13Z                                                                                                                          |
| disk_format      | qcow2                                                                                                                                         |
| file             | /v2/images/ba33ea97-710d-4c14-9283-18f27de74e56/file                                                                                          |
| id               | ba33ea97-710d-4c14-9283-18f27de74e56                                                                                                          |
| min_disk         | 0                                                                                                                                             |
| min_ram          | 0                                                                                                                                             |
| name             | jellyfish                                                                                                                                     |
| owner            | a95d364c2b564742b1d3e7da4c8e294e                                                                                                              |
| properties       | os_hidden='False', owner_specified.openstack.md5='', owner_specified.openstack.object='images/jellyfish', owner_specified.openstack.sha256='' |
| protected        | False                                                                                                                                         |
| schema           | /v2/schemas/image                                                                                                                             |
| status           | queued                                                                                                                                        |
| tags             |                                                                                                                                               |
| updated_at       | 2022-10-11T21:17:13Z                                                                                                                          |
| visibility       | public                                                                                                                                        |
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+

To use glance image-create;

glance image-create -h
usage: glance [--version] [-d] [-v] [--get-schema] [-f] [--os-image-url OS_IMAGE_URL] [--os-image-api-version OS_IMAGE_API_VERSION] [--profile HMAC_KEY]
              [--os-region-name OS_REGION_NAME] [--os-auth-token OS_AUTH_TOKEN] [--os-service-type OS_SERVICE_TYPE] [--os-endpoint-type OS_ENDPOINT_TYPE] [--insecure]
              [--os-cacert <ca-certificate>] [--os-cert <certificate>] [--os-key <key>] [--timeout <seconds>] [--collect-timing] [--os-auth-type <name>]
              [--os-auth-url OS_AUTH_URL] [--os-system-scope OS_SYSTEM_SCOPE] [--os-domain-id OS_DOMAIN_ID] [--os-domain-name OS_DOMAIN_NAME]
              [--os-project-id OS_PROJECT_ID] [--os-project-name OS_PROJECT_NAME] [--os-project-domain-id OS_PROJECT_DOMAIN_ID]
              [--os-project-domain-name OS_PROJECT_DOMAIN_NAME] [--os-trust-id OS_TRUST_ID] [--os-default-domain-id OS_DEFAULT_DOMAIN_ID]
              [--os-default-domain-name OS_DEFAULT_DOMAIN_NAME] [--os-user-id OS_USER_ID] [--os-username OS_USERNAME] [--os-user-domain-id OS_USER_DOMAIN_ID]
              [--os-user-domain-name OS_USER_DOMAIN_NAME] [--os-password OS_PASSWORD]
              <subcommand> ...

Once the creation is done, you can list available images;

openstack image list
+--------------------------------------+--------------------------+--------+
| ID                                   | Name                     | Status |
+--------------------------------------+--------------------------+--------+
| 5cad7ba3-851b-4b87-a762-8506cf803965 | cirros-0.5.2-x86_64-disk | active |
| ba33ea97-710d-4c14-9283-18f27de74e56 | jellyfish                | active |
+--------------------------------------+--------------------------+--------+

And that is it.

You should now be able to use the custom image to launch an instance.

Create and Upload Custom Linux Image into OpenStack
Create and Upload Custom Linux Image into OpenStack

Note, the flavor assigned to the instance must be slightly bigger than the virtual size of the image.

If you want to delete the image, just do it from the horizon or simply use the command line;

openstack image delete <ID>

That marks the end of our tutorial on creating and uploading custom Linux image into OpenStack.

Other Tutorials

Deploy OpenStack using DevStack on Ubuntu 22.04/Ubuntu 20.04

How to Create And Delete OpenStack Project

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
koromicha
I am the Co-founder of Kifarunix.com, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

1 thought on “Create and Upload Custom Linux Image into OpenStack”

  1. HI

    I congratulate you very good tutorial, but I have the following problem when I want to upload an image from horizon.

    from cli upload correctly

    TypeError: Cannot read properties of undefined (reading ‘data’)

    Reply

Leave a Comment