OpenStack Lifecycle Management Tools

In a joint effort Jannis Rake-Revelant, Jürgen Brüder, and myself Edmund Haselwanter had a look at several what we call “Openstack Lifecycle Management tools”.

This time Jürgen Brüder did most of the work, so thanks for sharing your findings :-)

Deploying Openstack with Stackforge and Chef Server

Stackforge provides an open-source repository to setup Openstack with Chef. You can deploy it with a Chef-Server or simply by using Chef-Zero.

It currently includes all OpenStack core projects: Compute, Dashboard, Identity, Image, Network, Object Storage, Block Storage, Telemetry and Orchestration.

In this documents we will be using Chef Server to setup our deployment. We will be using Vagrant to create three virtual machines for us.

Using Vagrant for Test setup

Vagrant can be installed on nearly all operating systems. We will be using Mac OS X for this example.

If you are on Mac OS X, you’ll need to install Xcode Command Line Tools from https://developer.apple.com/downloads/

Installing ChefDK

To ensure a proper working deployment, we recommend using the ChefDK for installing all needed Gem dependencies. This will also install Berkshelf etc.

Just follow this link a download the version that fits your OS. Then install it: http://downloads.getchef.com/chef-dk/

Installing VirtualBox and Vagrant

Install the latest VirtualBox for your operating system: https://www.virtualbox.org/wiki/Downloads

Then install the latest version of Vagrant: https://www.vagrantup.com/downloads

Create the VMs

Create a directory called stackforge-chef-server in your home directory. Inside of it, create a file called Vagrantfile.

Add this content to the Vagrantfile:

Vagrant.require_version ">= 1.1"

Vagrant.configure("2") do |config|

  # get local ip so that we can force chef zero onto a different port per
  # machine, allowing for multiple simultaneous vagrant up runs
  local_ip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address

  # virtualbox provider settings
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--cpus", 2]
    vb.customize ["modifyvm", :id, "--memory", 2048]
    vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
    vb.customize ["modifyvm", :id, "--nicpromisc3", "allow-all"]
  end

  #################################
  # Ubuntu 12.04 controller       #
  #################################

  config.vm.define :ubuntu1204cont do |ubuntu1204cont|

    ubuntu1204cont.vm.hostname = "ubuntu1204cont"

    ubuntu1204cont.vm.box = "opscode-ubuntu-12.04"
    ubuntu1204cont.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box"

    ubuntu1204cont.vm.network "forwarded_port", guest: 443, host: 8443     # dashboard-ssl
    ubuntu1204cont.vm.network "forwarded_port", guest: 8773, host: 8773    # compute-ec2-api
    ubuntu1204cont.vm.network "forwarded_port", guest: 8774, host: 8774    # compute-api
    ubuntu1204cont.vm.network "private_network", ip: "192.168.3.60"
    ubuntu1204cont.vm.network "private_network", ip: "172.16.10.60"
  end

  #################################
  # Ubuntu 12.04 compute1         #
  #################################

  config.vm.define :ubuntu1204comp1 do |ubuntu1204comp1|

    ubuntu1204comp1.vm.hostname = "ubuntu1204comp1"

    ubuntu1204comp1.vm.box = "opscode-ubuntu-12.04"
    ubuntu1204comp1.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box"

    ubuntu1204comp1.vm.network "private_network", ip: "192.168.3.61"
    ubuntu1204comp1.vm.network "private_network", ip: "172.16.10.61"
  end

  #################################
  # Ubuntu 12.04 chefsererv       #
  #################################

  config.vm.define :ubuntu1204chef do |ubuntu1204comp1|

    ubuntu1204comp1.vm.hostname = "ubuntu1204chef"

    ubuntu1204comp1.vm.box = "opscode-ubuntu-12.04"
    ubuntu1204comp1.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-12.04_chef-provisionerless.box"

    ubuntu1204comp1.vm.network "private_network", ip: "192.168.3.62"
  end

end

What this Vagrantfile does it to setup three VMs for us. This way, we can give the VMs all necessary network configurations that we need directly through the file.

Simply run this command in the directory with the Vagrantfile:

vagrant up

To SSH into the Machines, simply run from the stackforge-chef-server directory:

vagrant ssh ubuntu1204chef

vagrant ssh ubuntu1204cont

vagrant ssh ubuntu1204comp1

Setup Chef Server

On the ubuntu1204chef machine, run the following commands to setup a Chef Server:

wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef-server_11.1.4-1_amd64.deb
sudo dpkg -i chef-server_11.1.4-1_amd64.deb
sudo chef-server-ctl reconfigure

Point your browser to the Chef VM and login using admin and p@ssw0rd1. Change the password after the login, regenerate the key and copy the key somewhere safe.

Setup Workstation

After installing the ChefDK earlier on your workstation we have installed everything we need to connect to your Chef Server.

Inside your terminal run:

export PATH="/opt/chefdk/embedded/bin:${HOME}/.chefdk/gem/ruby/2.1.0/bin:$PATH"
chef

If both works, everything is setup just fine.

Clone the Chef-Repo Inside your home directory like so:

git clone git://github.com/opscode/chef-repo.git

Cloning into 'chef-repo'...
remote: Counting objects: 199, done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 199 (delta 71), reused 160 (delta 47)
Receiving objects: 100% (199/199), 30.45 KiB, done.
Resolving deltas: 100% (71/71), done.

Inside of the chef-repo directory create a new directory called .chef:

sudo mkdir -p .chef

Now we only need to configure the knife plugin:

knife configure --initial

Answer the questions of the setup. If you have configured everything correctly, you can run the following command to see if everything worked:

knife client list

Bootstrap Nodes

Navigate into your chef-repo and run:

knife bootstrap localhost --sudo -x vagrant -P vagrant --ssh-port 2222 -N ubuntu1204cont --bootstrap-version 11.14.6-1
knife bootstrap localhost --sudo -x vagrant -P vagrant --ssh-port 2200 -N ubuntu1204comp1 --bootstrap-version 11.14.6-1

Please make sure, that the ports numbers are correct. While running the vagrant up command earlier, Vagrant will have shown you the correct port numbers.

Checkout Repo and bundle upload

Navigate into chef-repo/cookbooks and clone the Stackforge cookbook there:

git clone -b stable/icehouse https://github.com/stackforge/openstack-chef-repo.git

To setup all cookbooks with your Chef server do

cd openstack-chef-repo
berks install
berks upload

If you encounter problems regarding SSL, you can create a config.json file in your ~/.berkshelf directory:

{
  "ssl": {
    "verify": false
  }
}

Create environment

Now we create the environment our deployment will be using:

export EDITOR=$(which vi)
knife environment create multi-node

{
    "name": "multi-node",
    "description": "Environment used in testing the upstream cookbooks and reference Chef repository with vagrant. To be used with the Vagrantfile-multi-neutron vagrantfile. Defines the necessary attributes for a working mutltinode (1 controller/n computes) openstack deployment, using neutron (with gre tunnels between hosts) for the networking component.",
    "cookbook_versions": {},
    "json_class": "Chef::Environment",
    "chef_type": "environment",
    "default_attributes": {},
    "override_attributes": {
        "mysql": {
            "allow_remote_root": true,
            "root_network_acl": ["%"]
        },
        "openstack": {
            "developer_mode": true,
            "identity": {
                "bind_interface": "eth1"
            },
            "endpoints": {
                "host": "192.168.3.60",
                "mq": {
                    "host": "192.168.3.60",
                    "bind_interface": "eth1"
                },
                "db": {
                    "host": "192.168.3.60",
                    "bind_interface": "eth1"
                },
                "network": {
                    "debug": "True",
                    "dhcp": {
                        "enable_isolated_metadata": "True"
                    },
                    "metadata": {
                        "nova_metadata_ip": "192.168.3.60"
                    },
                    "openvswitch": {
                        "tunnel_id_ranges": "1:1000",
                        "enable_tunneling": "True",
                        "tenant_network_type": "gre",
                        "local_ip_interface": "eth2"
                    },
                    "api": {
                        "bind_interface": "eth1"
                    }
                },
                "image": {
                    "api": {
                        "bind_interface": "eth1"
                    },
                    "registry": {
                        "bind_interface": "eth1"
                    },
                    "image_upload": true,
                    "upload_images": [
                        "cirros",
                        "ubuntu"
                    ],
                    "upload_image": {
                        "ubuntu": "http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-amd64-disk1.img",
                        "cirros": "https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img"
                    }
                },
                "compute": {
                    "xvpvnc_proxy": {
                        "bind_interface": "eth1"
                    },
                    "novnc_proxy": {
                        "bind_interface": "eth1"
                    },
                    "libvirt": {
                        "virt_type": "qemu"
                    },
                    "network": {
                        "public_interface": "eth1",
                        "service_type": "neutron"
                    },
                    "config": {
                        "ram_allocation_ratio": 5
                    }
                }
            }
        }
    }
}

Now we add the multi-node environment to our nodes:

knife node environment_set ubuntu1204cont multi-node

knife node environment_set ubuntu1204comp1 multi-node

Add Roles and recipes to nodes

Next, we will be adding the necessary roles to our Chef Server.

Once again inside chef-repo/cookbooks/openstack-chef-repo run

knife role from file roles/*.json

Now that the roles are on the Chef Server, we can add them to the nodes:

knife node run_list add ubuntu1204cont "role[os-compute-single-controller-no-network],recipe[openstack-network::identity_registration]","role[os-network-openvswitch]","role[os-network-dhcp-agent]","role[os-network-metadata-agent]","role[os-network-server]"

knife node run_list add ubuntu1204comp1 "role[os-compute-worker]"

As you can see, we configure one node to to be the Controller/Compute node and one to be just an additional Compute node.

Chef Client run

SSH on your nodes (ubuntu1204cont, ubuntu1204comp1) and run:

sudo chef-client

Test the deployment

You can now login at the URL of the first VM. Use the username admin and the password admin for this. If you navigate to Admin -> System Panel -> Host Aggregates you should see both nodes listed.