How to deploy a OpenStack DevStack @ KVM for development purposes in an automated way
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-filewget
to fetch the Ubuntu disk imageqemu-img
to resize the Ubuntu disk imagevirsh
to configure local networks for KVMvirt-install
to create and boot the virtual machinevirt-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 networkpublic
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!