How to deploy a OpenStack DevStack @ KVM for development purposes in an automated way

chrischdi
Mercedes-Benz Tech Innovation
5 min readJul 8, 2020

In this blog post I’d like to explain how to setup an OpenStack via DevStack including the Octavia API and its Horizon UI.

Why should I read this instead of the upstream docs

The OpenStack documentation only documents how to install DevStack to an already installed virtual machine.

This blog post also covers the setup of the virtual machine and automates away the manual steps of the upstream documentation by using cloud-init. This way we will get a setup which should be reproducible.

Target setup

Building the DevStack

To deploy a local OpenStack we will do the following steps:

  • Install prerequisites
  • Create the cloud-init iso
  • Download and resize a base Ubuntu disk image
  • Prepare the external network
  • Create the virtual machine

Prerequisites

Before you start you need the following tools:

  • cloud-localds to create a cloud-init iso-file
  • wget to fetch the Ubuntu disk image
  • qemu-img to resize the Ubuntu disk image
  • virsh to configure local networks for KVM
  • virt-install to create and boot the virtual machine
  • virt-manager as graphical interface to manage virtual machines

For Ubuntu Bionic the following snippet will install the tools for you:

$ apt-get install cloud-image-utils wget qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager

Prepare the cloud-init iso

We will later pass this iso file as disk to the virtual machine for cloud-init. During boot the virtual machine will detect the image and use the contained configuration. We will use the following cloud-init-devstack.yaml file which contains our DevStack configuration:

We can now create the cloud-init-devstack.iso:

sudo cloud-localds /var/lib/libvirt/images/cloud-init-devstack.iso cloud-init-devstack.yaml

Download and resize the Ubuntu disk image

Ubuntu provides a ready to use image for Ubuntu bionic. We will download and boot from it so we don’t have to install Ubuntu ourselves.

Luckily, the image already has cloud-init pre-installed so we just need to pass the previously created iso when booting the image for the first time.

We will copy it over to the default path for libvirt disks and resize it to a virtual size of 100 GB.

wget -c https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img
sudo qemu-img convert -f qcow2 -O qcow2 bionic-server-cloudimg-amd64.img /var/lib/libvirt/images/devstack.qcow2
sudo qemu-img resize /var/lib/libvirt/images/devstack.qcow2 100G

Prepare the “external network”

Our virtual machine will be attached to two different networks defined via virsh:

  • default as management network
  • public which will later-on be used as “external network” in OpenStack

The default management network does already exist so we only need to create the network public.

As you can see we are configuring here the network 192.168.200.0/24 as referenced in the above cloud-init-devstack.yaml.

This step does create a bridge device on our local machine named virbr-octavia and assigns the IP address 192.168.200.1 to it:

$ ip -4 addr show dev virbr-devstack
16: virbr-devstack: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
inet 192.168.200.1/24 brd 192.168.200.255 scope global virbr-devstack
valid_lft forever preferred_lft forever

Create and boot the virtual machine

As last step we will use virt-install to create and boot our virtual machine:

After executing the command we should be able to ssh into the virtual machine and tail the logs of cloud-init to view the installation process of our DevStack.

IP="$(virsh net-dhcp-leases default | grep -E 'devstack|ubuntu' | awk '{print $5}' | sed 's#/24##')"
# The password is ubuntu
ssh ubuntu@$IP sudo tail -f /var/log/cloud-init-output.log

The setup is finished as soon as we get The system is finally up .

Using the running DevStack

Accessing the OpenStack APIs

The DevStack scripts will preconfigure a restricted user named demo and an admin user named admin .

Both will have set the password secretadmin which could get modified inside the cloud-init-octavia.yaml.

We now have different ways to access the APIs:

  • Via the Horizon webinterface:
IP="$(virsh net-dhcp-leases default | grep -E 'devstack|ubuntu' | awk '{print $5}' | sed 's#/24##')"
xdg-open http://$IP
  • Via locally installed OpenStack CLI’s (here as user demo , requires installed OpenStack CLI’s):
IP="$(virsh net-dhcp-leases default | grep -E 'devstack|ubuntu' | awk '{print $5}' | sed 's#/24##')"
ssh-copy-id ubuntu@$IP
source <(ssh ubuntu@$IP "source /opt/stack/devstack/openrc admin && env" | grep '^OS' | sed 's/^/export /')
openstack host list
+-----------+-----------+----------+
| Host Name | Service | Zone |
+-----------+-----------+----------+
| devstack | scheduler | internal |
| devstack | conductor | internal |
| devstack | conductor | internal |
| devstack | compute | nova |
+-----------+-----------+----------+
  • Via ssh from inside the virtual machine (here as user demo ):
IP="$(virsh net-dhcp-leases default | grep -E 'devstack|ubuntu' | awk '{print $5}' | sed 's#/24##')"
# The password is ubuntu
ssh-copy-id ubuntu@$IP
ssh ubuntu@$IP
source /opt/stack/devstack/openrc admin
openstack host list
+-----------+-----------+----------+
| Host Name | Service | Zone |
+-----------+-----------+----------+
| devstack | scheduler | internal |
| devstack | conductor | internal |
| devstack | conductor | internal |
| devstack | compute | nova |
+-----------+-----------+----------+

Wrap up

The steps above show how to run a DevStack installation locally using KVM and automate the installation via cloud-init. It is pretty easy to extend the installation by modifying the cloud-init-devstack.yaml file to fit special needs. One special feature of the cloud-init script is the octavia-recover service which will ensure that Octavia will get back healthy after rebooting the virtual machine.

We’re using this internally to create a basic setup using Octavia and an adjusted configuration which installs Neutron LBaaS v2 instead of Octavia to test multiple scenarios for our production OpenStack environment. Also we did a basic setup of Kubernetes Cluster API Provider OpenStack on a DevStack installation!

--

--

chrischdi
Mercedes-Benz Tech Innovation

Developing, building and maintaining #kubernetes clusters since k8s v1.6! Working for @DaimlerTSS