DevStack deployment
As we know basics about openstack, let’s experiment it’s simplest form devstack.
Install a virtualization program if not already present
Here I will install kvm to my debian host with informations given in debian wiki. I will install qemu-kvm for kernel module, and libvirt-bin for virtualization daemon and virtinst for command line guest creation.
Then add users of concern to kvm and libvirt groups
and install virt-manager for gui control. Adding guest OS will be trivial using virt-manager.
Kvm GUI virt-manager usage resembles similar to somewhat more popular VirtualBox / WmWare. If virt-manager fails to start virtual machines due to default network error like;
Try starting network manually using;
virsh net-start
Here I created a template from scratch in order to enable custom modifications to support common bare minimums of the context. Another option may be downloading a template from one of already present alternatives. As our template is ready, let’s work on vagrant. Vagrant will be used as configuration controller/provisioner that will help us do things in a reproducible and programmatic way. For now it may be seem like matrix in matrix to use openstack in vagrant but lets continue and see what it will look line at the end. Preparing a vagrant base box for virtual box is handled before, and same principles may be applied here. After template is ready, try creating a base box with;
Here vagrant states it’s preference to VirtualBox. As we use KVM, this love story seems impossible unless we take necessary measures. In order to use KVM, we need to install a plug in vagrant-libvirt that adds a libvirt provider to vagrant. First install dependencies listed below (some of them should already be installed up to now);
Then install vagrant-libvirt plugin. Here I installed plug in as root but better install it at login that will be using vagrant.
In order to create a base box, we may follow box format specification. First create a temporary directory, copy guest image (that will normally be in /var/lib/libvirt/images/), create a json document (metadata.json) and a configuration file (Vagrantfile), and finally unite these into a single file using tar as presented below.
While copying it is better also rename image to box.img. Then create metadata and configuration files as;
And tar these into a .box file,
Now, we may create a base box (called debian86 here) as;
Now, create a directory for the project, and in that directory, initialize a vagrant project with
vagrant init
Here, we will see a blank Vagrantfile for vagrant configuration. Change Vagrantfile to enable puppet for provisioning, and create necessary files accordingly. Two divergences from the link are,
- set preferred hypervisor at the start of Vagrantfile, which will be libvirt,
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
This is optional, and you may also use –provider=’libvirt’ with corresponding vagrant commands, such as vagrant up / vagrant status.
- And if not already done generate ssh keys with;
ssh-keygen
or remove corresponding entry in ssh key path in Vagrantfile configuration. It is better to create one if you intend to use your host keys in guest through key forwarding. Then configure vagrant files in order to;
- clone devstack respository
- create a basic configuration
- create an appropriate user
- and install openstack
After all, sample configuration for devstack will be;
Vagrantfile (./Vagrantfile)
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt' # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Template box config.vm.box = "debian86" # Guest hostname and ip config.vm.hostname = "devstack" config.vm.network :private_network, ip: "192.168.121.10" # Guest hardware, 2048MB ram and 1 cpu config.vm.provider "libvirt" do |lv| lv.memory = 2048 lv.cpus = 1 end # Configure shared folders config.nfs.functional = false config.vm.synced_folder ".", "/vagrant", disabled: true config.vm.synced_folder "synced_folder", "/synced_folder", type: "rsync", create: true # Set puppet as provisioner and configure puppet modules path config.vm.provision :puppet do |puppet| puppet.module_path = "puppet/modules" puppet.manifests_path = "puppet/manifests" puppet.options = ['--verbose'] end # Use ssh keys of host config.ssh.forward_agent = true config.ssh.private_key_path = ['~/.vagrant.d/insecure_private_key', '~/.ssh/id_rsa'] end
Puppet manifest (./puppet/manifests/default.pp)
# set path for executables Exec { path => [ "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/" ] } # list packages that should be installed $system_packages = [ 'vim', 'g++', 'make', 'git', 'python', 'python-pip'] # perform an update exec { 'update': command => 'apt-get update' } # install system packages after an update package { $system_packages: ensure => "installed", require => Exec['update'] } # create a user "stack" user { 'stack': ensure => "present", home => "/home/stack", managehome => true, notify => Exec['update_sudoers'] } # add user 'stack' in sudoers list exec { 'update_sudoers': command => "/bin/echo \"stack ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers", refreshonly => true, require => User['stack'] } # clone devstack repository exec{ 'clone_repository' : creates => '/home/stack/devstack', cwd => "/home/stack", command => "git clone -v https://git.openstack.org/openstack-dev/devstack", user => 'stack', provider => shell, require => [Exec['update_sudoers'], Package['git']] } # copy templete configuration file, # remember that "puppet:///modules/localconf/local.conf" will # match to %vagrant_root%/modules/localconf/files/local.conf file{ 'local_conf' : path => '/home/stack/devstack/local.conf', ensure => file, source => "puppet:///modules/localconf/local.conf", owner => 'stack', group => 'stack', mode => 0744, require => Exec['clone_repository'], notify => Exec['install_devstack'] } # install devstack exec{ 'install_devstack' : cwd => "/home/stack/devstack", command => "./stack.sh", user => 'stack', provider => shell, refreshonly => true, require => File['local_conf'] }
Puppet module (./puppet/modules/localconf/files/local.conf)
[[local|localrc]]
ADMIN_PASSWORD=secret
DATABASE_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD
RECLONE=yes
Then start the engine;
vagrant up
Here for my debian 8.6 host, and vagrant-lbvirt 0.0.36, I encountered a dhcp lease problem that made my guests unable to obtain ip;
There is an issue about this git repository of fog-libvirt. while waiting for permanent fix,
as a solution
~/.vagrant.d/gems/gems/fog-libvirt-0.3.0/lib/fog/libvirt/requests/compute/dhcp_leases.rb
may be modified as suggested;
And also beware that there is a bug about halted guests ending in suspended state in guests with gui. Temporary solution may be using guests own controls using virt manager console while waiting a fix.
After ./stack.sh is executed at puppet manifest, our guest should have keystone, glance, nova, cinder, neutron and horizon installed.
We may access openstack cli by;
Next step will be getting familiar with devstack