--- title: 'OpendStack' disqus: OpenStack --- ![Logo](https://i.imgur.com/dzRc8DH.png =40x) OpenStack === Este documento describe los pasos a seguir para desplegar una prueba de concepto de OpenStack sobre máquinas virtuales en Azure. ## Tabla de Contenido [TOC] ## Introducción [OpenStack](https://www.openstack.org/) es un sistema operativo open source para la nube, que controla grandes *pools* de recursos de cómputo, almacenamiento y networking a través de un datacenter, todo gestionado y provisionado a través de APIs REST y un único mecanismo de autenticación. Openstack se compone de varios servicios que administran los distintos recursos. Algunos ejemplos de estos son `Cinder` para almacenamiento, `Nova` para cómputo y `Horizon` para el dashboard. ![OpenStack services](https://i.imgur.com/HfeWdjf.jpg) La instalación de OpenStack es extremadamente engorrosa: Necesita de servidores físicos (*Baremetal*) y requiere gran experiencia y mucho tiempo para su correcto despliegue. Una alternativa para generar despliegues pequeños más rápido para pruebas de concepto es [Packstack](https://github.com/redhat-openstack/packstack/), una herramienta open source desarrollada por [Red Hat](https://www.redhat.com/es). Si bien la herramienta simplifica la instalación de OpenStack, tiene varias limitaciones. Entre ellas, la falta de documentación, pobre soporte, y alcance limitado. En este documento, vamos a explicar como utilizar [Packstack](https://github.com/redhat-openstack/packstack/) para desplegar OpenStack sobre tres máquinas virtuales en Azure, levantando un nodo de Storage, uno de Compute, y el tercero que administra el Controller, tal como se ve en el siguiente diagrama (ignorando los nombres de los nodos y sus IPs): ![Arquitectura OpenStack](https://i.imgur.com/JHLn09A.png) Es esencial seguir estas instrucciones al pie de la letra y no saltearse ningún paso para el correcto despliegue de los servicios. Máquinas virtuales --- Vamos a crear 3 máquinas virtuales sobre la nube de Microsoft: [Azure](https://azure.microsoft.com/Account/Free). 1. Crearse una cuenta en [Azure](https://azure.microsoft.com/Account/Free). 2. Crear 3 VMs con los siguientes atributos (si no se menciona, se puede dejar el valor por defecto) y esperar a que se desplieguen con éxito: ``` Virtual machine name: NodoOpenStackController Resource group: nodos-openstack // Crear el resource group Region: East US Image: CentOS-based 7.5 Size: Standard D2s v3 Authentication type: Password Username: NodoOpenStackController Password: NodoOpenStackController // elegir la que se prefiera Public inbound ports: SSH 20, HTTP 80, HTTPS 443 Virtual machine name: NodoOpenStackCompute Resource group: nodos-openstack Region: East US Image: CentOS-based 7.5 Size: Standard D2s v3 Authentication type: Password Username: NodoOpenStackCompute Password: NodoOpenStackCompute // elegir la que se prefiera Public inbound ports: SSH 20, HTTP 80, HTTPS 443 Virtual machine name: NodoOpenStackStorage Resource group: nodos-openstack Region: East US Image: CentOS-based 7.5 Size: Standard D2s v3 Authentication type: Password Username: NodoOpenStackStorage Password: NodoOpenStackStorage // elegir la que se prefiera Public inbound ports: SSH 22, HTTP 80, HTTPS 443 ``` 3. Entrar a la configuración de cada una de las máquinas recién creadas en el panel `Virtual machines` de Azure e ingresar a la sección de `Networking`. Vamos a abrir algunos puertos (para entrada y salida), por lo que hay que agregar las siguientes `Inbound port rules` y `Outbound port rules` haciendo clic en cada pestaña según corresponda (Se menciona solo el puerto a abrir, todos los otros valores pueden quedar por defecto): :::info **Estos puertos deben abrirse tanto en las reglas de entrada como en las de salida** ::: | Name| Port | -------- | -------- | | Block Storage | 8776 | | Compute Manager | 8774 | | Compute API | 8773, 8775 | | Compute VMs | 5900-5999 | | Compute Proxies | 6080-6082 | | Data processing | 8386 | | Identity | 35357 | | Identity public | 5000 | | Image | 9292, 9191 | | Networking | 9696 | | Object Storage | 6000-6002 | | Orchestration | 8004, 8003, 8000 | | Telemetry | 8777 | | HTTP alternate | 8080 | | Rsync | 873 | | iSCSI | 3260 | | MySQL | 3306 | | Message Broker | 5672 | Referencia: [https://docs.openstack.org/kilo/config-reference/content/firewalls-default-ports.html](https://docs.openstack.org/kilo/config-reference/content/firewalls-default-ports.html) 4. Tomar nota de las IPs públicas y privadas de las máquinas. En este documento utilizaremos las siguientes: | Nombre | IP pública | IP privada | | -------- | -------- | -------- | | NodoOpenStackController | 140.0.0.1 | 10.0.2.10 | | NodoOpenStackCompute | 140.0.0.2 | 10.0.2.11 | | NodoOpenStackStorage | 140.0.0.3 | 10.0.2.12 | 5. Ingresar mediante sesión SSH a cada una de las VMs en diferentes sesiones utilizando las contraseñas definidas al momento de crear las VMs (en este documento utilizamos como contraseña el mismo nombre de las VMs), y correr `sudo su` para entrar en modo superuser, volviendo a escribir la contraseña. ``` # sesión 1 ssh NodoOpenStackController@140.0.0.1 sudo su # sesión 2 ssh NodoOpenStackCompute@140.0.0.2 sudo su # sesión 3 ssh NodoOpenStackStorage@140.0.0.3 sudo su ``` 6. Correr el comando `passwd` y actualizar la contraseña del user `root` para cada una de las máquinas virtuales. En este documento se utilizaron las siguientes contraseñas: ``` NodoOpenStackController! NodoOpenStackCompute! NodoOpenStackStorage! ``` Descargas y configuración inicial de VMs --- Con las sesiones abiertas como se explicó en la sección anterior, vamos a pasar a descargar las herramientas necesarias y a realizar las configuraciones iniciales en las VMs 1. Correr en todas las VMs el siguiente comando, y luego reiniciar las VMs desde el panel de control de `Virtual machines` de Azure. Este comando actualiza el programa de descarga de paquetes de CentOS: ``` yum -y update ``` 2. Al reiniciar las VMs las conexiones SSH se deberían haber cortado. Volver a conectarse como se explicó en la sección anterior y reeingresar al modo superuser. 3. Agregar un hostname a cada una de las máquinas según corresponda corriendo el siguiente comando: ``` # en NodoOpenStackController hostnamectl set-hostname controller # en NodoOpenStackCompute hostnamectl set-hostname compute # en NodoOpenStackStorage hostnamectl set-hostname storage ``` 4. Agregar en todas las VMs las siguientes entradas en el archivo `/etc/hosts` para evitar problemas con el DNS: ``` 10.0.2.10 controller.example.com controller 10.0.2.11 compute.example.com compute 10.0.2.12 storage.example.com storage ``` 5. Deshabilitar SElinux corriendo el siguiente comando en todas las VMS: ``` setenforce 0 ; sed -i 's/=enforcing/=disabled/g' /etc/sysconfig/selinux ``` 6. Deshabilitar opciones de firewall y el administrador de red de linux, para permitir la gestión de las redes por OpenStack corriendo los siguientes comandos en orden en todas las VMs: ``` systemctl disable firewalld systemctl stop firewalld systemctl disable NetworkManager systemctl stop NetworkManager systemctl enable network systemctl start network ``` 7. Volver a reiniciar las VMs desde Azure, y volver a ingresar mediante sesiones ssh a cada una de ellas. 8. Agregar en todas las VMs las siguientes entradas al archivo `~/.bashrc`: ``` export LANG=en_US.utf-8 export LC_ALL=en_US.utf-8 ``` Descarga y configuración de Packstack --- Completando la sección anterior se cuenta con 3 sesiones ssh activas a las VMs creadas en azure, con la configuración inicial para proceder con la descarga y configuración de Packstack. 1. Debemos primero descargar las herramientas de OpenStack y el programa Packstack. Para ello, correr en la VM Controller (NodoOpenStackController en este documento) los siguientes comandos en orden: ``` yum install -y centos-release-openstack-stein yum update -y yum install -y openstack-packstack ``` 2. Habiendo instalado Packstack y sus dependencias en la VM que será el Controller, procedemos a generar un **Answer file** corriendo el siguiente comando: ``` packstack --gen-answer-file=/root/answer.txt ``` Debemos detenernos un momento para explicar un poco más sobre el funcionamiento de Packstack. El programa, utiliza para la gestión del despliege de OpenStack un archivo (texto plano) de configuración llamado **Answer file**. Deberemos editar este archivo para definirle a Packstack la arquitectura de nuestro despliegue de OpenStack. 3. Editamos entonces el archivo `/root/answer.txt` con las configuraciones deseadas para nuestra arquitectura de OpenStack. En particular, vamos a editar las siguientes opciones: ``` # IP de la VM que correrá el Controller (localhost) CONFIG_CONTROLLER_HOST=10.0.2.10 # IP de la VM que correrá Compute (NodoOpenStackCompute) CONFIG_COMPUTE_HOSTS=10.0.2.11 # Deshabilitamos la opción de precarga de demo para testing CONFIG_PROVISION_DEMO=n # Seteamos la contraseña del administrador (poner una contraseña segura, este documento usa `password` para simplificar la explicación) CONFIG_KEYSTONE_ADMIN_PW=password # Habilitar configuraciones no soportadas, para poder desplegar el nodo de Storage CONFIG_UNSUPPORTED=y # IP de la VM que correrá Storage (NodoOpenStackStorage) CONFIG_STORAGE_HOST=10.0.2.12 # Setear cantidad de hilos a 1 para evitar un bug conocido de Packstack (https://linuxacademy.com/community/posts/show/topic/22389-openstack-essentials-testing-if-puppet-apply-is-finished) CONFIG_SERVICE_WORKERS=1 ``` 4. Ya estamos listos para ejecutar Packstack con la configuración que buscamos. Este proceso puede tardar bastante tiempo (hasta una hora según nuestra experiencia), por lo que hay que dejarlo correr hasta que termine. Es posible que pida las contraseñas de las máquinas virtuales. De ser así ingresarlas según corresponda. Tenga en cuenta que puede pedir tanto las contraseñas de los usuarios creados en el portal de Azure, como las seteadas para los usuarios `root`: ``` packstack --answer-file=/root/answer.txt ``` **Referencias**: * https://linuxacademy.com/community/posts/show/topic/22389-openstack-essentials-testing-if-puppet-apply-is-finished * https://www.rdoproject.org/install/packstack/ * https://www.linuxtechi.com/multinode-openstack-newton-installation-centos7/ * https://www.techsupportpk.com/2016/12/installing-openstack-on-multi-node-in-linux.html ## Verificación de la instalación Vamos a verificar que los nodos se instalaron correctamente y los servicios están levantados. Para ello, corramos en el `NodoOpenStackController`: ``` openstack compute service list ``` Deberíamos obtener una lista de los servicios de cómputo de OpenStack. Entre ellos, debería encontrarse el nodo `NodoOpenStackCompute`, como se ve a continuación: ``` +----+------------------+------------------------+----------+---------+-------+----------------------------+ | ID | Binary | Host | Zone | Status | State | Updated At | +----+------------------+------------------------+----------+---------+-------+----------------------------+ | 3 | nova-conductor | controller.example.com | internal | enabled | up | 2019-06-13T03:03:55.000000 | | 4 | nova-scheduler | controller.example.com | internal | enabled | up | 2019-06-13T03:03:52.000000 | | 6 | nova-consoleauth | controller.example.com | internal | enabled | up | 2019-06-13T03:03:52.000000 | | 7 | nova-compute | compute.example.com | nova | enabled | up | 2019-06-13T03:03:55.000000 | +----+------------------+------------------------+----------+---------+-------+----------------------------+ ``` Comprobemos ahora que los servicios de Storage están levantados, corriendo el siguiente comando en `NodoOpenStackController`: ``` cinder service-list ``` Deberíamos obtener ahora una lista de los servicios de Storage de OpenStack corriendo en nuestro despliegue. Entre ellos, debería encontrarse el nodo `NodoOpenStackStorage`, como se ve a continuación: ``` +------------------+------------------------+------+---------+-------+----------------------------+ | Binary | Host | Zone | Status | State | Updated_at | +------------------+------------------------+------+---------+-------+----------------------------+ | cinder-scheduler | controller.example.com | nova | enabled | up | 2019-06-13T03:03:58.000000 | | cinder-volume | storage.example.com | nova | enabled | up | 2019-06-13T03:03:59.000000 | +------------------+------------------------+------+---------+-------+----------------------------+ ``` De no verificarse alguno de estos servicios, pasar a la sección de *Troubleshooting*. **Referencias**: * https://docs.openstack.org/cinder/rocky/install/cinder-verify.html * https://docs.openstack.org/mitaka/install-guide-obs/nova-verify.html ## Acceso al dashboard Con OpenStack desplegado en nuestra red, y todos sus servicios corriendo (a cuenta de Packstack), ya podemos acceder al dashboard de administración: [Horizon](https://github.com/openstack/horizon). Para esto, desde el nodo controller (`NodoOpenStackController`) podemos acceder a [http://controller.example.com/dashboard](http://controller.example.com/dashboard), la uri del dashboard de gestión de OpenStack. Ahora nos enfrentamos a una situación: Este dashboard está en nuestra red privada, y no se encuentra expuesto al público ¿Cómo podemos entonces accederlo desde nuestra PC? No hay una sola respuesta para este problema, pero la solución que utilizamos en este documento es la siguiente: 1. Crear un tunel ssh a la VM `NodoOpenStackController` de la siguiente manera: ``` ssh -D 8080 -C -N NodoOpenStackController@140.0.0.1 ``` 2. Abrir la configuración del navegador (en este documento utilizamos `Google Chrome 74.0`) y abrir la opción `Open proxy settings`. 3. En la ventana que se acaba de abrir, seleccionar `SOCKS proxy` en el campo `Select a protocol to configure`. 4. Setear la configuración del proxy a `127.0.0.1:8080` en el campo `SOCKS proxy server`. 5. Aceptar y aplicar los cambios. 6. Ya podemos acceder desde nuestro navegador a [http://controller.example.com/dashboard](http://controller.example.com/dashboard) con las siguientes credenciales: ``` admin password // o la que se haya seteado en el campo CONFIG_KEYSTONE_ADMIN_PW del Answer file ``` Lo que hicimos en esta sección es crear un tunel ssh desde nuestra PC hasta la VM del controller, y lo utilizamos como un proxy SOCKS para poder conectarnos a través de nuestro navegador a la VM. Habiendo seteado `controller.example.com` en nuestro `/etc/hosts` file, nos permite acceder al dashboard utilizando esa cómoda url. **Referencias:** * https://customers.trustedproxies.com/knowledgebase.php?action=displayarticle&id=10 ## Conexión a la red externa Para poder conectar las redes que despleguemos en OpenStack a nuestra propia red, necesitaremos generar un bridge entre nuestra interfaz, y una interfaz virtual generada por OpenStack. Para lograr esto, deberemos editar la configuración de nuestras interfaces de la siguiente manera en `NodoOpenStackController`: ``` cd /etc/sysconfig/network-scripts/ cp ifcfg-eth0 ifcfg-br-ex vi ifcfg-eth0 ... DEVICE=eth0 HWADDR=08:00:27:4b:53:57 TYPE=OVSPort DEVICETYPE=ovs OVS_BRIDGE=br-ex ONBOOT=yes ``` Por otro lado, deberemos editar el nuevo archivo de configuración para que el bridge funcione correctamente: ``` vi ifcfg-br-ex ... DEVICE=br-ex DEVICETYPE=ovs TYPE=OVSBridge BOOTPROTO=static IPADDR=10.0.2.10 NETMASK=255.255.255.0 GATEWAY=10.0.2.1 ONBOOT=yes ``` Finalmente reiniciamos el servicio de red para habilitar nuestros cambios: ``` systemctl restart network ``` **Referencias**: * [https://www.techsupportpk.com/2016/12/installing-openstack-on-multi-node-in-linux.html](https://www.techsupportpk.com/2016/12/installing-openstack-on-multi-node-in-linux.html) * [https://www.linuxtechi.com/multinode-openstack-newton-installation-centos7/](https://www.linuxtechi.com/multinode-openstack-newton-installation-centos7/) ## Troubleshooting Estos son algunos de los problemas que surgieron en la implementación de OpenStack ### ¿Cómo desinstalar OpenStack? Una vez instalado y corriendo OpenStack, son tantos los procesos que matarlos y desinstalarlos a mano puede ser engorroso. Este script busca los servicios instalados y los desinstala. ```shell=bash #!/usr/bin/bash # Warning! Dangerous step! Destroys VMs for x in $(virsh list --all | grep instance- | awk '{print $2}') ; do virsh destroy $x ; virsh undefine $x ; done ; # Warning! Dangerous step! Removes lots of packages, including many # which may be unrelated to RDO. yum remove -y nrpe "*nagios*" puppet ntp ntp-perl ntpdate "*openstack*" \ "*nova*" "*keystone*" "*glance*" "*cinder*" "*swift*" \ mysql mysql-server httpd "*memcache*" scsi-target-utils \ iscsi-initiator-utils perl-DBI perl-DBD-MySQL ; ps -ef | grep -i repli | grep swift | awk '{print $2}' | xargs kill ; # Warning! Dangerous step! Deletes local application data rm -rf /etc/nagios /etc/yum.repos.d/packstack_* /root/.my.cnf \ /var/lib/mysql/ /var/lib/glance /var/lib/nova /etc/nova /etc/swift \ /srv/node/device*/* /var/lib/cinder/ /etc/rsync.d/frag* \ /var/cache/swift /var/log/keystone ; umount /srv/node/device* ; killall -9 dnsmasq tgtd httpd ; setenforce 1 ; vgremove -f cinder-volumes ; losetup -a | sed -e 's/:.*//g' | xargs losetup -d ; find /etc/pki/tls -name "ssl_ps*" | xargs rm -rf ; for x in $(df | grep "/lib/" | sed -e 's/.* //g') ; do umount $x ; done ``` De todas formas, se sugiere eliminar y volver a levantar la VM. Esto es por mayor simplicidad y por la seguridad de volver a comenzar con una copia en blanco. ### El dashboard dice `Error: Unable to retrieve volume limit information` Esto se debe a un problema de conexión con `Cinder`, el servicio de Storage de OpenStack. Si la verificación del servicio falla, referirse al apartado de esta sección correspondiente. Si la verificación es exitosa, el error puede deberse a algún defecto de la configuración debido a la falta de soporte de la creación de nodos de almacenamiento. Debemos editar el archivo de configuración de cinder en `NodoOpenStackController` de la siguiente forma: ``` vi /etc/cinder/cinder.conf .................................... [keystone_authtoken] auth_uri = http://:5000 auth_url = http://:35357 auth_plugin = password project_domain_id = default user_domain_id = default project_name = services username = cinder password = {Search CONFIG_CINDER_KS_PW in answer file} ..................................... ``` Para luego resetear los servicios asociados: ``` systemctl restart openstack-cinder-api.service systemctl restart openstack-cinder-backup.service systemctl restart openstack-cinder-scheduler.service systemctl restart openstack-cinder-volume.service ``` ### Alguno de los servicios no corre en la etapa de verificación Esto puede deberse a algún problema de la instalación de Packstack. En nuestra experiencia los resultados de las operaciones corridas son altamente inconsistentes, por lo que la reinstalación de Packstack podría resolver los inconvenientes. Si el problema se encuentra en algún nodo en particular, puede intentarse reinstalarse los servicios asociados a ese nodo agregando al `Answer file` la siguiente variable de configuración: ``` # Listar las IPs privadas de los nodos instalados correctamente EXCLUDE_SERVERS:10.0.2.10,10.0.2.11 ``` Para luego volver a correr la instalación: ``` packstack --answer-file=/root/answer.txt ``` De no resolverse de esta manera, o si el problema se encuentra en la configuración general, se supone que las operaciones de Packstack son idempotentes (en nuestra experiencia, no lo son), por lo que volver a correr la instalación con el `Answer file` original debería resolver la situación. De todas formas, si se continúa recayendo en este tipo de problemas, se recomienda comenzar nuevamente con todo el flujo de este documento. ### Agregar un nodo de Compute cuelga la instalación en `Testing if puppet apply is finished` Este es un error en el que recaímos varias veces y con las configuraciones más diversas. La única solución que encontramos es agregar nodos de cómputo la primera vez que se instala Packstack, y no volver a hacerlo. El tiempo estimado de ejecución de la operación de *Puppet* mencionada en el título es de alrededor de una hora. De tardarse más tiempo se puede estar cayendo en la situación descripta. Para solucionar este problema, entonces, es necesario comenzar desde 0 con el proceso de este documento. ### Packstack falla con el mensaje `Failed to load plugin from file ssl_001.py` Este error es probable que se deba a un problema del encoding de los caracteres. Para solucionarlo, debe agregarse al archivo `~/.bash_rc` las siguientes lineas: ``` LANG=en_US.utf-8 LC_ALL=en_US.utf-8 ``` **Referencias:** * [https://bugs.launchpad.net/packstack/+bug/1740711](https://bugs.launchpad.net/packstack/+bug/1740711) * [https://bugzilla.redhat.com/show_bug.cgi?id=1553463](https://bugzilla.redhat.com/show_bug.cgi?id=1553463) * [https://www.techsupportpk.com/2016/12/installing-openstack-on-multi-node-in-linux.html](https://www.techsupportpk.com/2016/12/installing-openstack-on-multi-node-in-linux.html) ## Autores | Nombre | Legajo | Email | | -------- | -------- | -------- | | Ramiro Olivera Fedi | 56498 | rolivera@itba.edu.ar | | Julián Antonielli | 56390 | jantonielli@itba.edu.ar |