OpenStack Big Tent

Nota:  Este artículo está basado en la publicación del blog de Rich Bowen.

Históricamente, cada nuevo release realizado por la comunidad de OpenStack se oficializaba algún proyecto, es decir, dejaba de formar parte de los proyectos de incubación.

Nombre Fecha Nuevos proyectos
Austin 21 octubre 2010 Nova, Swift
Bexar 3 febrero 2011 Glance
Cactus 15 abril 2011
Diablo 22 septiembre 2011
Essex 5 abril 2012 Horizon, Keystone
Folsom 27 septiembre 2012 Quantum, Cinder
Grizzly 4 abril 2013 Quantum, Cinder
Havana 17 octubre 2013 Ceilometer & Heat
Icehouse 17 abril 2014 Trove
Juno 16 octubre 2014 Sahara
Kilo 30 abril 2015 Ironic
Liberty 15 octubre 2015  “Big Tent”
Mitaka abril 2016
N octubre 2016

Con el fin de dar una mayor claridad de qué proyectos son considerados como parte esencial de OpenStack el comité Tecnico decidió crear un mejor enfoque bajo el término de “Big Tent”.  Para que un proyecto sea considerado como parte de este “Big Tent”, este debe cumplir con cuatro características importantes:

1) Alinearse con la Misión de OpenStack.

2) Obedece la Manera de trabajo de OpenStack.

3) Esforzarse en mantener interoperabilidad entre los componentes de OpenStack.

4) Estar sujeto a la dirección del Comité Tecnico.

Por último, cabe mencionar una vez aprobado el proyecto éste será etiquetado por el Comité y publicado desde su página oficial.

Network Managers (Legacy networking)

Durante el proceso de creación de instancias, el nodo de cómputo asigna una IP privada a cada máquina virtual. Este servicio diferencia entre una IP estática(Fixed IP) y una IP dinamica(Floating IP). Las IPs estáticas son aquellas que permanecen asignadas a lo largo de su vida operativa de una máquina virtual . Por otra parte, las IPs dinámicas o flotantes pueden ser asignadas con una máquina virtual por un periodo de tiempo definido.

Existen tres opciones (FlatManager, FlatDHCPManager y VlanManager) soportadas como manejadores de red para Nova, estas proveen redes virtuales para que las máquinas virtuales puedan comunicarse entre distintos nodos de cómputo y/o con la red publica. Además, han sido descritas hace tiempo en artículos de Mirantis, sin embargo considero conveniente escribir al respecto. Estos tipos de redes pueden coexistir en una implementación, pero debido a que no se puede seleccionar el tipo de rede para cada proyecto, no es posible seleccionar varios tipos para un nodo de cómputo y es por eso que solo una clase puede ser especificada en el archivo de configuración de nova para el nodo de cómputo y su elección depende de las necesidades del negocio. Estas opciones comparten la necesidad de ser administradas y monitoreadas por el operador de la nube.

Todos los administradores de red operan tanto en modo single-host como multi-host(variable de configuracion multi_host). La diferencia entre cada uno es la cantidad de servicios de nova-network que son ejecutados, mientras que single-host, levanta un solo servicio de nova-network ofreciendo servicios como Network Address Translation (NAT), DHCP, y DNS para las máquinas virtuales, para el modo de multi-host cada nodo de cómputo levanta su propio servicio de nova-network.  Esta última opción, permite tener alta disponibilidad y evitando cuellos de botella en el tráfico de red.

nova.network.manager.FlatManager

flatnetwork-diagram-1

La primera clase a analizar es FlatManager, entre las posibles razones para utilizar dicha clase es la existencia de un servicio externo de DHCP y la simplicidad de su uso. Esta opción no ofrece ningún bridge, su creación en cada nodo de cómputo, es responsabilidad del operador y se define en el archivo de configuración con la variable flat_network_bridge. Estos son los cambios necesarios en el archivo de configuración:

/etc/nova/nova.conf

[DEFAULT]
...
network_api_class = nova.network.api.API
public_interface = eth0
flat_network_bridge = br100
network_manager = nova.network.manager.FlatManager
dhcp_domain = novalocal

Es necesario reiniciar el servicio para que los cambios tomen efecto( el nombre del servicio y la forma dependerá de la distribución de Linux que se está usando). Una vez que el servicio inicie con los valores previamente configurados es necesario especificar el rango de redes. Estas direcciones de IP serán inyectadas en la imagen utilizada en la construcción de la máquina virtual. En otras palabras, cada instancia recibe una IP fija de un conjunto disponible.

# service nova-network restart
$ nova-manage network create --label=demo-net --bridge=br100 --multi-host=T --fixed_range_v4=203.0.113.24/29

nova.network.manager.FlatDHCPManager

flat-dhcp-networking-diagrams-4

La clase FlatDHCPManager es similar a la clase FlatManager con la diferencia de que OpenStack levanta un servicio de DHCP a través del servicio de dnsmasq. Al igual que FlatManager, todas las instancias son conectadas a un único bridge del nodo de computo. El servicio de computo asigna una IP estática a cada instancia y dnsmasq registra la dirección de IP con el MAC ID de la máquina virtual para garantizar que cada instancia mantenga su IP estática. Cabe señalar que el servicio de dnsmasq no toma parte del proceso de asignación de direcciones IP, solo lleva el registro(por medio del comando dhcpdiscover) en un archivo que se almacena en la carpeta definida por la variable networks_path del archivo de configuración( por lo general /var/lib/nova/networks/), de cada nodo de cómputo.

/etc/nova/nova.conf

[DEFAULT]
...
network_api_class = nova.network.api.API
public_interface = eth0
flat_interface = eth0
flat_network_bridge = br100
network_manager = nova.network.manager.FlatDHCPManager

También es necesario reiniciar los servicios y crear los rangos de red.

# service nova-network restart
$ nova-manage network create --label=demo-net --bridge=br100 --multi-host=T --fixed_range_v4=203.0.113.24/29

nova.network.manager.VlanManager

vlanmanager-2-hosts-2-tenants

Esta es la clase utilizada por el servicio de Nova Network por defecto. En este modo, los operadores de la nube deben crear una VLAN y un bridge para cada proyecto. En cuanto a hardware, se requiere que el switch utilizado entre varios nodos de cómputo soporte VLAN tagging (IEEE 802.1Q). El rango de IPs privadas son solo accesibles dentro de la VLAN. Para que un usuario pueda acceder a sus máquinas virtuales en cada proyecto, es necesario crear una instancia VPN(llamada cloudpipe).

/etc/nova/nova.conf

[DEFAULT]
...
network_api_class = nova.network.api.API
public_interface = eth0
vlan_interface = eth0
flat_network_bridge = br100
network_manager = nova.network.manager.VlanManager

De igual forma, el rango de IPs es especificado por el administrador para ser asignado(el rango de IPs) dinámicamente a un proyecto cuando es necesario.

# service nova-network restart
$ nova-manage network create --fixed_range_v4=10.0.1.0/24 --vlan=102

Para mayor información, está disponible la guia oficial de administración.

Tareas periódicas de Nova

Actualmente he estado trabajando en un proyecto que me permite revisar a detalle el código fuente de OpenStack, por lo que me he topado con una funcionalidad que me ha parecido interesante. Esta es la ejecucion de tareas periódicas en el proyecto de Nova, y si bien la documentación oficial hace una analogia de estas con los cron jobs de Linux vale la pena profundizar un poco mas sobre el tema.

Su funcionalidad es sencilla, como su nombre lo indica son funciones que se ejecutan con cierto grado de periodicidad. Estas funciones van desde la actualización de los estados de las maquinas hasta la verificación del caché de que almacena las imagenes. En cada función se define, entre otras cosas, la frecuencia de ejecución y si es necesario que sea ejecutada de forma inmediata.

A nivel de código podemos encontrar su implementación en el proyecto de oslo.service como un metodo decorador de funciones. Este decorador define el comportamiento de cada función, ademas de proveer la conexion entre el valor de configuración provisto por el usuario y la definicion del tarea periodica, un claro ejemplo es la función que sincroniza los estados de las maquinas.

Cada una de las funciones es registradas a traves de una clase Manager, que a su vez hace uso de los metodos definidos por una metaclase llamada _PeriodicTasksMeta en su metodo _add_periodic_task.

Por último y una vez registradas cada una de las funciones es necesario conocer el motor que manda ejecutar cada una de ellas de forma periódica. De igual forma estas son ejecutadas por la clase Manager en su funcion periodic_tasks que a su vez manda llamar a clase padre en su metodo run_periodic_tasks este ultimo iterando y ejecutando cada elemento de la lista de funciones. Y si se estan preguntando quien manda llamar a esta clase Manager, cada servicio(nova-api, nova-cert, nova-compute, nova-conductor, nova-consoleauth, nova-network, nova-novncproxy, nova-scheduler) tienen definida una propiedad que hace referencia a una subclase de esta clase Manager, es desde ahí donde se hace la llamada a sus tareas periodicas.

Esta funcionalidad está habilitada por defecto y puede ser deshabilitada via archivo de configuracion en la variable periodic_enable de la seccion DEFAULT del archivo nova.conf.

Utilizando nova-docker y nova-compute-lxd drivers

Hace tiempo estuve leyendo un articulo de Lars Kellogg Stedman donde menciona la posibilidad de utilizar varios “hipervisores” en el mismo nodo de computo, por medio de la instalación y configuración de nova-docker driver en conjunto con el levantamiento de un servicio adicional de nova-compute, el cual se encarga de despachar las peticiones por los usuarios para ese hipervisor en particular. Esta información esta basada en Fedora 21 y hace uso de los servicios de systemd, pero puede ser adaptado a cualquier otra distribución de Linux.

Este articulo pretende enlistar aquellos pasos necesarios para lograr el mismo objetivo en Ubuntu 14.04 LTS. Ademas de incluir Docker, se incluye los pasos necesarios para agregar LXD como otra alternativa mas en la lista de “hipervisores”.

Nota : Se asume la correcta instalación y configuración de otros servicios de OpenStack en el servidor.

Antes que nada es necesario instalar algunas dependencias y servicios que serán utilizados mas tarde, por lo cual se necesita validar conexión a internet y que la cuenta utilizada tenga permisos de administrador sobre la maquina.

Instalación de dependencias

sudo apt-get update -y
sudo apt-get install -y git python-dev crudini

# Instalacion de pip
curl https://bootstrap.pypa.io/get-pip.py | sudo python

# Instalacion de LXD
sudo add-apt-repository -y ppa:ubuntu-lxc/lxd-git-master
sudo apt-get update -y
sudo apt-get install -y lxd

# Instalacion de Docker
curl -sSL https://get.docker.com/ubuntu/ | sudo sh

Una vez instaladas algunas dependencias y servicios, realizaremos la descarga e instalación de los drivers para la comunicación de nova con el “hipervisor”. Ya que no hay garantia de que estos drivers puedan estar incluidos en los paquetes o dependencias de los paquetes de OpenStack es mas sencillo instalarlos de forma manual. Para ello se necesita descargar el código fuente (clonando el repositorio) e instalarlo por medio de pip o simplemente utilizando python setup install.

Instalación de drivers

git clone https://github.com/stackforge/nova-docker /tmp/nova-docker
git clone https://github.com/lxc/nova-compute-lxd /tmp/nova-compute-lxd

pushd /tmp/nova-docker
git checkout stable/kilo
cp etc/nova/rootwrap.d/docker.filters /etc/nova/rootwrap.d
pip install .
popd

pushd /tmp/nova-compute-lxd
git checkout stable/kilo
cp etc/nova/rootwrap.d/lxd.filters /etc/nova/rootwrap.d
pip install .
popd

Cabe mencionar que el branch utilizado en esta ocasión es para release de Kilo, esto puede variar con respecto al release utilizado, y es necesario incluir los filtros que serán utilizados por rootwrap.

El siguiente paso consiste en configurar cada servicio para que utilize un driver especifico y así conectarse con el hipervisor correspondiente. Cada servicio utilizara un valor de host diferente para poder ser diferenciados y require los valores necesarios para conectarse con el servidor de cola de mensajes.

Configuración de drivers

# Configuracion de nova-docker
touch /etc/nova/nova-docker.conf
chown nova:nova /etc/nova/nova-docker.conf

crudini --set /etc/nova/nova-docker.conf DEFAULT host docker${CONFIGURATION}
crudini --set /etc/nova/nova-docker.conf DEFAULT compute_driver novadocker.virt.docker.DockerDriver
crudini --set /etc/nova/nova-docker.conf DEFAULT state_path /var/lib/nova-docker

crudini --set /etc/nova/nova-docker.conf DEFAULT rpc_backend rabbit
crudini --set /etc/nova/nova-docker.conf oslo_messaging_rabbit rabbit_host ${MESSAGE_BROKER_HOSTNAME}
crudini --set /etc/nova/nova-docker.conf oslo_messaging_rabbit rabbit_userid openstack
crudini --set /etc/nova/nova-docker.conf oslo_messaging_rabbit rabbit_password ${RABBIT_PASS}

# Configuracion de nova-compute-lxd
touch /etc/nova/nova-compute-lxd.conf
chown nova:nova /etc/nova/nova-compute-lxd.conf

crudini --set /etc/nova/nova-compute-lxd.conf DEFAULT host lxd${CONFIGURATION}
crudini --set /etc/nova/nova-compute-lxd.conf DEFAULT compute_driver nclxd.nova.virt.lxd.LXDDriver
crudini --set /etc/nova/nova-compute-lxd.conf DEFAULT state_path /var/lib/nova-compute-lxd

crudini --set /etc/nova/nova-compute-lxd.conf DEFAULT rpc_backend rabbit
crudini --set /etc/nova/nova-compute-lxd.conf oslo_messaging_rabbit rabbit_host ${MESSAGE_BROKER_HOSTNAME}
crudini --set /etc/nova/nova-compute-lxd.conf oslo_messaging_rabbit rabbit_userid openstack
crudini --set /etc/nova/nova-compute-lxd.conf oslo_messaging_rabbit rabbit_password ${RABBIT_PASS}

Por ultimo y no menos importante, es necesario registrar los servicios para que estos puedan ser levantados durante el arranque de la maquina por upstart. Para lograrlo se necesita agregar las instrucciones de arranque del servicio en archivos localizados en el directorio /etc/init/.

Configuration de servicios

cat < /etc/init/nova-docker.conf
# vim: set ft=upstart et ts=2:
description "Nova compute docker worker"
author "Victor Morales "

start on runlevel [2345]
stop on runlevel [!2345]

exec start-stop-daemon --start --chuid root --exec /usr/bin/nova-compute -- --config-file=/etc/nova/nova-docker.conf
EOL

cat < /etc/init/nova-compute-lxd.conf
# vim: set ft=upstart et ts=2:
description "Nova compute LXD worker"
author "Victor Morales "

start on runlevel [2345]
stop on runlevel [!2345]

exec start-stop-daemon --start --chuid root --exec /usr/bin/nova-compute -- --config-file=/etc/nova/nova-compute-lxd.conf
EOL

service nova-docker restart
service nova-compute-lxd restart

Una vez que los servicios inicien y puedan comunicarse con el servidor de cola de mensajes, serán registrados dentro del catalogo de “hipervisores” disponibles para OpenStack.

Cloud-Driven Development

Esta es una propuesta para la mejora en la eficiencia del desarrollo de software:

Summary

Even today, environments dedicated entirely to support projects during its development and/or testing phases are under-utilised during non-working hours. No matter the use of those servers they’re always consuming energy for its operation, resulting in infrastructure operating costs for the company. Adapting software development processes in such a way that can only consume resources(servers) on demand during development and testing phases can significantly reduce costs and prevents information loss for an application.

Problem/Opportunity

The process to create and configure environments is traditionally assigned to a single person and managed through a ticketing system whereby time and effort are estimated. In other words, the operator or responsible will only have predefined period of time for setting up an environment requested by an end user(e. g. developer, tester). This is why provisioning activities are made only once and usually at the beginning of a project. But the working environment creation can be the easiest way to do a sanity check of the whole project and verify its correct functionality, this process must not have workarounds or undocumented steps. Additionally, the earlier detection of defects can simplify its resolution and reduce costs for the software development process. Therefore, creating working environments periodically can help to detect defects no matter the stage of the project.

Development and Testing environments are mainly used during working hours, meaning that almost two-thirds of their time the servers are in a state of inactivity. Simple acts such as turning servers off when they are not used can reduce infrastructure operating costs. In order to make this a new habit, these actions must be done on a regular basis.

Solution

Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent workflow to help maximize the productivity and flexibility of you and your team. Vagrant has the ability to manage virtual machines such as VirtualBox, VMware, KVM, and others. Lastly, boxes are the package format for Vagrant environments.

A base box is created from a minimal Operative System with the minimum set of software required for Vagrant to function.  Vagrant uses industry-standard provisioning tools such as shells scripts, Chef or Puppet to automatically install and configure software on the machine. As result, developers, testers and operators are able to create disposable and consistent environments for development and testing.

Agile methodologies promotes adaptive planning, evolutionary development, early delivery, continuous improvement, and encourages rapid and flexible response to change. The main goal for short iterations is to release working item(s) to product owners and communicate the progress on the project with stakeholders and project sponsors.

This document suggests doing changes into day-to-day activities of developer and tester, in a way that at the beginning of the day they must recreate a work environment for getting the latest changes. Having completed their work, only those desired changes should be backed up to proceed to release resources used (i. e. destroy the work environment created at the beginning). If those actions are performed daily by the team, anyone can be joined and start working on the project without assistance, since anytime can request the creation of an work environment and it will have latest changes of the project setup and the project itself. Furthermore, those changes that were not backing up previously are going to reflect malfunctioning the next time that someone creates a work environment, as consequence, this new process helps to fail fast and quickly realize that something is not working.

In order to demonstrate how this methodology works, I’ll take the OpenStack development as an example. OpenStack is an open source infrastructure as a service (IaaS) initiative for creating and managing large groups of virtual private servers in a data center. According to their activity reports during the last 7 days 553 commits have been submitted, resulting in around 80 commits per day. That is why an OpenStack developer can get different results of the work environment based on the day that was created.

The devstack-vagrant project allows to setup an OpenStack work environment and retrieve latest changes of each OpenStack component using Vagrant boxes. Using Cloud-Driven Development, an OpenStack developer must recreate an OpenStack work environment with devstack-vagrant project at the beginning of the day. This new work environment will remain active until all changes have been tested and verified properly. Once all desired changes have been submitted to the OpenStack repositories, before ending the day, the work environment must be destroyed to release any resource.

Results

Adapting agile methodologies to consume only the resources that are needed can results in:

  1. By using cloud computing model of “pay as you go” only during working hours can reduce infrastructure costs for development and test teams.
  2. Every time a work environment is created there is an opportunity to early detect failures in the project.
  3. Performing regular backups of the project reduces time for recovering and impact caused by a disaster.
  4. New members can quickly start contributing into the project.

Docker Swarm Cluster

En el auge de la utilización de contenedores de Linux, Docker se ha caracterizado por ser una herramienta muy poderosa que permite realizar distintas tareas por medio de sus distintas herramientas. En esta ocasión analizare la creación de clusters por medio de Docker Swarm.

Comenzare por describir lo que es un cluster. Un cluster consiste en un conjunto de computadoras que se encuentran poco o fuertemente conectadas para trabajar en conjunto, las cuales pueden ser vistas como un solo sistema. Para el caso de Docker, Swarm es la herramienta que permite crear un conjunto de servidores de contenedores, en un servidor virtual.

Para este ejemplo vamos a crear un cluster con solo dos nodos, pero siempre es posible agregar mas nodos a un cluster existente. Como ya es costumbre utilizare Vagrant para realizar las pruebas.

Vagrantfile

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"

  config.vm.define :node01 do |node01|
    node01.vm.hostname = "node01"
    node01.vm.network :private_network, ip: '192.168.50.10'
    node01.vm.provision "shell", path: "postinstall-node.sh"
  end

  config.vm.define :node02 do |node02|
    node02.vm.hostname = "node02"
    node02.vm.network :private_network, ip: '192.168.50.11'
    node02.vm.provision "shell", path: "postinstall-node.sh"
  end

  config.vm.define :manager do |manager|
    manager.vm.hostname = "manager"
    manager.vm.network :private_network, ip: '192.168.50.15'
    manager.vm.provision "shell" do |s|
      s.path = "postinstall-manager.sh"
      s.args = ["192.168.50.10", "192.168.50.11"]
    end
  end
end

Como primer paso instalaremos y configuraremos en cada uno de los nodos con docker. En el caso de Ubuntu, es necesario modificar el servicio de upstart para incluir el protocolo de comunicación entre los nodos.

postinstall-node.sh

curl -sSL https://get.docker.com/ubuntu/ | sudo sh
service docker stop
sed -i "s/DOCKER_OPTS=/DOCKER_OPTS='-H tcp:\/\/0.0.0.0:2375'/g" /etc/init/docker.conf
service docker start

Por ultimo, es necesario configurar el servidor que administrara todos los nodos, para ello instalaremos docker, descargaremos el contenedor de swarm y registraremos cada uno de los nodos.

postinstall-manager.sh

curl -sSL https://get.docker.com/ubuntu/ | sudo sh
service docker stop
sed -i "s/DOCKER_OPTS=/DOCKER_OPTS='-H tcp:\/\/0.0.0.0:2375'/g" /etc/init/docker.conf
service docker start

export DOCKER_HOST=tcp://0.0.0.0:2375
echo "export DOCKER_HOST=tcp://0.0.0.0:2375" >> /root/.bashrc

docker pull swarm
cluster_id=`docker run --rm swarm create`
nodes="$@"
for node in $nodes
do
  echo "Adding node $node to cluster $cluster_id"
  docker run -d swarm join --addr="$node:2375" token://$cluster_id
done

docker run -d -p 5000:5000 swarm manage token://$cluster_id

Por ultimo, cabe mencionar que Docker Swarm tiene algunas limitantes. Mencionare tres limitaciones que son descritas por Nikhil en su articulo.

  • La version actual de Swarm no soporta descargar imagenes de repositorios privados.
  • Swarm no soporta multiples swarm masters resultando en un solo punto de falla para programar la creación de contenedores.
  • Swarm no soporta ligar contenedores en distintos servidores.

Nota: El código utilizado para este ejemplo en el repositorio de vagrant-docker-swarm.

Instalación “manual” de OpenStack – Servicio de Computo (perspectiva operador/implementador)

Es momento de instalar el servicio encargado de proveer maquinas virtuales(instancias), este servicio resulta primordial para aquellas nubes orientadas a ofrecer servicios de computo como lo es High-Performance Computing. Conocido como “Nova”, este proyecto (junto con Swift) es de los mas antiguos y su origen se remonta desde Austin release. A lo largo de su historia, Nova ha agregado soporte a multiples hipervisores, como lo son KVM, qemu, Hyper-V, VMware, XenServer, LXC, Docker, etc.

Por otra parte, el proyecto de nova ofrece una variedad de servicios que pueden ser separados en dos categorias: compute y controller. Dependiendo de la distro que se use los nombres de los servicios pueden variar, en la categoria de controller podemos encontrar los siguientes servicios o paquetes: nova-api, nova-cert, nova-consoleauth, nova-scheduler, nova-conductor y nova-novncproxy. Para el caso de la categoria de compute: solo es necesario nova-compute y opcionalmente, nova-network en caso de utilizar una configuración de Legacy Networking.

Nota: Existen algunas variantes de como o donde utilizar el servicio de nopa-api. Estas tres alternativas son resumidas en este articulo.

Comenzaremos con la instalación y configuración de servicios de Compute. Nuevamente es necesario modificar el archivo de Vagrantfile para poder habilitar los puertos necesarios, en este caso el 8774:

Vagrantfile

    config.vm.define :compute_controller do |compute_controller|
      compute_controller.vm.hostname = 'compute-controller'
      compute_controller.vm.network :private_network, ip: '192.168.50.14'
      compute_controller.vm.network :forwarded_port, guest: 8774, host: 8774
      compute_controller.vm.provision "shell", path: "nova-controller.sh"
      compute_controller.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--memory", 2048]
      end
    end

Nota: Los servicios de nova controller utilizan memoria RAM adicional de la que ofrece la configuración por defecto de Vagrant, por lo que es necesario especificar ese cambio explicitamente.

nova-controller.sh

apt-get install -y ubuntu-cloud-keyring
echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu trusty-updates/juno main" >>  /etc/apt/sources.list.d/juno.list
apt-get update && apt-get dist-upgrade
apt-get install -y nova-api nova-cert nova-conductor nova-consoleauth nova-novncproxy nova-scheduler python-novaclient

Como ya es costumbre, es necesario registrar el repositorio que contiene los paquetes requeridos para el release de OpenStack a instalar. En el caso de los paquetes su instalación sera muy especifica, ya que puede existir variantes que estarán ligadas a la arquitectura deseada.

A continuación describiré las secciones a configurar.

nova-controller.sh

echo "my_ip = 192.168.50.14" >> /etc/nova/nova.conf
echo "novncproxy_host = 0.0.0.0" >> /etc/nova/nova.conf
echo "novncproxy_port = 6080" >> /etc/nova/nova.conf

echo "rpc_backend = rabbit" >> /etc/nova/nova.conf
echo "rabbit_host = message-broker" >> /etc/nova/nova.conf
echo "rabbit_password = secure" >> /etc/nova/nova.conf

echo "auth_strategy = keystone" >> /etc/nova/nova.conf
echo "" >> /etc/nova/nova.conf
echo "[keystone_authtoken]" >> /etc/nova/nova.conf
echo "identity_uri = http://identity:35357" >> /etc/nova/nova.conf
echo "admin_tenant_name = service" >> /etc/nova/nova.conf
echo "admin_user = nova" >> /etc/nova/nova.conf
echo "admin_password = secure" >> /etc/nova/nova.conf

echo "" >> /etc/nova/nova.conf
echo "[glance]" >> /etc/nova/nova.conf
echo "host = image" >> /etc/nova/nova.conf

El primer grupo de instrucciones pretende configurar valores básicos del servicio de nova, como la ip del nodo de controller, y los valores para el servicio de VNC por el cual los clientes se conectaran a las instancias. El segundo grupo, pretende conectar el servicio de nova con el servicio de cola mensajes, de esta forma ira procesando peticiones de clientes tan pronto pueda. El cuarto bloque de instrucciones especifica valores referentes a la autorización y autenticación de usuarios por medio del servicio de Identidad. Y por ultimo el quinto bloque refiere a el hostname o IP del nodo que ofrece el servicio de Imagenes.

nova-controller.sh

echo "" >> /etc/nova/nova.conf
echo "[database]" >> /etc/nova/nova.conf
echo "connection = mysql://nova:secure@database/nova" >> /etc/nova/nova.conf

apt-get install -y python-mysqldb
su -s /bin/sh -c "nova-manage db sync" nova

Intencionalmente aisle las instrucciones referentes al manejo de la conexión y sincronización de la base de datos. En nuestro caso el manejador de base de datos que utilizamos es un MySQL, por lo que para la ejecución de “nova-manage db sync” es necesario tener instalado su ORM utilizando el modulo de python-mysqldb.

nova-controller.sh

service nova-api restart
service nova-cert restart
service nova-consoleauth restart
service nova-scheduler restart
service nova-conductor restart
service nova-novncproxy restart

Por ultimo no queda mas que reiniciar cada uno de los servicios para que estos utilicen los cambios realizados en el archivo de configuración.

Instalación “manual” de OpenStack – Servicio de Imagenes (perspectiva desarrollador)

Toca el turno ahora de configurar el servicio de imagenes desde la perspectiva de desarrollador. En este caso la documentación es algo escasa, ademas de que el proceso que se tiene resulta diferente respecto al resto de los servicios.

Antes que nada, primero es necesario modificar el archivo de Vagrantfile para utilizar un script diferente para el provisionamiento.

Vagrantfile

  config.vm.define :glance do |glance|
    glance.vm.hostname = 'glance-precise64'
    glance.vm.network :private_network, ip: '192.168.50.13'
    glance.vm.network :forwarded_port, guest: 9292, host: 9292
    #glance.vm.provision "shell", path: "glance.sh"
    glance.vm.provision "shell", path: "glance_dev.sh"
  end

Este nuevo script comenzara con la instalación de dependencias que require el código fuente de glance. La documentación oficial menciona que para Ubuntu puede utilizarse “sudo apt-get build-dep glance” para instalar las dependencias, en lo personal al utilizar ese comando he detectado la falta de algunas dependencias, por lo que he preferido especificar cada una de ellas.

glance_dev.sh

apt-get update
apt-get install --no-install-recommends -qqy git screen python-pip python-virtualenv python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libldap2-dev libffi-dev libmysqlclient-dev libpq-dev

Una vez que se tiene todo lo necesario, procedemos a descargar el código fuente, con este podremos generar un ambiente virtual desde el cual se agregaran mas dependencias solo que esta vez serán agregadas al ambiente virtual.

glance_dev.sh

git clone https://github.com/openstack/glance.git
cd glance

python tools/install_venv.py
. .venv/bin/activate
python setup.py develop

Una vez instalado las dependencias necesarias, es necesario modificar los archivos de configuración para especificar la ruta del archivo de bitácora, ademas de la ubicación de los archivos que contendrán almacenaran los datos.

glance_dev.sh

glance-manage --config-file etc/glance-registry.conf db_sync
glance-manage --config-file etc/glance-api.conf db_sync

Por ultimo, solo nos queda iniciar los servicios. El metodo recomendable para hacerlo es a traves de el comando “glance-control”, desafortunadamente al especificar el archivo de configuración este comando genera aun error. Por el momento utilizaremos sesiones de screen para mantener en segundo plano la ejecución del servicio.

glance_dev.sh

screen -dmS "glance_api_service" tools/with_venv.sh glance-api --config-file etc/glance-api.conf --debug
screen -dmS "glance_registry_service" tools/with_venv.sh glance-registry --config-file etc/glance-registry.conf --debug

Instalación “manual” de OpenStack – Servicio de Imagenes (perspectiva operador/implementador)

Ahora es momento de instalar el servicio para manejar imagenes, el cual tiene como nombre de proyecto el de “Glance”. Su origen se remonta desde su liberación en el release de Bexar el 3 de febrero del 2011, y a lo largo de distintas versiones se han ido incorporando nuevas funcionalidades como lo son el soporte a distintos tipos de imagenes(Cactus), el poder compartir una imagen entre varios tenants(Diablo), el replicado de imagenes a traves de glance-replicator(Folsom), la exposición del estatus de los servicios por medio de glance-control(Grizzly) y la incorporación de una estrategia basada en la localización(Ice House).

La arquitectura de Glance esta compuesta por dos componentes:

  • glance-api. El cual acepta llamadas a la API para poder descubrir, recuperar y almacenar imagenes.
  • glance-registry. Almacena, procesa y recupera la información de las imagenes. Dicha información incluye tamaño tipo, etc.

Para su instalación sera necesario modificar nuevamente el archivo Vagrantfile para incorporar este nuevo servicio, de tal forma que agregaremos la siguiente sección:

Vagrantfile

  config.vm.define :glance do |glance|
    glance.vm.hostname = 'glance-precise64'
    glance.vm.network :private_network, ip: '192.168.50.13'
    glance.vm.network :forwarded_port, guest: 9292, host: 9292
    glance.vm.provision "shell", path: "glance.sh"
  end

Asignaremos la siguiente IP disponible y habilitaremos el puerto 9292 para permitir la comunicación desde el exterior. Al igual que otras instalaciones, los pasos a realizar son similares, los cuales se pueden resumir en la instalación de paquetes, generación de tablas, configuración y reinicio de servicios.

Para la instalación de servicios, en el caso de Ubuntu, sera necesario registrar el repositorio que se utilizara de acuerdo a la version deseada, en este caso es “IceHouse”.

glance.sh

echo "deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/icehouse main" >>  /etc/apt/sources.list.d/icehouse.list
apt-get update
apt-get --no-install-recommends -qqy install ubuntu-cloud-keyring
apt-get update
apt-get --no-install-recommends -qqy install glance

Una vez instalado los paquetes necesarios, varios archivos de configuración son creados por defecto, los cuales tendremos que modificar para consumir los servicios que ofrece Keystone. Por otra parte, el motor de base de datos que se usa por defecto es sqlite, por lo que es necesario modificar el archivo de configuración para utilizar el servidor de MySQL que creamos previamente.

glance.sh

sed -i.bak "s/auth_host = 127.0.0.1/auth_host = 192.168.50.12/g" /etc/glance/glance-api.conf
sed -i.bak "s/%SERVICE_TENANT_NAME%/service/g" /etc/glance/glance-api.conf
sed -i.bak "s/%SERVICE_USER%/glance/g" /etc/glance/glance-api.conf
sed -i.bak "s/%SERVICE_PASSWORD%/secure/g" /etc/glance/glance-api.conf
sed -i.bak "s/#flavor=/flavor=keystone/g" /etc/glance/glance-api.conf

sed -i.bak "s/auth_host = 127.0.0.1/auth_host = 192.168.50.12/g" /etc/glance/glance-registry.conf
sed -i.bak "s/%SERVICE_TENANT_NAME%/service/g" /etc/glance/glance-registry.conf
sed -i.bak "s/%SERVICE_USER%/glance/g" /etc/glance/glance-registry.conf
sed -i.bak "s/%SERVICE_PASSWORD%/secure/g" /etc/glance/glance-registry.conf
sed -i.bak "s/#flavor=/flavor=keystone/g" /etc/glance/glance-registry.conf

sqlite="sqlite:////var/lib/glance/glance.sqlite"
mysql="mysql://glance:secure@192.168.50.11/glance"
sed -i.bak "s/#connection = /connection=${mysql//\//\\/}/g" /etc/glance/glance-registry.conf
rm -f /var/lib/glance/glance.sqlite

Es necesario generar las tablas y columnas requeridas por el Servicio de Imagenes, por lo que realizaremos la generación a traves del comando de sincronización provisto por glance-manage.

glance.sh

apt-get --no-install-recommends -qqy install python-mysqldb
glance-manage db_sync

Por ultimo y para poder cargar los nuevos valores de configuracion, necesitaremos reiniciar tanto el servicio de registro como el de la API.

glance.sh

service glance-registry restart
service glance-api restart

Nota: el código utilizado a lo largo de esta publicación estará disponible en el mismo repositorio.

Instalación “manual” de OpenStack – Servicio de Identidad (perspectiva desarrollador)

Ahora es momento de explicar que pasos son requeridos para poder consumir y depurar el código fuente del Servicio de Identidad, o mejor conocido como Keystone.

En términos generales los pasos a realizar son muy sencillos y pueden resumirse en los siguientes:

  • Instalación de paquetes necesarios
  • Descarga del código fuente
  • Personalización de valores de configuración
  • Generación de tablas
  • Inicio de servicio

Todos los pasos a realizar serán agregados a un nuevo script llamado “keystone_dev.sh”, el cual podrá ser utilizado desde nuestro proyecto en vagrant. No esta por de mas mencionar que el código utilizado a lo largo de esta publicación estará disponible en el mismo repositorio.

Lo primero que haremos sera modificar el archivo Vagrantfile para poder ejecutar el script keystone_dev.sh

Vagrantfile

  config.vm.define :keystone do |keystone|
    keystone.vm.hostname = 'keystone-precise64'
    keystone.vm.network :private_network, ip: '192.168.50.12'
    keystone.vm.network :forwarded_port, guest: 5000, host: 5000
    keystone.vm.network :forwarded_port, guest: 35357, host: 35357
    #keystone.vm.provision "shell", path: "keystone.sh"
    keystone.vm.provision "shell", path: "keystone_dev.sh"
  end

Comenzare el script almacenando un par de variables que pueden servir en caso de querer agregar roles, cuentas, servicios, etc. No son parte indispensable del proceso, pero son de gran utilidad para manipular datos en el momento de hacer pruebas.

keystone_dev.sh

#!/bin/bash
token=`openssl rand -hex 10`
echo "export SERVICE_TOKEN=${token}" >> openrc
echo "export SERVICE_ENDPOINT=http://127.0.0.1:35357/v2.0" >> openrc

La documentación oficial recomienda para Ubuntu la instalacion de solo algunos paquetes necesarios como lo son: python-dev, libxml2-dev, libxslt1-dev, libsasl2-dev, libsqlite3-dev, libssl-dev, libldap2-dev y libffi-dev, para complementar la lista seran agregados varios paquetes para facilitar el desarrollo.

keystone_dev.sh

apt-get update
apt-get install --no-install-recommends -qqy git screen python-pip python-virtualenv python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev libffi-dev

Una vez instalado las dependencias necesarias para nuestro ambiente de desarrollo, procederemos a descargar el código fuente mas reciente desde el repositorio oficial.

keystone_dev.sh

git clone https://github.com/openstack/keystone.git
cd keystone

Nuevamente instalaremos mas dependencias requeridas por el proyecto, solo que estas librerías serán almacenadas en un ambiente virtual de python llamado “.venv”. Por ultimo creamos un archivo de configuración con base en una plantilla proporcionada por el código fuente descargado.

keystone_dev.sh

python tools/install_venv.py
cp etc/keystone.conf.sample etc/keystone.conf
sed -i.bak "s/#admin_token=ADMIN/admin_token=${token}/g" etc/keystone.conf

Al sincronizar la base de datos, las tablas y columnas generadas serán almacenados en el archivo definido por la configuración que especificamos previamente.

keystone_dev.sh

tools/with_venv.sh bin/keystone-manage db_sync

Por ultimo, solo nos queda levantar el servicio para poder ser consumido por otras herramientas. Por lo que iniciaremos una instancia de screen donde estará corriendo el servicio.

keystone_dev.sh

screen -dmS "keystone_service" tools/with_venv.sh bin/keystone-all