Openstack on NixOS

Openstack Liberty with linuxbridge driver

We deploy with Nixops the following Openstack services: nova, glance, keystone and neutron with the linuxbridge driver. Once they are deployed, we will boot a VM and ssh to it.

Deploy Openstack services with Nixops

We consider this nixpkgs branch.

My openstack.nix nixops file:

{
  openstack =
    { config, pkgs, nixpkgs, ... }:
  let
    credentials = { keystoneAdminUsername="admin"; keystoneAdminTenant="admin"; keystoneAdminPassword="admin"; };
    osConfig = {
      endpointPublic = config.networking.privateIPv4;
    } // credentials;
    keystoneConfig = {
      enable = true;
    } // osConfig;
    otherConfig = {
      enableSingleNode = true;
    } // osConfig;
  in 
    { 
      deployment.targetEnv = "libvirtd";
      deployment.libvirtd.memorySize = 4096;
      deployment.libvirtd.headless = true;
      nixpkgs.config.allowBroken = true; 
      networking.firewall.enable = false;
      environment.systemPackages = [ pkgs.pythonPackages.neutronclient
                                     pkgs.pythonPackages.keystoneclient
				     pkgs.pythonPackages.glanceclient
				     pkgs.pythonPackages.novaclient
				   ];
      
      virtualisation.keystone = keystoneConfig;
      virtualisation.glance = otherConfig;
      virtualisation.neutron = otherConfig;
      virtualisation.nova = otherConfig;
    };
}

Then, we deploy it

nixops create -d openstack openstack.nix
nixops deploy -d openstack

Openstack services are preprovionned. Basic endpoints and admin account are created.

We first export default credentials used by openstack clients.

export OS_AUTH_URL=http://NIXOPS_DEPLOYED_VM_IP:5000/v2.0
export OS_USERNAME=admin
export OS_PASSWORD=admin
export OS_TENANT_NAME=admin

Create user resources and boot a VM

Create the network

We create a network, a subnet and attach the subnet to a router.

neutron net-create my-network
neutron subnet-create my-network 192.168.1.1/24 --name my-subnet
neutron router-create my-router
neutron router-interface-add my-router my-subnet

Note, the subnet has to be added to a router, otherwise, VMs will not get any metadatas.

We also create a security group to allow SSH traffic to come in.

neutron security-group-create ssh
neutron security-group-rule-create ssh --protocol tcp --port-range-min 22 --port-range-max 22 --direction ingress

Download an image and boot a VM

We download and create a glance image.

curl -O http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
glance image-create --name "cirros" --file cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --visibility public --progress

We finally add a ssh keypair and boot the VM.

nova keypair-add my-key > my-key.private && chmod 600 my-key.private
nova boot --image cirros --flavor m1.tiny --key my-key --security-group ssh --nic net-id=MY-NETWORK-ID my-vm

Here the VM is up and accepts ssh connections from my-network. To properly ssh it, we will set a public network and associate a floating ip to this VM. Or, for testing purpose, we can already ssh the VM from the DHCP netns.

Associate a floating IP

We create a network connected to our public physical network (as defined in neutron.conf). In the following, I consider the existing libvirt network 192.168.122.0/24.

neutron net-create public --shared --router:external True --provider:physical_network public  --provider:network_type flat
neutron subnet-create public 192.168.122.0/24 --allocation-pool start=192.168.122.100,end=192.168.122.105 --gateway 192.168.122.1 --disable-dhcp

We first define the public network as the gateway of the router. We can then create and associate the floating IP to the VM.

neutron router-gateway-set my-router public
neutron floatingip-create public
nova floating-ip-associate my-vm 192.168.122.101

We can then ssh from the host:

ssh -i my-key.private cirros@192.168.122.101

Notes

Subnet without any gateway

To avoid the need of the l3 agent, it is possible to boot a VM in a subnet which has no gateway. The dhcp server pushes static routes to the VM to announce the metadata IP. In this case, it is not possible to set a floating ip