Está en la página 1de 85

Universidad Politécnica de Madrid

Escuela Técnica Superior de Ingenieros de Telecomunicación

DESARROLLO DE ESCENARIOS VIRTUALES


PARA PRÁCTICAS DE LABORATORIO SOBRE
ARQUITECTURAS DE SERVICIOS EN LA NUBE

Autor: Raúl Álvarez Pinilla

Tutor: David Fernández Cambronero

Miembros del tribunal

Presidente: Alejandro Alonso Muñoz


Vocal: David Fernández Cambronero
Secretario: Joaquín Salvachúa Rodríguez
Suplente: Francisco Javier Ruiz Piñar

Fecha de lectura y defensa:

Calificación:
Universidad Politécnica de Madrid
Escuela Técnica Superior de Ingenieros de Telecomunicación

Grado en Ingeniería de Tecnologías y


Servicios de Telecomunicación

TRABAJO FIN DE GRADO

DESARROLLO DE ESCENARIOS VIRTUALES


PARA PRÁCTICAS DE LABORATORIO SOBRE
ARQUITECTURAS DE SERVICIOS EN LA NUBE

Autor: Raúl Álvarez Pinilla

Tutor: David Fernández Cambronero

Miembros del tribunal

Presidente: Alejandro Alonso Muñoz


Vocal: David Fernández Cambronero
Secretario: Joaquín Salvachúa Rodríguez
Suplente: Francisco Javier Ruiz Piñar

Fecha de lectura y defensa:

Calificación:
Resumen
El trabajo consiste en el diseño, desarrollo y prueba de escenarios basados en máquinas
virtuales que implementan servicios en la nube, haciendo énfasis en las soluciones actuales
para dotar de fiabilidad y escalabilidad a dichos servicios.

El escenario virtual en el que se fundamenta el trabajo está compuesto por servidores web,
servidores de disco y un cortafuegos, y mediante él se comprobarán diferentes configuraciones
a implantar. Se centrará principalmente en la creación de un sistema de ficheros distribuido
y en el estudio de las nuevas arquitecturas de red basadas en software para dotar la
funcionalidad de balanceo de carga en el escenario proporcionando alta disponibilidad y
tolerancia a posibles fallos.

Con todo ello se pretende combinar los componentes de una arquitectura de servicios en la
nube y profundizar en el funcionamiento de ella, acercando la visión de un centro de datos
mediante la virtualización de un escenario.

Palabras clave: Computación en la nube, Centro de datos, Virtualización, Sistema de ficheros


_distribuido, Balanceador de carga, Redes definidas por software

Abstract
The project consist of the design, development and testing of scenarios based on virtual
machines which implement cloud services, emphasizing current solutions to provide reliability
and scalability to such services.

The virtual scenario of this project is composed of web servers, disk servers and a firewall,
and through him, different configurations will be checked to introduce. It will focus mainly
on the creation of a distributed file system and the study of new network architectures based
on software to supply the functionality of load balancing providing high availability and
fault tolerance.

All of this is intended to combine the components of a cloud service architecture and go into
detail about its functioning, bringing closer the vision of a data center by virtual network
scenarios.

Key words: Cloud computing, Data center, Virtualization, Distributed file system,
_Load balancer, Software Defined Networking (SDN)
INDICE DE CONTENIDOS
.

1. INTRODUCCIÓN ....................................................................................................................... 1
1.1. Motivación ................................................................................................................................. 1
1.2. Objetivos .................................................................................................................................... 1
1.3. Estructura de la memoria ........................................................................................................... 2

2. DESARROLLO............................................................................................................................ 3
2.1. Preparación del escenario .......................................................................................................... 4
2.1.1. Instalación de VNX ................................................................................................................ 4
2.1.2. Configuración del escenario .................................................................................................. 5
2.1.2.A. Modificación del sistema de ficheros ............................................................................ 7
2.1.2.B. Conexión del escenario con redes externas ................................................................... 8
2.2. Arranque del escenario............................................................................................................. 13
2.3. Sistema de ficheros .................................................................................................................. 15
2.3.1.Configuración de los servidores de disco ............................................................................. 15
2.3.1.A. Volumen distribuido .................................................................................................... 17
2.3.1.B. Volumen en réplica ...................................................................................................... 17
2.3.1.C. Volumen seccionado .................................................................................................... 18
2.3.2. Montaje desde los servidores web ..................................................................................... 19
2.3.2.A. Montaje mediante el comando mount ........................................................................ 19
2.3.2.B. Montaje mediante el fichero fstab .............................................................................. 20
2.3.2.C. Montaje creando un archivo de configuración del volumen ....................................... 21
2.4. Aplicación web ......................................................................................................................... 22
2.5. Balanceador de carga ............................................................................................................... 24
2.5.A. Controlador Floodlight ........................................................................................................ 25
2.5.B. Controlador POX ................................................................................................................. 27
2.6. Firewall ..................................................................................................................................... 30
2.7. Clientes..................................................................................................................................... 35

3. PRUEBAS Y RESULTADOS ................................................................................................. 37


3.1. Análisis de GlusterFS ................................................................................................................ 37
3.2. Recuperación de un Servidor de Disco ...................................................................................... 39
3.3. Análisis del balanceador de carga ............................................................................................. 41
3.4. Comprobación de las políticas de seguridad ............................................................................. 46

4. CONCLUSIONES ..................................................................................................................... 47

BIBLIOGRAFÍA ...................................................................................................................... 49
INDICE DE FIGURAS
DESARROLLO

Figura 2-1: Diagrama lógico del escenario de Centro de Datos y Provisión de Servicios ...................................... 3
Figura 2-2: Diagrama lógico del escenario del trabajo ......................................................................................... 3

Figura 2.1-1 - Sistema COW en un servidor web ................................................................................................... 5


Figura 2.1-2 - Switch de red virtual de libvirt ........................................................................................................ 8
Figura 2.1-3 - Servidor DNS y DHCP de libvirt ....................................................................................................... 8

Figura 2.2-1 - Diagrama de estados de las máquinas virtuales en VNX .............................................................. 13

Figura 2.3-1: Volumen distribuido 10.................................................................................................................... 17


Figura 2.3-2: Volumen en réplica 10 ..................................................................................................................... 17
Figura 2.3-3: Volumen seccionado 10 ................................................................................................................... 18
Figura 2.3-4 - Modelo maestro-esclavo en GlusterFS 11 ...................................................................................... 19

Figura 2.4-1: Página de incio de la Aplicación web ............................................................................................. 22


Figura 2.4-2: Función de Subida de ficheros ........................................................................................................ 23
Figura 2.4-3: Función de Descarga de ficheros .................................................................................................... 23
Figura 2.4-4: Función de Borrado de ficheros ...................................................................................................... 23

Figura 2.5-1: Arquitectura SDN ........................................................................................................................... 24


Figura 2.5-2: Petición de servicio desde FW para comprobar balanceador de carga mediante Floodlight ........ 26
Figura 2.5-3: Arranque del Controlador POX ....................................................................................................... 27
Figura 2.5-4: Arranque del Controlador POX en modo DEBUG ........................................................................... 28
Figura 2.5-5: ARPing hacia los servidores web .................................................................................................... 28
Figura 2.5-6: Envío de una petición de servicio desde un cliente......................................................................... 29
Figura 2.5-7: Envío de una respuesta de servicio desde un servidor web ............................................................ 29

Figura 2.6-1: Pantalla de bienvenida de Firewall Builder .................................................................................... 30


Figura 2.6-2: Creación de un firewall (paso 1) ..................................................................................................... 31
Figura 2.6-3 Creación de un firewall (paso 2) ...................................................................................................... 31
Figura 2.6-4: Configuración de la interfaz eth1 del firewall ................................................................................ 32
Figura 2.6-5: Configuración de la interfaz eth2 del firewall ................................................................................ 32
Figura 2.6-6: Configuración de la interfaz de loopback del firewall .................................................................... 32
Figura 2.6-7: Política de reglas aplicadas en el firewall ...................................................................................... 33
Figura 2.6-8: Instalación de políticas de seguridad en el firewall ........................................................................ 34

Figura 2.7-1: Navegador Firefox desde un cliente a través de un túnel ssh ........................................................ 35
Figura 2.7-2: Código fuente desde Firefox de la Aplicación web ......................................................................... 36
PRUEBAS Y RESULTADOS

Figura 3.1-1 - Captura del envío de la información del volumen ......................................................................... 37


Figura 3.1-2 - Captura de llamada LOOKUP en GlusterFS ................................................................................... 38
Figura 3.1-3: Captura de la llamada WRITE en GlusterFS ................................................................................... 38

Figura 3.2-1 - Uso del comando ifconfig down .................................................................................................... 39


Figura 3.2-2 - Contenido de los servidores de disco ............................................................................................. 39
Figura 3.2-3 - Uso del comando ifconfig up ......................................................................................................... 40
Figura 3.2-4 - Captura de la recuperación de la información en un servidor de disco caído ............................... 40

Figura 3.3-1: Balanceo mediante iperf desde un cliente ..................................................................................... 42


Figura 3.3-2: Balanceo mediante iperf desde varios clientes .............................................................................. 42
Figura 3.3-3: Uso de curl para comprobar balanceo de carga ............................................................................ 43
Figura 3.3-4: Trazas del controlador que verifican el balanceo de carga ............................................................ 43
Figura 3.3-5: Captura de tráfico de paquetes OpenFlow ..................................................................................... 43
Figura 3.3-6: Tabla de flujos del switch virtual en LAN2 ...................................................................................... 44
Figura 3.3-7: Diagrama físico de LAN2 ................................................................................................................ 45
Figura 3.3-8: Trazas del controlador al realizar una petición de servicio desde un navegador ........................... 45

Figura 3.4-1: Ping desde C1 hacia FW ................................................................................................................. 46


Figura 3.4-2: Captura de tráfico para comprobar la regla 4 del firewall ............................................................. 46
1. Introducción
En el día de hoy la computación en la nube sigue en continuo crecimiento y progresivamente
ofrece a los usuarios más tipos de servicios. Las aplicaciones telemáticas son de gran
complejidad y cada vez demandan mayor cantidad de recursos de computación, red y
almacenamiento. Asimismo, los usuarios exigen a los servicios un comportamiento eficiente,
fiable y seguro. Por ello surge la necesidad de grandes infraestructuras de redes de
comunicaciones y de centros de datos.

Otra de las razones de la necesidad de disponer de grandes centros de datos es la creciente


tendencia que existe de mover aplicaciones e infraestructuras desde centros de datos
corporativos de un tamaño pequeño a otros de mayor tamaño, que son mantenidos por grandes
proveedores. Esto permite a pequeños negocios ahorrar elevados costes en inversión
económica y pagar únicamente por el consumo efectuado, teniendo un servicio de forma
flexible y adaptativa.

A parte de las características mencionadas, los centros de datos proporcionan muchas más,
como pueden ser, gran escalabilidad, mayor fiabilidad, mejor conectividad con proveedores y
facilidad en la gestión.

1.1. Motivación
Con el objeto de conocer las tecnologías usadas para proporcionar servicios en la nube en
los centros de datos de hoy en día es necesario disponer de escenarios didácticos que
permitan entender y practicar dichas tecnologías.

A través de la virtualización de un escenario que recrea un centro de datos, se proporcionará


a los equipos clientes un servicio de compartición de ficheros escalable que cumplirá los
requisitos de un servicio alojado en la nube.

1.2. Objetivos
Se partirá de un escenario proporcionado en la práctica final de Centro de Datos y Provisión
de Servicios con el propósito de su perfeccionamiento, y así dotarlo de nuevas
funcionalidades usadas actualmente en los grandes centros de datos del mundo.

Con ello se profundizará en el conocimiento de las tecnologías usadas y se propondrán


nuevas funcionalidades. Los puntos en los que se centrará principalmente el trabajo serán el
análisis de un sistema de ficheros distribuido para el servicio a través de GlusterFS y el
estudio e incorporación de un balanceador de carga utilizando la tecnología SDN (Software
Defined Networking). Además, será necesario centrarse en otros aspectos durante el
transcurso del trabajo como la virtualización a través de la herramienta VNX, la
implementación de una aplicación web, y la creación y configuración de un firewall.

1
Introduccion

1.3. Estructura de la memoria


Se ha seguido el siguiente esquema a lo largo de la memoria:

En el Capítulo 2: Desarrollo se presentan las diferentes etapas que se han seguido desde la
preparación del escenario hasta que un cliente puede acceder al servicio, pasando por los
diferentes elementos que son necesarios configurar para cumplir con los requisitos de un
servicio en la nube.

En el Capítulo 3: Pruebas y resultados se han analizado diferentes puntos del escenario para
comprobar el correcto funcionamiento de sus elementos. Las pruebas se han centrado
fundamentalmente en el sistema de ficheros y en el balanceador de carga.

En el Capítulo 4: Conclusiones se ofrece una visión final sobre el trabajo realizado y posibles
líneas de trabajo futuro que se podrían seguir.

Se ha utilizado un código de colores en los diferentes cuadros que aparecerán a lo largo de


la memoria. Un relleno anaranjado mostrará el contenido total o parcial de un fichero
específico, como puede ser un script, y un relleno de color gris claro indicará comandos
ejecutados en un terminal.

CONTENIDO DE FICHEROS

COMANDOS EN UN TERMINAL

Todos los comandos que se muestran a lo largo del trabajo se encuentran con privilegios de
root, por lo tanto el lector puede anteponer sudo a todos ellos o bien pasar a ser root con el
comando sudo su.

2
2. Desarrollo
A lo largo de este capítulo se describirán los diferentes pasos que se han seguido para modificar
y mejorar el escenario virtual que emula el funcionamiento de un servicio de compartición de
ficheros escalable implementado sobre un centro de datos.

El escenario de partida del trabajo es el propuesto en la práctica final de la Centro de Datos y


Provisión de Servicios, que se encuentra compuesto por tres equipos clientes, tres servidores
web, tres servidores de disco y un router que realiza balanceo de carga entre los diferentes
servidores web. Su diagrama lógico es el que se muestra a continuación:

Figura 2-1: Diagrama lógico del escenario de Centro de Datos y Provisión de Servicios 1

Sobre el anterior escenario se ha decidido realizar los siguientes cambios:


 La función de balanceador de carga recaerá sobre un controlador SDN que se conectará
a un switch de la subred LAN2 de tipo Open vSwitch 2. Se escogerá este tipo de switch
virtual ya que es compatible con el controlador SDN.
 El router LB de acceso al servicio se cambiará por un firewall al que se le aplicarán
unas políticas de seguridad.
De esta forma, el escenario propuesto en el que se basará este trabajo es el siguiente:

Figura 2-2: Diagrama lógico del escenario del trabajo

3
Desarrollo

2.1. Preparación del escenario


Se utilizará la herramienta de virtualización VNX (Virtual Networks over linuX) 3, que se
encargará de la creación del escenario propuesto sobre el ordenador, incluyendo redes
virtuales creadas por switches virtualizados. Para ello será necesario, tras el diseño del
escenario, la especificación de un fichero .xml que tendrá el siguiente formato:

<?xml version="1.0" encoding="UTF-8"?>


<vnx>
(definiciones globales: <global>)
(definiciones de redes virtuales: <net>)
(definiciones de máquinas virtuales: <vm>)
(definiciones del equipo host: <host>)
</vnx>

De esta forma se proporcionará a la herramienta VNX la configuración de cada uno de los


elementos que componen el escenario y la interconexión entre ellos.

2.1.1. Instalación de VNX


La instalación se encuentra descrita paso a paso en el portal de la herramienta, y tras ella
será necesario descargar alguno de los sistemas de ficheros preconfigurados que facilita la
herramienta desde su repositorio. En nuestro caso, se utilizará el sistema de ficheros
proporcionado por LXC (Linux Containers) 4, que es una tecnología de contenedores que
permite crear sistemas Linux contenidos dentro de otro aplicándole algunos límites de CPU,
memoria o incluso asignarle interfaces de red, tratándolo como si fuera un equipo
independiente. La ventaja de LXC respecto a otras tecnologías de virtualización es su
ligereza, ya que utiliza recursos mínimos dando así respuestas mucho más rápidas. Como
inconveniente cabe mencionar que no hay interfaz gráfica (GUI) para configuración, por lo
que todo se realizará a través del terminal de cada máquina virtual.

Se puede descargar el sistema de ficheros directamente desde el repositorio o desde la


herramienta vnx_download_rootfs que proporciona VNX. El archivo comprimido
necesario a descargar para nuestro escenario se llama “vnx_rootfs_lxc_ubuntu-XX.XX-
vXXX.tgz”. Si el sistema operativo lo permite también se encuentra disponible una versión
de 64 bits.

Es importante recordar a lo largo de la práctica que el sistema de ficheros descargado


dispone de los usuarios “root” y “vnx”, con contraseña “xxxx” en ambos.

4
Desarrollo

2.1.2. Configuración del escenario


Las máquinas virtuales pueden utilizar el sistema de ficheros que se ha descargado de dos
formas posibles, en modo directo o en modo cow (copy on write) 5. Cuando una máquina
virtual utiliza el sistema de ficheros en modo directo solo podrá ser usado un sistema de
ficheros por máquina virtual, por lo que para nuestro escenario sería necesario disponer de
numerosas copias de sistemas de ficheros. La opción de copy on write será la que se utilice
ya que permite que varias máquinas virtuales puedan utilizar el mismo sistema de ficheros.
En el escenario propuesto será útil porque los tres servidores web podrán utilizar un mismo
sistema de ficheros, e igual sucede con los servidores de disco y los clientes.

El sistema copy on write devuelve punteros a un mismo sistema de ficheros, y en el


momento en que un proceso intenta modificar algún fichero del sistema, se crea una copia
para prevenir que los cambios producidos por dicho proceso sean visibles por todos los
demás. Todo ocurre de forma transparente para los procesos, y de esta forma no se crea
ninguna copia adicional del recurso si ningún proceso llega a realizar modificaciones.

De esta forma, se dispondrá del sistema de ficheros de sólo lectura que se encontrará
disponible el directorio filesystems de VNX (/usr/share/vnx/filesystems), y del directorio
(read and write) donde se encontrarán las modificaciones del sistema de ficheros. Además
se dispondrá de un directorio en el cual se encuentran punteros del sistema de ficheros
completo de la máquina virtual. En el siguiente diagrama se muestra un ejemplo de lo
comentado en la máquina virtual WWW1:

Figura 2.1-1 - Sistema COW en un servidor web

En este punto se puede plantear la práctica de diferentes formas dependiendo que opción
se utilice respecto a los sistemas de ficheros:

 Crear un único sistema de ficheros que compartirán todas las máquinas virtuales
reduciendo el espacio utilizado en disco.

 Crear varios sistemas de ficheros para aislar el software de los diferentes grupos de
máquinas virtuales.

5
Desarrollo
Si se escoge la opción de tener varios sistemas de ficheros, se tendrá que realizar la copia
del sistema de ficheros descargado y modificar dos líneas del fichero config de cada uno de
los sistemas de ficheros copiados. En las líneas a modificar se deberá indicar la ruta del
directorio rootfs y del fichero fstab del sistema de ficheros correspondiente. El siguiente
ejemplo corresponde al sistema de ficheros que se utilizará en los servidores web:

lxc.rootfs = /usr/share/vnx/filesystems/vnx_rootfs_lxc_ubuntu-13.10-
v025-WWW/rootfs
lxc.mount = /usr/share/vnx/filesystems/vnx_rootfs_lxc_ubuntu-13.10-
v025-WWW/fstab

Además, en la plantilla .xml del escenario se indicará en cada máquina virtual su


correspondiente sistema de ficheros:

<filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-WWW
</filesystem>

Para la instalación de los diferentes paquetes necesarios en las máquinas virtuales se puede:

a) Modificar directamente el sistema de ficheros descargado cuando el escenario no


se encuentre arrancado. En este caso se está modificando el sistema de ficheros de
sólo lectura que compartirán las máquinas virtuales.

b) Configurar en las máquinas virtuales del escenario una interfaz con conexión a
Internet e instalar en cada máquina los paquetes necesarios. Mediante esta opción
se crearán copias de los archivos modificados del sistema de ficheros en cada
máquina virtual de forma individualizada.

Para el desarrollo del trabajo se instalarán los siguientes paquetes:

Máquina virtual Identificador Paquetes


Controlador SDN CONTROLLER Git
Servidores de disco NAS GlusterFS
Servidores web WWW Apache2 , PHP5 , GlusterFS , Iperf
Firewall FW Firewall Builder , Xauth
Clientes C Firefox , Iperf , Curl , Xauth

6
Desarrollo
Para la instalación de los paquetes mencionados se ejecutarán las siguientes órdenes en las
correspondientes máquinas virtuales:

Paquete Comando de instalación


Git # apt-get install git

GlusterFS # apt-get install glusterfs-server

Apache2 # apt-get install apache2

PHP5 # apt-get install php5

Firewall Builder # apt-get install fwbuilder

Iperf # apt-get install iperf

Curl # apt-get install curl

Xauth # apt-get install xauth

En los siguientes subapartados se describirán los dos procedimientos comentados para la


instalación de los paquetes necesarios en las máquinas virtuales.

2.1.2.A. Modificación del sistema de ficheros


Dado un cierto sistema de ficheros rootfs_lxc_ubuntu, que se encuentra en el directorio
/usr/share/vnx/filesystems, se explicará cómo modificarlo para añadir los paquetes que se
consideren oportunos. De esta forma, al arrancar el escenario las máquinas virtuales que
dependan de tal sistema de ficheros tendrán modificado su sistema de ficheros con los
cambios que se hayan realizado. Como ventaja de este método cabe nombrar que al estar
utilizando copy on write en la virtualización se reduce el espacio de disco utilizado, ya
que varias máquinas virtuales están utilizando la misma imagen de disco con los paquetes
ya instalados.

Para ello se arrancará una máquina virtual que utilice en modo directo y con conectividad
a Internet el sistema de ficheros descargado:

# lxc-start –n MV –f
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu/config

Una vez arrancada se activará la red utilizando el comando dhclient a la interfaz eth0:

# dhclient eth0

De esta forma, tal interfaz se conectará al switch virtual lxcbr0 que proporcionará acceso
a Internet y ya se podrán instalar los paquetes necesarios. Finalizada la instalación se
parará la máquina virtual con el comando halt, quedando los cambios realizados visibles
desde todas las máquinas virtuales de nuestro escenario que dependan del sistema de
ficheros modificado.

7
Desarrollo
2.1.2.B. Conexión del escenario con redes externas
La otra opción disponible, para la instalación de los paquetes necesarios en el escenario,
es dotar a las diferentes máquinas virtuales de una interfaz de red conectada a un switch
virtual con conexión a Internet. En nuestro caso se dispone de dos redes virtuales creadas
por defecto con sus correspondientes switches virtuales: virbr0 y lxcbr0.

A continuación se explicará el funcionamiento de este tipo de redes y switches virtuales,


más en concreto virbr0, que es proporcionado por libvirt 6.

Libvirt es una interfaz de programación de aplicaciones (API) que interactúa con varios
hipervisores de virtualización y ofrece diferentes funciones, como por ejemplo la creación
de redes virtuales.

Se utilizará el switch de red virtual


virbr0 que está disponible tras la
instalación de la herramienta VNX.

A este switch se conectarán las


diferentes máquinas virtuales de
nuestro escenario y en el momento
que se precise de conexión con el
exterior será posible. 7
Figura 2.1-2 - Switch de red virtual de libvirt 7

Para realizar la conexión es necesario solicitar desde la máquina virtual deseada una
petición desde el cliente de DHCP. De esta forma se enviarán peticiones broadcast por la
interfaz creada solicitando información de configuración, y así conseguir una dirección
IP junto con otros parámetros
relevantes para el correcto
funcionamiento del sistema en la
red, como la máscara de red, el
router por defecto y los servidores
de DNS. El servidor DHCP
otorgará a la máquina virtual una
dirección IP del rango
192.168.122.2 – 192.168.122.254
Figura 2.1-3 - Servidor DNS y DHCP de libvirt 7

8
Desarrollo
Se puede comprobar que está activo el switch virtual virbr0, que viene preconfigurado
por defecto, mediante el comando ifconfig o brctl show en el que se obtendrán los
siguientes resultados:

# ifconfig virbr0
Link encap:Ethernet direcciónHW fe:35:18:d7:76:81
Direc.inet:192.168.122.1 Difus.:192.168.122.255 Másc:255.255.255.0
ACTIVO DIFUSIÓN FUNCIONANDO MULTICAST MTU:1500 Métrica:1
Paquetes RX:27 errores:0 perdidos:0 overruns:0 frame:0
Paquetes TX:18 errores:0 perdidos:0 overruns:0 carrier:0
colisiones:0 long.colaTX:0
Bytes RX:2884 (2.8 KB) TX bytes:1934 (1.9 KB)

# brctl show virbr0


bridge name bridge id STP enabled interfaces
virbr0 8000.000000000000 yes

También existen unas funciones disponibles a través del comando virsh mediante el cual
se obtiene más información, como por ejemplo:

 Muestra el listado de redes (en nuestro caso la red que utilizada es default, que deberá
venir preconfigurada)

# virsh net-list
Nombre Estado Inicio automático Persistente
-------------------------------------------------------------
default activo si si

 Muestra información general sobre la red solicitada

# virsh net-info default


Nombre default
UUID 70a01cdb-e771-462c-8ec1-8a7f64c57088
Activar: si
Persistente: si
Autoinicio: si
Puente: virbr0

9
Desarrollo
 Muestra el fichero .xml de la red solicitada

# virsh net-dumpxml default


<network>
<name>default</name>
<uuid>70a01cdb-e771-462c-8ec1-8a7f64c57088</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0' />
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>

Si en algunas de las comprobaciones no se obtiene un resultado verificando el switch


virtual o se desea crear una nueva red con su switch virtual correspondiente se puede
definir de la siguiente manera:

1 – Creación de un fichero .xml especificando la red a crear en el directorio


/etc/libvirt/qemu/network. A continuación se muestra un ejemplo del fichero
correspondiente de la red preconfigurada default:

<network>
<name>default</name>
<bridge name="virbr0" />
<forward/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
</dhcp>
</ip>
</network>

2 – Definición de la red

# virsh net-define /etc/libvirt/qemu/network/default.xml


La red default se encuentra definida desde default.xml

3 – Configuración de auto-inicio de la red (opcional)

# virsh net-autostart default


La red default se ha sido marcada para iniciarse automáticamente

10
Desarrollo
4 – Inicio de la red

# virsh net-start default


La red default se ha iniciado

Si se desea borrar una red existente se puede hacer uso del siguiente comando:

# virsh net-destroy default


La red default ha sido destruida

Para la creación de la interfaz de red de las máquinas virtuales que se conectará al switch
virtual que se ha descrito se tendrá que modificar la plantilla .xml del escenario.

Se añadirá un nuevo switch virtual con el nombre de virbr0 y la opción managed=”no”


que permitirá a la herramienta VNX en el momento del borrado del escenario no eliminar
la red correspondiente al switch virtual virbr0:

<net name="virbr0" mode="virtual_bridge" managed="no" />

Y en cada una de las máquinas virtuales que se desee tener conexión a Internet se indicará
el nuevo interfaz:

<if id="99" net="virbr0"/>

Una vez arrancado el escenario, como se describe en el apartado 2.1.3. Arranque del
escenario, se podrá comprobar que está disponible tal interfaz de red en las máquinas
virtuales:

# ifconfig eth99
Link encap:Ethernet HWaddr 02:fd:00:00:03:63
inet6 addr: fe80::fd:ff:fe00:363/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:337 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:62098 (62.0 KB) TX bytes:1076 (1.0 KB)

Para solicitar una dirección IP al servidor DHCP, y tener conectividad al exterior, se


utilizará el siguiente comando:

# dhclient eth99

11
Desarrollo
Se puede comprobar la dirección IP asignada utilizando de nuevo el comando ifconfig:

# ifconfig eth99
Link encap:Ethernet HWaddr 02:fd:00:00:03:63
inet addr:192.168.122.153 Bcast:192.168.122.255 Mask:255.255.255.0
inet6 addr: fe80::fd:ff:fe00:363/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:68 errors:0 dropped:0 overruns:0 frame:0
TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10078 (10.0 KB) TX bytes:1920 (1.9 KB)

Y en la tabla de forwarding de las máquinas virtuales se habrá añadido automáticamente


como puerta de enlace la dirección IP 192.168.122.1:

root@FW:~# route
Kernel IP routing table
Destination Gateway Genmask Iface
default 192.168.122.1 0.0.0.0 eth99
10.1.1.0 * 255.255.255.0 eth1
10.1.2.0 * 255.255.255.0 eth2
192.168.122.0 * 255.255.255.0 eth99

Realizando un ping para comprobar la conectividad a cualquier página web disponible en


Internet se comprueba que el resultado es satisfactorio:

# ping www.dit.upm.es
PING www.dit.upm.es (138.4.2.60) 56(84) bytes of data.
64 bytes from www.dit.upm.es (138.4.2.60): seq=1 ttl=51 time=53.5 ms
64 bytes from www.dit.upm.es (138.4.2.60): seq=2 ttl=51 time=54.5 ms
64 bytes from www.dit.upm.es (138.4.2.60): seq=3 ttl=51 time=52.8 ms

--- www.dit.upm.es ping statistics ---


3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 52.814/53.634/54.503/0.715 ms

12
Desarrollo

2.2. Arranque del escenario


El último paso para el funcionamiento del escenario es arrancarlo a través de la herramienta
VNX, la cual ofrece múltiple funcionalidades.

Los comandos a ejecutar tendrán la siguiente estructura:

# vnx –f VNX_file --ACTION [options][-M VM_LIST]

 VNX_FILE es la plantilla .xml creada para el escenario.

 ACTION es una de las diferentes acciones disponibles de la herramienta.

 VM_LIST es una de las posibles opciones en el que la acción a ejecutar sólo se


producirá en la lista de máquinas virtuales indicadas del escenario. Un ejemplo puede
ser -M NAS1,NAS2,NAS3.

A continuación se muestra el diagrama de estados en el que pueden estar las diferentes


máquinas virtuales de un escenario en concreto a través de la herramienta VNX, y sus
diferentes acciones de transición:

Figura 2.2-1 - Diagrama de estados de las máquinas virtuales en VNX

13
Desarrollo
En nuestro caso, las acciones más utilizadas serán create, destroy, shutdown, start y reboot,
siendo sus comandos los siguientes:

# vnx –f VNX_file --create

# vnx –f VNX_file --destroy

# vnx –f VNX_file --shutdown

# vnx –f VNX_file --start

# vnx –f VNX_file --reboot

Cabe mencionar la opción –n al utilizar el comando create o start que permite ocultar las
consolas de las distintas máquinas virtuales arrancadas.

También existen otros comandos de interés de la herramienta VNX a utilizar en el desarrollo


de la práctica como por ejemplo los que se nombran a continuación:

 Ejecuta los comandos indicados con una cierta etiqueta de la plantilla. Este tipo de
comando es útil porque se puede especificar en la plantilla que se ejecuten ciertos
comandos en las máquinas virtuales que se requieran en el momento de arranque de
la propia máquina virtual o cuando se utiliza este comando.

# vnx –f VNX_file --execute TAG [-M VM_LIST]

En la plantilla .xml se configurará de la siguiente forma:

<exec seq="TAG" type="verbatim" ostype="system">


COMANDO_A_EJECUTAR
</exec>

 Muestra las consolas del conjunto de máquinas virtuales del escenario. Aplicando la
opción -M permite mostrar las consolas de aquellas máquinas virtuales indicadas.

# vnx –f VNX_file --console [-M VM_LIST]

 Muestra el estado en el que se encuentran las máquinas virtuales

# vnx –f VNX_file --show-status [-M VM_LIST]

 Muestra un diagrama con las conexiones de red construidas en el escenario.

# vnx –f VNX_file --show-map

14
Desarrollo

2.3. Sistema de ficheros


A continuación se detalla la configuración del sistema de ficheros GlusterFS 8 en el escenario
propuesto con el objetivo de evaluar diferentes propuestas y características de un centro de
datos como pueden ser: escalabilidad, redundancia, tolerancia de fallos, etc.

El proceso se dividirá en dos pasos ya que es necesario configurar tanto los servidores de
disco como los servidores web. El primer paso consistirá en la creación del volumen en los
servidores de disco, donde se podrá disponer de diferentes tipos de volúmenes según las
necesidades requeridas. En el segundo paso se describirán diferentes métodos para realizar
el montaje desde los servidores web, ya que aunque tengan el mismo propósito no son todos
iguales de fiables.

2.3.1. Configuración de los servidores de disco


Para la correcta configuración de los servidores de disco se necesita que cada uno de ellos
disponga de identificadores (UUID) distintos. En nuestro caso, al generar todas las
máquinas virtuales a partir de la misma imagen tienen configurado el mismo identificador.
Por ello, es necesario generar nuevos identificadores. Una posible solución es generar
identificadores nuevos con el comando uuidgen en cada uno de los servidores de disco
NAS2 y NAS3, y sobrescribir el fichero /etc/glusterd/glusterd.info con el nuevo
identificador generado en cada uno de ellos respectivamente. Por ejemplo:

Comandos a ejecutar en el servidor de disco NAS2:

root@NAS2:~# uuidgen
361fbfb4-fa61-49d1-9096-1b8a481476b6
root@NAS2:~# echo UUID=361fbfb4-fa61-49d1-9096-1b8a481476b6>
/etc/glusterd/glusterd.info

Comandos a ejecutar en el servidor de disco NAS3:

root@NAS3:~# uuidgen
6763582b-7fc7-4767-a7d7-e289709c0ba7
root@NAS3:~# echo UUID=6763582b-7fc7-4767-a7d7-e289709c0ba7>
/etc/glusterd/glusterd.info

Tras la ejecución de estos comandos se debe rearrancar el servicio, en cada uno de los NAS,
para que los cambios tengan efecto mediante la siguiente orden:

# service glusterfs-server restart


glusterfs-server stop/waiting
glusterfs-server start/running

15
Desarrollo
El siguiente paso será la creación del clúster de servidores de disco 9. Para ello se necesitará
acceder a uno de los servidores de disco, por ejemplo NAS1, y agregar los servidores al
repositorio ejecutando el comando gluster peer probe seguido de la dirección IP de los
demás servidores:

root@NAS1:~# gluster peer probe 10.1.3.22


Probe successful
root@NAS1:~# gluster peer probe 10.1.3.23
Probe successful

Se puede verificar que se han añadido correctamente desde cualquiera de los servidores
NAS de la siguiente manera:

root@NAS1:~# gluster peer status


Number of Peers: 2

Hostname: 10.1.3.22
Uuid: 361fbfb4-fa61-49d1-9096-1b8a481476b6
State: Peer in Cluster (Connected)

Hostname: 10.1.3.23
Uuid: 6763582b-7fc7-4767-a7d7-e289709c0ba7
State: Peer in Cluster (Connected)

Si se necesita descartar algún servidor añadido al cluster se puede hacer uso del siguiente
comando:

root@NAS1:~# gluster peer detach IPADDRESS


Detach successful

Una vez añadidos los servidores de disco se procederá a crear el volumen con la
configuración que se considere más apropiada. Se deberá seguir el siguiente formato en el
comando de creación:

# gluster volume create VOLNAME [stripe COUNT | replica COUNT]


NEW-BRICK1 NEW-BRICK2 NEW-BRICK3...

Los distintos modelos de configuración se tratarán en los siguientes subapartados:

- Volumen distribuido
- Volumen en replica
- Volumen seccionado
Existen otras posibilidades que se pueden aplicar en GlusterFS que son combinaciones
entre las configuraciones anteriores.

16
Desarrollo
2.3.1.A. Volumen distribuido
Se distribuyen los archivos de
forma aleatoria entre los bloques
del volumen. En este modo de
configuración hay que tener en
cuenta que la avería de algún
servidor de disco puede resultar una
grave pérdida de datos, ya que el
contenido del servidor caído se
perderá del volumen. Como ventaja
en esta configuración cabe destacar Figura 2.3-1: Volumen distribuido 10
la eficiencia en la escritura de datos.10

El comando de creación en esta configuración debe seguir el siguiente formato:

# gluster volume create NEW-VOLNAME NEW-BRICK...

Siendo en nuestro escenario el siguiente:

# gluster volume create nas 10.1.3.21:/nas 10.1.3.22:/nas


10.1.3.23:/nas

2.3.1.B. Volumen en réplica


Se copian los archivos a través de los
bloques del volumen. Esta
configuración proporciona una
mayor fiabilidad ya que se tendrá
redundancia en la información
almacenada y garantizará mayor
disponibilidad del servicio. El
inconveniente en este tipo de
volumen es la cantidad de tráfico
generado, ya que los cambios se
distribuyen al mismo tiempo a todos Figura 2.3-2: Volumen en réplica 10

los bloques del volumen.

El comando de creación en esta configuración debe seguir el siguiente formato:

# gluster volume create NEW-VOLNAME [replica COUNT] NEW-BRICK..

Siendo en nuestro escenario el siguiente:

# gluster volume create nas replica 3 10.1.3.21:/nas


10.1.3.22:/nas 10.1.3.23:/nas

17
Desarrollo
2.3.1.C. Volumen seccionado
En esta configuración los archivos
son fragmentos en diferentes
porciones que se reparten entre los
diferentes bloques que componen el
volumen. Es generalmente utilizado
para almacenar archivos de gran
tamaño en entornos de alta
concurrencia.
Figura 2.3-3: Volumen seccionado 10

El comando de creación en esta configuración debe seguir el siguiente formato:

# gluster volume create NEW-VOLNAME [stripe COUNT] NEW-BRICK..

Siendo en nuestro escenario el siguiente:

# gluster volume create nas stripe 3 10.1.3.21:/nas


10.1.3.22:/nas 10.1.3.23:/nas

Una vez creado el volumen se puede comprobar la información del volumen:

# gluster volume info


Volume Name: nas
Type: XXX
Status: Created
Number of Bricks: 3
Transport-type: tcp
Bricks: ...

Tras la creación del volumen será necesario su inicialización mediante el comando:

# gluster volume start nas


Starting volume nas has been successful

Si en algún determinado momento es necesario eliminar el volumen creado se debe seguir


el siguiente procedimiento:

# gluster volume stop nas


Stopping volume will make its data inaccessible.
Do you want to continue? (y/n) y
Stopping volume nas has been successful

# gluster volume delete nas


Deleting volume will erase all information about the volume.
Do you want to continue? (y/n) y
Deleting volume nas has been successful

18
Desarrollo

2.3.2. Montaje desde los servidores web


El último paso para finalizar la configuración del sistema de ficheros es realizar el montaje
desde los servidores web, ya que necesitan conocer el volumen creado, así como su
configuración y bloques que lo componen.

En el momento del montaje se especificará desde cada servidor web uno de los tres
servidores de disco del escenario, los cuales poseen la información del volumen creado en
el directorio/etc/glusterd/vols/nas.

Una vez realizado el montaje, los servidores


web conocerán cada uno de los servidores
de disco que componen el volumen para
mantener el sistema de ficheros.

El sistema de ficheros GlusterFS funciona


basándose en un modelo maestro-esclavo,
siendo en nuestro caso el maestro los
servidores web, y el esclavo los servidores
de disco del escenario.11 Figura 2.3-4 - Modelo maestro-esclavo en GlusterFS 11

Para las diferentes formas de montaje es necesario tener en el sistema un módulo cargable
de núcleo conocido como FUSE (Filesystem in Userspace) 12. Para su creación basta con
ejecutar el siguiente comando mknod 13 creando el correspondiente archivo de dispositivo:

# mknod -m 666 /dev/fuse c 10 229

A continuación se describirán diferentes métodos de montaje que se diferenciarán entre sí


porque proporcionarán distintos grados de automatización y fiabilidad en el montaje.

2.3.2.A. Montaje mediante el comando mount


Para acceder al sistema de ficheros exportado por los servidores de disco se puede utilizar
directamente el comando mount, ya que es una de las opciones más rápidas de montaje.

Solamente será necesaria la creación de un directorio y ejecutar mount indicando el punto


de montaje en el directorio creado del servidor web. Un posible ejemplo es el siguiente:

# mkdir /mnt/nas

root@NAS1:~# mount -t glusterfs 10.1.3.21:/nas /mnt/nas


root@NAS2:~# mount -t glusterfs 10.1.3.22:/nas /mnt/nas
root@NAS3:~# mount -t glusterfs 10.1.3.23:/nas /mnt/nas

En este caso, si falla el servidor de disco que se indica en el momento del montaje se
perderá el sistema de ficheros en el servidor web correspondiente.

19
Desarrollo
2.3.2.B. Montaje mediante el fichero fstab
El fichero /etc/fstab (File System Table) 14 forma parte de la configuración del sistema y
es el encargado de reflejar cómo se montan los discos en el sistema de ficheros. Lo que
está escrito en tal fichero sirve para tener acceso a los discos una vez que se inicia el
sistema operativo.

Este procedimiento se puede considerar una versión avanzada del montaje visto
anteriormente ya que se modificará el fichero fstab para que el sistema monte
automáticamente el sistema de ficheros proporcionado por los servidores de disco.

Para ello, será necesario añadir la siguiente línea al fichero fstab:

IPADDRESS:/VOLNAME MOUNTDIR glusterfs defaults,_netdev 0 0

En nuestro caso, el fichero fstab quedará con el siguiente contenido:

# UNCONFIGURED FSTAB FOR BASE SYSTEM

10.1.3.21:/nas /mnt/nas glusterfs defaults,_netdev 0 0

Para proceder al montaje una vez modificado el fichero fstab se puede reiniciar la máquina
virtual mediante el comando reboot, o directamente utilizar el comando mount –a.

Si al arrancar de nuevo alguna de las máquinas no se cargara automáticamente el sistema


de ficheros será necesario modificar el fichero /etc/rc.local dejándolo con el siguiente
contenido:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
mount -a
exit 0

Sin embargo, se tiene el mismo problema que en el montaje mediante el comando mount,
donde si no se encuentra disponible el servidor de disco indicado en el momento del
montaje no se cargará el sistema de ficheros en el servidor web correspondiente.

20
Desarrollo
2.3.2.C. Montaje creando un archivo de configuración del volumen
En este modo de montaje se pretende crear un archivo de configuración del volumen
indicando diferentes puntos de montaje. Dado el escenario se indicarán tres puntos de
montaje del volumen, uno por cada servidor de disco del escenario. Este tipo de montaje
se garantiza que se comprobarán todos los puntos de montaje indicados, evitando el
problema que se mencionaba en los otros dos métodos anteriores.

Para ello, se debe modificar el fichero /etc/fstab indicando donde se encuentra el archivo
de configuración del volumen:

# UNCONFIGURED FSTAB FOR BASE SYSTEM

/etc/glusterfs/datastore.vol /mnt/nas glusterfs


rw,allow_other,default_permissions,max_read=131072 0 0

Se creará un archivo de configuración llamado datastore.vol en el directorio /etc/glusterfs.


Su contenido es el siguiente:

volume remote1
type protocol/client
option transport-type tcp
option remote-host 10.1.3.21
option remote-subvolume /nas
end-volume

volume remote2
type protocol/client
option transport-type tcp
option remote-host 10.1.3.22
option remote-subvolume /nas
end-volume

volume remote3
type protocol/client
option transport-type tcp
option remote-host 10.1.3.23
option remote-subvolume /nas
end-volume

volume replicate
type cluster/replicate
subvolumes remote1 remote2 remote3
end-volume

volume writebehind
type performance/write-behind
option window-size 1MB
subvolumes replicate
end-volume

21
Desarrollo
volume cache
type performance/io-cache
option cache-size 512MB
subvolumes writebehind
end-volume

Para realizar el montaje sin reiniciar el sistema es posible utilizar el comando mount -a.
Se puede comprobar el estado del montaje de la siguiente forma:

root@WWW1:/# df -h
S.ficheros Montado en
/etc/glusterfs/datastore.vol /mnt/nas

Así, aunque en el momento del montaje no se encuentre accesible el servidor de disco


NAS1, se intentará con NAS2, y en caso de fallo se intentará con NAS3, siendo esta
opción la más fiable de las mencionadas.

2.4. Aplicación web


Se ha desarrollado para el escenario una aplicación web que permite a los diferentes usuarios
subir, descargar y borrar ficheros que se alojan en los servidores de disco. Para ello las
tecnologías utilizadas han sido HTML y PHP5.

Se pretende proporcionar una interfaz sencilla para el usuario donde en todo momento pueda
seleccionar una de las opciones que se han comentado. Por ello se ha utilizado una estructura
de marcos con cuatro frames, donde uno de ellos se encargará de permitir al usuario realizar
la acción que seleccione a partir de un menú. De esta forma, la página principal es la
siguiente:

Figura 2.4-1: Página de incio de la Aplicación web

22
Desarrollo
 SUBIDA DE FICHEROS: Se puede realizar una subida múltiple seleccionando
varios archivos en la ventana emergente que se muestra. Para el correcto
funcionamiento es necesario que los directorios /tmp y /mnt/nas dispongan de
permisos de lectura y escritura para todos los usuarios.

Figura 2.4-2: Función de Subida de ficheros

 DESCARGA DE FICHEROS: Se mostrará una lista con todos los archivos que se
encuentran disponibles para descargar.

Figura 2.4-3: Función de Descarga de ficheros

 BORRADO DE FICHEROS: Se mostrará una lista con los archivos alojados en los
servidores. Se notificará mediante una ventana emergente cuando se haya eliminado
el archivo deseado correctamente.

Figura 2.4-4: Función de Borrado de ficheros

23
Desarrollo

2.5. Balanceador de carga


Según el escenario propuesto se pretende balancear la carga entre los diferentes servidores
web que se disponen y así se podrán repartir las peticiones de servicio que se reciban. En
este caso, se ha decidido realizar esta funcionalidad a través de la tecnología SDN (Software
Defined Networking) 15, ya que proporciona una nueva visión sobre las configuraciones y
funciones de la red mediante el control y centralización gestionado por software.

La aplicación software que se encarga de la red se denomina controlador, y en el escenario


se situará en la máquina virtual denominada CONTROLLER. De esta forma, en el controlador
se encontrará la Capa de Control y en los dispositivos de red la Capa de Infraestructura. Para
la comunicación entre ambas capas será necesario la utilización de un protocolo.
Actualmente, existe un proyecto en el que trabajan varias empresas del mundo, que forman
parte de la Open Networking Fundation (ONF) 16, con el objetivo del desarrollo de un
protocolo de código abierto llamado OpenFlow, siendo el más ampliamente aceptado en
SDN, pero cabe mencionar que existen otras iniciativas para la comunicación entre las capas
mencionadas.

En cada uno de los dispositivos de la red se encuentra una parte denominada Tabla de Flujos,
que recoge todas las acciones que debe realizar un switch a medida que se recibe un nuevo
flujo por alguno de sus puertos. El controlador es el encargado de añadir entradas en la tabla
de flujos de cada switch.

Existe una tercera capa, la Capa de Aplicación, que es la de más alto nivel y aporta la
capacidad de crear aplicaciones a través de una API (application programming interface).
De esta forma, la estructura SDN es la siguiente:

Figura 2.5-1: Arquitectura SDN

24
Desarrollo
Dependiendo de la API utilizada existen múltiples controladores que se diferenciaran
fundamentalmente en cuanto al lenguaje de programación y la plataforma. Algunas de las
alternativas de controladores SDN OpenFlow son:

 Python: POX, Ryu


 Java: Floodlight, Beacon
 Ruby: Trema

El estudio se ha centrado en los controladores Floodlight y POX, ya que son dos


controladores que vienen con la funcionalidad de balanceo de carga implementada en cierta
medida, y por sus características se han considerado apropiados para el escenario.

En un primer momento se trabajó con el controlador Floodlight en el escenario propuesto,


pero no se alcanzó el balanceo de carga correctamente ya que solo se produce en peticiones
que se realizan desde la misma subred. Por ello se decidió examinar nuevas alternativas y se
realizó el estudio con el controlador POX, con el cual se han alcanzado los objetivos
satisfactoriamente y se balancea el tráfico en el escenario en su totalidad. A continuación se
detalla más información sobre cada uno de ellos para dotar de la función de balanceo de
carga al escenario.

2.5.A. Controlador Floodlight


Es un controlador que está basado en Java, y para su correcto funcionamiento debe estar
ejecutándose en el propio host o en una máquina virtual donde el sistema de ficheros sea
en modo directo. Si se decide instalar el controlador en el host se deberá indicar en la
plantilla .xml del escenario que en la red LAN2 el controlador se encontrará en
127.0.0.1:6633. Si se escoge la otra opción, y se decide utilizar una máquina virtual en
modo directo es necesario modificar la plantilla .xml del escenario con la siguiente línea:

<filesystem type="direct">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-CONTROLLER
</filesystem>

El proceso de instalación e inicialización se encuentra descrito en la documentación del


proyecto Floodlight 17, donde también se especifica el funcionamiento del módulo
balanceador de carga.

Para trasmitir los parámetros del balanceador al controlador, será necesario crear un script
y mediante la conexión de curl será suficiente. En el escenario propuesto se utilizará el
siguiente script:

25
Desarrollo
#!/bin/sh
curl -X POST -d
'{"id":"1","name":"vip1","protocol":"tcp","address":"10.1.2.10","port":"8"}'
http://localhost:8080/quantum/v1.0/vips/
curl -X POST -d '{"id":"1","name":"pool1","protocol":"tcp","vip_id":"1"}'
http://localhost:8080/quantum/v1.0/pools/
curl -X POST -d '{"id":"1","address":"10.1.2.11","port":"8","pool_id":"1"}'
http://localhost:8080/quantum/v1.0/members/
curl -X POST -d '{"id":"2","address":"10.1.2.12","port":"8","pool_id":"1"}'
http://localhost:8080/quantum/v1.0/members/
curl -X POST -d '{"id":"3","address":"10.1.2.13","port":"8","pool_id":"1"}'
http://localhost:8080/quantum/v1.0/members/

Con todo esto se tendrá el controlador Floodlight funcionando, pero como se ha comentado
anteriormente, solo balanceará peticiones de la misma subred donde se encuentran los
servidores web. Para ello se puede comprobar realizando una petición de servicio desde la
máquina FW:

Figura 2.5-2: Petición de servicio desde FW para comprobar balanceador de carga mediante Floodlight

Una de las ventajas que se ha encontrado que tiene Floodlight es que incorpora un portal
web en el que se recoge información sobre el controlador. Para acceder basta con conectarse
desde el navegador a la dirección localhost:8080/ui/index.html.

Sin embargo, se han encontrado varios inconvenientes en el escenario:

 No se ha alcanzado el balanceo de carga en su totalidad, ya que los clientes deben


encontrarse en la misma subred que los servidores web.
 El controlador debe estar ejecutándose en el propio host o en una máquina virtual
donde el sistema de ficheros sea en modo directo, no tipo cow como se estaba
utilizando hasta ahora.
 Requiere importante espacio libre en disco, ya que se precisa la instalación de
diferentes paquetes

Por las anteriores razones, se decidió estudiar y probar el controlador POX con el objetivo
de dotar al escenario con la funcionalidad de balanceo de carga a las diferentes peticiones
de servicio que se envíen desde los equipos clientes.

26
Desarrollo

2.5.B. Controlador POX


Es un controlador que tiene una interfaz OpenFlow y puede estar ejecutándose en cualquier
plataforma: Linux, Windows, Mac OS, etc. Se constituye por diversos componentes que
pueden ser reutilizados para la adaptación según considere el usuario. En nuestro caso se
modificará el componente de balanceo de carga para adaptarlo al escenario propuesto.

Para su instalación solo es necesario disponer en la máquina de Git y ejecutar el siguiente


comando para obtener una copia del repositorio del proyecto:

# git clone http://github.com/noxrepo/pox


# cd pox

El componente encargado del balanceo de carga se encuentra implementado, dentro del


proyecto, en el fichero pox/misc/ip_loadbalancer.py. Es necesario realizar diferentes
modificaciones en el fichero para personalizarlo en el escenario propuesto.

Para poner en marcha el controlador se utiliza el componente de inicio pox.py. De esta


forma, para arrancar cualquier modulo se sigue la siguiente orden:

root@CONTROLLER:/pox# ./pox.py NOMBRE_COMPONENTE [OPCIONES]

En nuestro caso, para arrancar el balanceador de carga:

root@CONTROLLER:/pox# ./pox.py misc.ip_loadbalancer


--ip=10.1.2.10 --servers=10.1.2.11,10.1.2.12,10.1.2.13

Figura 2.5-3: Arranque del Controlador POX

27
Desarrollo
También es posible arrancarlo en un modo de depuración donde es posible obtener más
información al respecto de los eventos que suceden en el controlador. Para ello hay que
añadir la opción log.level --DEBUG, como se muestra en la siguiente captura:

Figura 2.5-4: Arranque del Controlador POX en modo DEBUG

Como se muestra en la captura


anterior, el controlador envía
periódicamente mensajes ARP a los
diferentes servidores, que se le han
proporcionado en su arranque, para
comprobar que se encuentran
activos y así enviar las posibles
peticiones de servicio hacia ellos. Si
pasado un cierto tiempo del envío
del mensaje ARP Request no se
recibe ninguna respuesta por parte
de algún servidor, mediante un
mensaje ARP Reply, se considerará
que el servidor está caído y no se
Figura 2.5-5: ARPing hacia los servidores web enviarán peticiones hacia él.

28
Desarrollo
Al recibir una petición de servicio el switch verificará si en su tabla de flujos tiene algún
flujo asociado. En caso de no tenerlo se lo comunicará al controlador que examinará cuál
de los servidores de encuentra activo y según el algoritmo implementado informará a la
tabla de flujos del switch para redirigir la petición hacia al servidor web seleccionado. En
nuestro caso, se encuentra implementado un algoritmo round robin 18 entre los servidores
web para balancear las diferentes conexiones abiertas en los clientes. En la siguiente imagen
se muestra este proceso:

Figura 2.5-6: Envío de una petición de servicio desde un cliente

Una vez que el servidor web seleccionado recibe la petición, devuelve una respuesta al
cliente, y en el momento que la trama pasa por el switch se cambia la dirección IP origen
del servidor web a la dirección IP virtual del servicio. Este proceso se puede ver en la
siguiente imagen:

Figura 2.5-7: Envío de una respuesta de servicio desde un servidor web

Se puede comprobar el estudio de pruebas realizado del balanceador de carga mediante el


controlador POX en el capítulo 3.3. Análisis del balanceador de carga.

29
Desarrollo

2.6. Firewall
En el escenario se ha elegido utilizar Firewall Builder 19 como sistema cortafuegos ya que
proporciona una interfaz gráfica y profesional al usuario para la configuración de políticas
de seguridad. Sin embargo, es posible utilizar cualquier otro software de seguridad como por
ejemplo, Uncomplicated Firewall 20, que es más ligero y utiliza un pequeño número de
comandos simples para su configuración.

Para el acceso a la interfaz de Firewall Builder es necesario acceder a la máquina FW desde


el host a través de la red, y ejecutar las acciones pertinentes en la máquina remota. Por ello,
ha sido necesario la instalación del paquete xauth que permitirá mostrar la interfaz gráfica
del software en el equipo host de manera remota.

Para crear un túnel ssh a la máquina FW, y así poder conectarse a ella, se ejecutará el
siguiente comando:

# slogin -X root@10.1.1.1
root@10.1.1.1’s password: xxxx
root@FW:~#

Una vez dentro de la máquina virtual FW se accederá a la interfaz de Firewall Builder:

root@FW:~# fwbuilder
Firewall Builder GUI 5.1.0.3599

La primera vez que se accede se mostrará la siguiente pantalla de bienvenida:

Figura 2.6-1: Pantalla de bienvenida de Firewall Builder

30
Desarrollo
En ella se pulsará la opción Create new firewall, situada en el botón izquierdo de la parte
central. Tras ello se abrirá una nueva ventana solicitando información sobre el firewall a
crear. Aquí se indicará que se utilizará como software iptables 21, como se indica a
continuación:

Figura 2.6-2: Creación de un firewall (paso 1)

Tras seleccionar el botón Next, se permite realizar el descubrimiento automáticamente de las


interfaces de red del firewall mediante SNMP 22 o realizar una configuración manual. En
nuestro caso se realizará una configuración manual de las mismas.

Figura 2.6-3 Creación de un firewall (paso 2)

Para ello será necesario configurar las tres interfaces que tiene el firewall de nuestro
escenario: eth1 (10.1.1.1), eth2 (10.1.2.1) y lo (127.0.0.1).

31
Desarrollo

Figura 2.6-4: Configuración de la interfaz eth1 del firewall

Figura 2.6-5: Configuración de la interfaz eth2 del firewall

Figura 2.6-6: Configuración de la interfaz de loopback del firewall

Tras finalizar el proceso de creación del firewall ya se está en condiciones de crear, según
las necesidades, las reglas de filtrado de paquetes.

En la parte izquierda de la pantalla principal se encuentran disponibles dos librerías, Standard


y User, que muestran un árbol de objetos y servicios que se podrán añadir en las reglas
mediante la técnica conocida como arrastrar y soltar (drag and drop), por lo que será muy
fácil el rellenado de las reglas con el contenido que se desee aplicar.

Es posible crear nuevos objetos en la librería User según las necesidades del usuario. En
nuestro caso se han realizado las siguientes creaciones:

32
Desarrollo

NOMBRE DEL OBJETO TIPO DETALLES

Addresses Address: 10.1.1.10

Address: 10.1.2.0
Networks
Netmask: 255.255.255.0

También se ha agregado un servicio que debe permitir el firewall en nuestro escenario, el


puerto 5001 que utiliza la herramienta iperf por defecto.

NOMBRE DEL SERVICIO TIPO DETALLES


TCP Destination Port: 5001

Una vez creados todos los objetos necesarios para la política de seguridad, en la pestaña
Policy del firewall es posible definir un conjunto de reglas a aplicar en nuestro escenario,
como pueden ser las siguientes:

Figura 2.6-7: Política de reglas aplicadas en el firewall

En este momento, antes de la instalación de las reglas, se debe salvar un fichero de


configuración, con la extensión .fwb, que permite guardar no solo los nombres y definiciones
de los objetos, servicios, etc. que utilizan las reglas de filtrado, sino también las propias reglas
de filtrado. Tras ello es posible realizar la instalación de las reglas mediante la compilación
del fichero de configuración, generando un fichero, con extensión .fw, que es realmente un
archivo tipo Shell-Script que permitirá poner en marcha las reglas especificadas en el fichero
de configuración. Este proceso hay que llevarlo a cabo usando las funciones Compile e Install
que se muestran en la parte superior de la pantalla.

En el momento de instalación aparecerá una pantalla solicitando algunos datos sobre el


firewall, que se deben rellenar como se muestra en la siguiente figura:

33
Desarrollo

Figura 2.6-8: Instalación de políticas de seguridad en el firewall

Al pulsar el botón Install, se procederá a la instalación de todas las reglas configuradas y


mediante el mensaje Firewall policy successfully installed se concluye que ha sido un éxito
la instalación.

La próxima vez que sea necesario configurar nuevas reglas en el firewall será posible cargar
el fichero de configuración mediante la opción Open, y así evitar de nuevo la creación del
firewall desde cero.

Para finalizar la sesión ssh a la máquina FW es necesario ejecutar el comando exit:

root@FW:~# exit
logout
Connection to 10.1.1.1 closed.

34
Desarrollo

2.7. Clientes
Se han configurado en el escenario dos clientes, C1 y C2, además del propio host para
comprobar el correcto acceso a la aplicación web desde diferentes equipos. El sistema
operativo que tienen los clientes también carece de interfaz gráfica, como el resto de las
máquinas virtuales. Por lo que para acceder al navegador Firefox instalado en los clientes se
procederá a crear una sesión ssh, igual que en el caso del firewall.

Para crear la sesión remota a C1, por ejemplo, se introducirá el siguiente comando:

# slogin -X root@10.1.1.11
root@10.1.1.11’s password: xxxx
root@C1:~#

Una vez dentro de la máquina virtual del cliente es posible abrir el navegador:

root@C1:~# firefox

Figura 2.7-1: Navegador Firefox desde un cliente a través de un túnel ssh

De esta forma es posible visualizar la aplicación web que se ha creado desde los diferentes
clientes. Además, desde el propio navegador se puede comprobar que se está efectuando
correctamente el balanceo de carga configurado en el Controlador. Para ello, es posible
mostrar el código fuente de la página mediante el atajo de teclado Ctrl+U.

35
Desarrollo

Figura 2.7-2: Código fuente desde Firefox de la Aplicación web

En la figura anterior se muestra que la página ha sido obtenida del servidor web WWW1, ya
que en la aplicación web se configuró en el fichero index.html un comentario, que se indica
dentro del rectángulo rojo, aportando información del servidor en el que se encuentra alojada
la aplicación.

Se recuerda que es posible tener conectividad al exterior desde el cliente al cual se está
accediendo. Para ello solo será necesario utilizar el comando dhclient y abrir de nuevo el
navegador.

root@C1:~# dhclient eth99


root@C1:~# firefox

Para finalizar la sesión ssh abierta con el cliente es necesario ejecutar el comando exit:

root@C1:~# exit
logout
Connection to 10.1.1.11 closed.

36
3. Pruebas y resultados
Tras el completo desarrollo del escenario se ha decidido realizar una serie de pruebas de
algunas partes en concreto para comprobar el funcionamiento de diversos aspectos.

Las dos primeras pruebas se han centrado en el sistema de ficheros. La primera de ellas
ofrece un análisis del funcionamiento del protocolo GlusterFS, y la segunda muestra
como un servidor caído es capaz de recuperar la información tras su reanudación.

La tercera prueba se centra en el balanceador de carga, e intenta examinar el


funcionamiento del controlador SDN cuando recibe diferentes peticiones de servicio.

La cuarta prueba es una breve comprobación de la política de seguridad que se ha aplicado


en el firewall.

3.1. Análisis de GlusterFS


En esta prueba se pretende analizar fases destacables en el funcionamiento del protocolo
GlusterFS cuando ya se tiene un volumen creado en los servidores de disco. Se utilizará
el analizador de tráfico Wireshark para mostrar capturas de la información relevante en
los diferentes procesos.

Una vez creado el volumen como se ha descrito en 2.3.1. Configuración de los


servidores de disco, es necesario el montaje desde los servidores web. El montaje es un
proceso en el cual un servidor de disco indicado envía al servidor web correspondiente
toda la información referente al volumen creado.

En este caso se utilizará un volumen en réplica y se analizará el tráfico cuando el montaje


es realizado desde el servidor web WWW1. En la siguiente captura se muestra la trama
enviada por el servidor de disco NAS1 (10.1.3.21) que recibe el servidor web WWW1
(10.1.3.11) con toda la información del volumen creado a través del protocolo GlusterFS
Handshake. Esta información enviada la poseen todos los servidores de disco en el
directorio /etc/glusterd/vols/nas.

Figura 3.1-1 - Captura del envío de la información del volumen

37
Pruebas y resultados
Una vez montado el sistema de ficheros en los servidores web se procede a la creación
de un archivo, y analizando el tráfico se puede comprobar en qué determinado momento
se envía el archivo creado en el servidor web a los diferentes servidores de disco.

En esta acción cabe destacar dos procesos que realiza el protocolo GlusterFS. El primero
de ellos consiste en el envío de información general del archivo creado desde el servidor
web a los diferentes servidores de disco. Lo realiza a través de una llamada denominada
LOOKUP como se puede apreciar en la siguiente captura:

Figura 3.1-2 - Captura de llamada LOOKUP en GlusterFS

Tras la llamada LOOKUP enviada a los diferentes servidores de disco se produce una
llamada WRITE en la que envía el contenido del archivo creado. La siguiente captura
muestra este proceso:

Figura 3.1-3: Captura de la llamada WRITE en GlusterFS

En las tramas 200 y 201 se envía el contenido del archivo desde el servidor web hacia
el servidor de disco NAS1. La trama 202 es el acuse de recibo que envía el servidor de
disco NAS2 tras la recepción de la información, junto con la trama 204 que es la
contestación a la llamada WRITE producida. Lo mismo ocurre en los demás servidores
de disco, como se puede apreciar en las otras tramas capturadas.

38
Pruebas y resultados

3.2. Recuperación de un Servidor de Disco


En esta prueba se pretende deshabilitar un servidor de disco mientras un usuario se
encuentra añadiendo archivos al servidor web. Tras unos segundos se habilitará el
servidor de disco caído y se analizará el proceso de recuperación de la información
perdida.

Para la prueba se configurará un volumen en réplica, ya que en este caso todos los
servidores de disco deberán contener la misma información.

Para simular la caída del servidor de disco se empleará una de las opciones del comando
ifconfig que permite desactivar una interfaz dada.

Figura 3.2-1 - Uso del comando ifconfig down

De esta forma solamente figurará como interfaz de red la de loopback, dejando así el
servidor de disco aislado de la red.

En este momento, si un usuario agrega cualquier archivo a los servidores web no se


encontrará disponible la información en el servidor de disco caído, como se puede
apreciar en la siguiente captura:

Figura 3.2-2 - Contenido de los servidores de disco

39
Pruebas y resultados
Para habilitar de nuevo la interfaz de red del servidor de disco caído se utilizará de nuevo
el comando ifconfig:

Figura 3.2-3 - Uso del comando ifconfig up

De esta forma el servidor de disco caído se encuentra de nuevo habilitado en la red, y al


interaccionar con alguno de los servidores web enviará la información que desconocía.
El envío de la información se realiza de igual forma que el explicado en el apartado 3.1.
Análisis del protocolo GlusterFS. La siguiente captura muestra tal envío de
recuperación de la información que se produce desde el servidor web, en este caso desde
WWW1 (10.1.3.11), hacia el servidor de disco caído NAS1 (10.1.3.21)

Figura 3.2-4 - Captura de la recuperación de la información en un servidor de disco caído

40
Pruebas y resultados

3.3. Análisis del balanceador de carga


Una vez que se tiene el controlador POX funcionando, se pueden realizar diferentes
pruebas para verificar el balanceo de tráfico de las peticiones que se hacen del servicio.
En el momento de iniciar el controlador se muestra en una línea la siguiente
información:

INFO:openflow.of_01:[fa-f5-8d-5d-a8-45 1] connected

En ella se muestra que se ha reconocido un switch del tipo Open vSwitch e indica un
identificador del mismo. Es posible obtener más información sobre el switch creado
mediante los siguientes comandos:

# ovs-vsctl list bridge LAN2


_uuid : 5d8df5fb-4a9b-45a8-b73f-a50538a410ab
controller : [5cfbd10a-2de9-444d-934b-9d38826e4d62]
datapath_id : "0000faf58d5da845"
datapath_type : ""
external_ids : {}
fail_mode : []
flood_vlans : []
flow_tables : {}
ipfix : []
mirrors : []
name : "LAN2"
netflow : []
other_config : {}
ports : [119c5e01-30e7-431b-bb25-26d8ef48158f,
5e040e2d-8c24-48e9-8340-2e129e61af75, f8ff6d46-73a0-431a-
9ab5-3738c6fbdd15, fc9a6f99-a9c0-4a29-accc-166d5fe7e1e9,
fd9266ea-2a50-4496-954e-a79aeb533a07]
protocols : []
sflow : []
status : {}
stp_enable : false

# ovs-vsctl show
1b0d0349-6984-40cb-bbb1-100a50bcbf1d
Bridge "LAN2"
Controller "tcp:10.1.4.2:6633"
is_connected: true
Port "WWW3-e1"
Interface "WWW3-e1"
Port "WWW1-e1"
Interface "WWW1-e1"
Port "LAN2"
Interface "LAN2"
type: internal
Port "WWW2-e1"
Interface "WWW2-e1"
Port "FW-e2"
Interface "FW-e2"
ovs_version: "2.0.1"ports

41
Pruebas y resultados
Mediante la herramienta iperf ejecutándola desde alguno de los clientes se puede
comprobar el balanceo entre los diferentes servidores web. A continuación se muestra
una captura de la prueba:

Figura 3.3-1: Balanceo mediante iperf desde un cliente

De la misma forma, también es posible realizar la prueba con más clientes, y comprobar
que se sigue balanceando sin ningún problema:

Figura 3.3-2: Balanceo mediante iperf desde varios clientes

En las capturas anteriores se comprueba que a medida que se inicia una nueva conexión
con la dirección 10.1.2.10 se va balanceando el tráfico entre los tres servidores web, a
pesar que se estén realizando peticiones simultáneamente entre diferentes clientes.

42
Pruebas y resultados
Otra prueba se podría realizar con la herramienta curl, y así obtener el contenido de una
página web en modo texto. Como en el index.html de la aplicación web se ha añadido
un comentario indicando la procedencia del servidor, será de utilidad para comprobar el
balanceador de carga. En la siguiente captura se muestra tal comando:

Figura 3.3-3: Uso de curl para comprobar balanceo de carga

A la vista del resultado se puede asegurar que el servidor web seleccionado para obtener
el fichero index.html ha sido WWW1. Además, si se comprueba la ventana del
controlador se mostrará una traza indicando el redireccionamiento:

Figura 3.3-4: Trazas del controlador que verifican el balanceo de carga

También es posible analizar el tráfico en la interfaz del CONTROLLER y comprobar


que se está enviando información hacia la tabla de flujos del switch para la nueva
petición del servicio realizada.

Figura 3.3-5: Captura de tráfico de paquetes OpenFlow

43
Pruebas y resultados
En la captura de tráfico se aprecia que desde el controlador se está creando un nuevo
flujo como respuesta al nuevo paquete que se ha recibido desde el cliente hacia la IP
virtual de servicio. Y comprobando la tabla de flujos se verifican los flujos creados:

Figura 3.3-6: Tabla de flujos del switch virtual en LAN2

Resumiendo la información más relevante de la captura anterior de la tabla de flujos


queda de la siguiente forma:

FLUJO 1
in_port 1 output 2
dl_src 02:fd:00:00:02:02 dl_dst 00:00:00:11:22:33
nw_src 10.1.1.11 nw_dst 10.1.2.10
tp_src 42449 tp_dst 80
mod_dl_dst 02:fd:00:00:04:01
mod_nw_dst 10.1.2.11

FLUJO 2
in_port 2 output 1
dl_src 02:fd:00:00:04:01 dl_dst 02:fd:00:00:02:02
nw_src 10.1.2.11 nw_dst 10.1.1.11
tp_src 80 tp_dst 42449
mod_dl_src 00:00:00:11:22:33
mod_nw_src 10.1.2.10

Observando las tablas cabe mencionar que igual que existe una dirección IP virtual de
servicio, también existe una dirección MAC virtual, 00:00:00:11:22:33. De esta forma,
todas las peticiones del servicio se dirigen hacia la IP virtual y en el último salto se
proporciona la dirección MAC virtual.

Así, en las peticiones que se reciben desde el cliente se modifica la dirección física de
destino (mod_dl_dst) y la dirección lógica de destino (mod_nw_dst). Y en las respuestas
que se proporcionan desde el servidor web se modifica la dirección física de origen
(mod_dl_src) y la dirección lógica de origen (mod_nw_src).

44
Pruebas y resultados
En nuestro escenario el mapa físico en la red LAN2 es el siguiente:

Figura 3.3-7: Diagrama físico de LAN2

Si se realiza la misma prueba desde el navegador de alguno de los clientes y se examina


el controlador, se comprobará que se han añadido diferentes flujos para una única
petición de servicio. Esto es así porque la aplicación web está creada con marcos y se
compone de cinco ficheros .html. El navegador se encarga de abrir diferentes puertos
para los ficheros que necesita obtener y con ello el controlador balancea todas las
peticiones. En la siguiente captura se muestra lo obtenido en las trazas del controlador:

Figura 3.3-8: Trazas del controlador al realizar una petición de servicio desde un navegador

45
Pruebas y resultados

3.4. Comprobación de las políticas de seguridad


Tras la instalación de las políticas de seguridad del firewall descritas en el apartado 2.6.
Firewall, es posible realizar aquellas acciones configuradas con denegar y rechazar para
comprobar su correcto funcionamiento.

La regla 2 no permite ningún tipo de tráfico con destino el propio firewall, a excepción
si proviene desde el host mediante el servicio ssh. Por lo que se puede comprobar que
deniega ese tipo de tráfico realizando un ping desde alguno de los clientes disponibles
del escenario. En la siguiente figura se muestra el resultado:

Figura 3.4-1: Ping desde C1 hacia FW

La regla 4 no permite ningún tráfico saliente desde las máquinas situadas en LAN2
distinto de ICMP. Para comprobar el funcionamiento de ella es posible utilizar la
herramienta iperf desde uno de los servidores web, e indicar la dirección de alguno de
los clientes como dirección del servidor. Así, ejecutando el comando se indica que la
red es inalcanzable:

root@WWW1:~# iperf –c 10.1.1.11


connect failed: Network is unreachable

Si se analiza el tráfico que se encuentra en la interfaz eth1 (10.1.2.11) del servidor web
WWW1 se aprecia que desde el firewall se indica que el acceso a la red está prohibido,
tal y como se indicó en la regla mediante la acción Reject: ICMP net prohibited.

Figura 3.4-2: Captura de tráfico para comprobar la regla 4 del firewall

46
4. Conclusiones
El trabajo se ha finalizado cumpliendo las expectativas iniciales, dejando un escenario
didáctico que representa el concepto de centro de datos y computación en la nube.

A lo largo de su desarrollo se han encontrado diferentes problemas relacionados


fundamentalmente con la virtualización y la configuración de un controlador capaz de realizar
la función de balanceador de carga satisfactoriamente en el escenario propuesto. Sin embargo,
todo ello ha ayudado en el aprendizaje de diferentes conceptos, como el de las SDN.

Durante la utilización de la herramienta VNX para la gestión del escenario virtual, se han
notificado diferentes fallos y se han propuesto nuevas extensiones, como la conexión a
Internet de las máquinas virtuales de un escenario, ayudando con ello al perfeccionamiento de
la misma.

A través de este trabajo, que se ha centrado en cuestiones prácticas partiendo del desarrollo
de ideas, he aprendido que una primera propuesta a un problema no es siempre la correcta, y
por ello es necesario buscar nuevas soluciones a todos los problemas que van surgiendo hasta
encontrar una válida.

En cuanto al apartado de Pruebas y resultados se han especificado algunas de las posibles


pruebas que se pueden realizar en un escenario como el descrito con el objetivo de comprobar
y asimilar conceptos a través de los resultados, pero se pueden efectuar muchas otras.

Las líneas futuras de desarrollo que pueden partir de este trabajo son varias, ya que un
escenario como el utilizado permite profundizar en diferentes aspectos de un centro de datos.
A continuación se nombran algunas:
 La importancia que actualmente están teniendo las redes definidas por software en los
grandes centros de datos es una línea de desarrollo para seguir investigando. De la
misma forma que se ha implementado un balanceador de carga en un controlador SDN,
es posible hacerlo con otras funciones, como puede ser un firewall. Además, en este
trabajo solo se han estudiado dos tipos de controlador, por lo que ampliar el análisis
podría añadir nuevas funcionalidades al escenario.
 La evaluación de alternativas a GlusterFS para sistemas de archivos distribuidos en un
entorno de red de área local puede optimizar de la red y el uso de los servidores de disco.
Una opción puede ser Ceph.
 La creación de una base de datos alojada en una nueva máquina virtual en el escenario
puede permitir a la aplicación un control centralizado de los usuarios al almacenamiento
de ficheros.

Finalmente, mencionar que mediante la realización de este trabajo se han aplicado diferentes
conocimientos adquiridos a lo largo de la carrera que permiten ser relacionados entre ellos y
puestos en práctica en un escenario tan completo como el utilizado.

47
Bibliografía
1
Práctica final de Centro de Datos y Provisión de Servicios - E.T.S.I. Telecomunicación
2
Open vSwitch - Wikipedia
(http://en.wikipedia.org/wiki/Open_vSwitch)
3
Portal de Virtual Networks over linuX
(http://web.dit.upm.es/vnxwiki)
4
Información sobre LinuX Containers - Ubuntu Documentation
(https://help.ubuntu.com/lts/serverguide/lxc.html)
5
Copy on write – Wikipedia
(http://en.wikipedia.org/wiki/Copy-on-write)
6
Libvirt
(http://libvirt.org/index.html)
7
Virtual Networking – WikiLibvirt
(http://wiki.libvirt.org/page/VirtualNetworking)
8
GlusterFS – Gluster Community
(http://www.gluster.org/about/)
9
Filesystem Administration Guide – Gluster Community
(http://gluster.org/community/documentation/index.php/Gluster_3.2_Filesystem_Admi
nistration_Guide)
10
Setting up Storage Volumes – Red Hat Storage (Administration Guide)
(https://access.redhat.com/site/documentation/en-
US/Red_Hat_Storage/2.0/html/Administration_Guide/index.html)
11
Resumen sobre GlusterFS - Escuela Latinoamericana de Redes
(http://www.eslared.org.ve/walc2012/material/track5/GlusterFS.pdf)
12
Sistema de archivos en el espacio de usuario (SAEU / FUSE) - Wikipedia
(http://es.wikipedia.org/wiki/Sistema_de_archivos_en_el_espacio_de_usuario)
13
Comando mknod - Ubuntu Manuals
(http://manpages.ubuntu.com/manpages/karmic/es/man1/mknod.1.html)
14
Fichero fstab - Wikipedia
(http://es.wikipedia.org/wiki/Fstab)
15
Sotware Defined Networking - Wikipedia
(http://en.wikipedia.org/wiki/Software-defined_networking)

49
16
Open Networking Foundation
(https://www.opennetworking.org/about/onf-overview)
17
Floodlight Documentation
(http://www.openflowhub.org/display/floodlightcontroller/Floodlight+Documentation)
18
Algoritmo Round Robin - Wikipedia
(http://es.wikipedia.org/wiki/Planificaci%C3%B3n_Round-robin)
19
Firewall Builder
(http://www.fwbuilder.org)
20
Uncomplicated Firewall - Ubuntu Wiki
(https://wiki.ubuntu.com/UncomplicatedFirewall?action=show&redirect=UbuntuFire
wall)
21
IPTables - Wikipedia
(http://es.wikipedia.org/wiki/Netfilter/iptables)
22
Simple Network Management Protocol - Wikipedia
(http://en.wikipedia.org/wiki/Simple_Network_Management_Protocol)

50
Apéndice A: Plantilla del escenario
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!--
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 DESARROLLO DE ESCENARIOS VIRTUALES
6 PARA PRÁCTICAS DE LABORATORIO SOBRE
7 ARQUITECTURAS DE SERVICIOS EN LA NUBE
8 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 Autor: Raúl Álvarez Pinilla
10 Tutor: David Fernández Cambronero
11
12 Departamento de Ingeniería de Sistemas Telemáticos (DIT)
13 Universidad Politécnica de Madrid
14 SPAIN
15 -->
16
17 <vnx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18 xsi:noNamespaceSchemaLocation="/usr/share/xml/vnx/vnx-2.00.xsd">
19 <global>
20 <version>2.0</version>
21 <scenario_name>TFG:Arquitecturas_de_servicios_en_la_nube
</scenario_name>
22 <automac/>
23 <vm_mgmt type="none" />
24 <vm_defaults>
25 <console id="0" display="no"/>
26 <console id="1" display="yes"/>
27 <forwarding type="ip" />
28 </vm_defaults>
29 </global>
30
31 <net name="LAN1" mode="virtual_bridge" />
32 <net name="LAN2" mode="openvswitch" controller="tcp:10.1.4.2:6633" />
33 <net name="LAN3" mode="virtual_bridge" />
34 <net name="virbr0" mode="virtual_bridge" managed="no"/>
35 <net name="MNG" mode="virtual_bridge" />
36
37 <vm name="C1" type="lxc">
<filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-CLIENT
38 </filesystem>
39 <if id="1" net="LAN1">
40 <ipv4>10.1.1.11/24</ipv4>
41 </if>
42 <if id="99" net="virbr0"/>
43 <route type="ipv4" gw="10.1.1.1">10.1.2.0/24</route>
44 </vm>
45
46 <vm name="C2" type="lxc">
<filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-CLIENT
47 </filesystem>
48 <if id="1" net="LAN1">
49 <ipv4>10.1.1.12/24</ipv4>
50 </if>
51 <if id="99" net="virbr0"/>
52 <route type="ipv4" gw="10.1.1.1">10.1.2.0/24</route>
53 </vm>

51
Apéndicé A: Plantilla dél éscénario

54
55 <vm name="FW" type="lxc">
<filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-FW
56 </filesystem>
57 <if id="1" net="LAN1">
58 <ipv4>10.1.1.1/24</ipv4>
59 </if>
60 <if id="2" net="LAN2">
61 <ipv4>10.1.2.1/24</ipv4>
62 </if>
63 <if id="99" net="virbr0"/>
64 </vm>
65
66 <vm name="CONTROLLER" type="lxc">
<filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-CONTROLLER
67 </filesystem>
68 <if id="1" net="MNG">
69 <ipv4>10.1.4.2/24</ipv4>
70 </if>
71 <if id="99" net="virbr0"/>
72 </vm>
73
74 <vm name="WWW1" type="lxc">
75 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-WWW
</filesystem>
76 <if id="1" net="LAN2">
77 <ipv4>10.1.2.11/24</ipv4>
78 </if>
79 <if id="2" net="LAN3">
80 <ipv4>10.1.3.11/24</ipv4>
81 </if>
82 <if id="99" net="virbr0"/>
83 <route type="ipv4" gw="10.1.2.1">10.1.1.0/24</route>
84 <exec seq="on_boot" type="verbatim"
ostype="system">/etc/init.d/apache2 start</exec>
85 </vm>
86
87 <vm name="WWW2" type="lxc">
88 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-WWW
</filesystem>
89 <if id="1" net="LAN2">
90 <ipv4>10.1.2.12/24</ipv4>
91 </if>
92 <if id="2" net="LAN3">
93 <ipv4>10.1.3.12/24</ipv4>
94 </if>
95 <if id="99" net="virbr0"/>
96 <route type="ipv4" gw="10.1.2.1">10.1.1.0/24</route>
97 <exec seq="on_boot" type="verbatim"
ostype="system">/etc/init.d/apache2 start</exec>
98 </vm>
99

52
Apéndicé A: Plantilla dél éscénario

100 <vm name="WWW3" type="lxc">


101 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-WWW
</filesystem>
102 <if id="1" net="LAN2">
103 <ipv4>10.1.2.13/24</ipv4>
104 </if>
105 <if id="2" net="LAN3">
106 <ipv4>10.1.3.13/24</ipv4>
107 </if>
108 <if id="99" net="virbr0"/>
109 <route type="ipv4" gw="10.1.2.1">10.1.1.0/24</route>
110 <exec seq="on_boot" type="verbatim"
ostype="system">/etc/init.d/apache2 start</exec>
111 </vm>
112
113 <vm name="NAS1" type="lxc">
114 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-NAS
</filesystem>
115 <if id="1" net="LAN3">
116 <ipv4>10.1.3.21/24</ipv4>
117 </if>
118 <if id="99" net="virbr0"/>
119 </vm>
120
121 <vm name="NAS2" type="lxc">
122 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-NAS
</filesystem>
123 <if id="1" net="LAN3">
124 <ipv4>10.1.3.22/24</ipv4>
125 </if>
126 <if id="99" net="virbr0"/>
127 </vm>
128
129 <vm name="NAS3" type="lxc">
130 <filesystem type="cow">
/usr/share/vnx/filesystems/rootfs_lxc_ubuntu-NAS
</filesystem>
131 <if id="1" net="LAN3">
132 <ipv4>10.1.3.23/24</ipv4>
133 </if>
134 <if id="99" net="virbr0"/>
135 </vm>
136
137 <host>
138 <hostif net="LAN1">
139 <ipv4>10.1.1.10/24</ipv4>
140 </hostif>
141 <hostif net="MNG">
142 <ipv4>10.1.4.1/24</ipv4>
143 </hostif>
144 <route type="ipv4" gw="10.1.1.1">10.1.0.0/16</route>
145 </host>
146
147 </vnx>

53
Apéndice B: Scripts del sistema de ficheros
Mediante los siguientes scripts se pretende aclarar el proceso de configuración del
sistema de ficheros, y de esta forma proporcionar una guía a seguir.

B.1. Script para la creación del sistema de ficheros


El siguiente script pretende automatizar el proceso de configuración en los servidores
de disco para la creación de un cierto volumen. Se permitirá al usuario elegir entre un
volumen distribuido, en réplica, o seccionado. Además, se dará la opción de eliminar
un volumen ya creado.

1 #!/bin/bash
2
3 # Definición de funciones
4 function anadirServidores(){
5 lxc-attach -n NAS2 -- bash -c "echo UUID=361fbfb4-fa61-49d1-9096-
1b8a481476b6 > /etc/glusterd/glusterd.info"
6 lxc-attach -n NAS3 -- bash -c "echo UUID=6763582b-7fc7-4767-
a7d7e289709c0ba7 > /etc/glusterd/glusterd.info"
7 lxc-attach -n NAS2 -- service glusterfs-server restart
8 lxc-attach -n NAS3 -- service glusterfs-server restart
9 sleep 2
10 lxc-attach -n NAS1 -- gluster peer probe 10.1.3.22
11 lxc-attach -n NAS1 -- gluster peer probe 10.1.3.23
12 echo
13 lxc-attach -n NAS1 -- gluster peer status
14 echo
15 }
16
17 function compruebaVolumen(){
18 com=$( lxc-attach -n NAS1 -- gluster volume info | grep "No
volumes present" )
19 if [ "$com" ]
20 then
21 echo "No hay ningún volumen creado"
22 else
23 echo "Hay algún volumen creado"
24 echo "Elimínelo e inténtelo de nuevo"
25 exit 0
26 fi
27 }
28
29 function iniciarVolumen(){
30 lxc-attach -n NAS1 -- gluster volume start nas
31 lxc-attach -n NAS1 -- gluster volume info
32 }
33
34 function eliminarVolumen(){
35 lxc-attach -n NAS1 -- bash -c "gluster volume stop nas"
36 lxc-attach -n NAS1 -- bash -c "gluster volume delete nas"
37 }
38

55
Apéndicé B: Scripts dél sistéma dé fichéros

39 #Programa principal
40 clear
41 echo "CONFIGURACIÓN DE LOS SERVIDORES DE DISCO"
42 echo "Seleccione la opción a realizar:"
43 echo "1 - Crear volumen"
44 echo "2 - Eliminar volumen"
45 echo -n "Opción seleccionada: "
46 read opcion
47 clear
48
49 case $opcion in
50 "1")
51 echo "CREACION DEL VOLUMEN"
52 compruebaVolumen
53 echo "Seleccione el tipo de volumen deseado:"
54 echo "1 - Volumen distribuido"
55 echo "2 - Volumen en réplica"
56 echo "3 - Volumen seccionado"
57 echo -n "Opción seleccionada: "
58 read tipo
59 clear
60
61 case $tipo in
62 "1")
63 echo "CREACION DE VOLUMEN DISTRIBUIDO"
64 anadirServidores
65 lxc-attach -n NAS1 -- gluster volume create nas 10.1.3.21:/nas
10.1.3.22:/nas 10.1.3.23:/nas
66 iniciarVolumen
67 ;;
68 "2")
69 echo "CREACION DE VOLUMEN EN REPLICA"
70 anadirServidores
71 lxc-attach -n NAS1 -- gluster volume create nas replica 3
10.1.3.21:/nas 10.1.3.22:/nas 10.1.3.23:/nas
72 iniciarVolumen
73 ;;
74 "3")
75 echo "CREACION DE VOLUMEN SECCIONADO"
76 anadirServidores
77 lxc-attach -n NAS1 -- gluster volume create nas stripe 3
10.1.3.21:/nas 10.1.3.22:/nas 10.1.3.23:/nas
78 iniciarVolumen
79 ;;
80 esac
81 ;;
82
83 "2")
84 echo "ELIMINACION DEL VOLUMEN"
85 eliminarVolumen
86 ;;
87 esac

56
Apéndicé B: Scripts dél sistéma dé fichéros

B.2. Script para el montaje del sistema de ficheros


Con la ejecución de este script se pretende automatizar el proceso de montaje del
sistema de ficheros que hay que realizar desde los servidores web. Se permitirá al
usuario la opción de montar el sistema de ficheros como de desmontarlo.

1 #!/bin/bash
2
3 # Definición de funciones
4 function creaFstab(){
5 echo -e "# UNCONFIGURED FSTAB FOR BASE SYSTEM
6
7 /etc/glusterfs/datastore.vol /mnt/nas glusterfs
rw,allow_other,default_permissions,max_read=131072 0 0" > /tmp/fstab
8 }
9
10 function creaDatastore(){
11 echo "volume remote1
12 type protocol/client
13 option transport-type tcp
14 option remote-host 10.1.3.21
15 option remote-subvolume /nas
16 end-volume
17
18 volume remote2
19 type protocol/client
20 option transport-type tcp
21 option remote-host 10.1.3.22
22 option remote-subvolume /nas
23 end-volume
24
25 volume remote3
26 type protocol/client
27 option transport-type tcp
28 option remote-host 10.1.3.23
29 option remote-subvolume /nas
30 end-volume
31
32 volume replicate
33 type cluster/replicate
34 subvolumes remote1 remote2 remote3
35 end-volume
36
37 volume writebehind
38 type performance/write-behind
39 option window-size 1MB
40 subvolumes replicate
41 end-volume
42
43 volume cache
44 type performance/io-cache
45 option cache-size 512MB
46 subvolumes writebehind
47 end-volume" > /tmp/datastore.vol
48 }
49

57
Apéndicé B: Scripts dél sistéma dé fichéros

50 function copiaFstab(){
51 cp /tmp/fstab /var/lib/lxc/WWW1/rootfs/etc
52 cp /tmp/fstab /var/lib/lxc/WWW2/rootfs/etc
53 cp /tmp/fstab /var/lib/lxc/WWW3/rootfs/etc
54 }
55
56 function copiaDatastore(){
57 cp /tmp/datastore.vol /var/lib/lxc/WWW1/rootfs/etc/glusterfs
58 cp /tmp/datastore.vol /var/lib/lxc/WWW2/rootfs/etc/glusterfs
59 cp /tmp/datastore.vol /var/lib/lxc/WWW3/rootfs/etc/glusterfs
60 }
61
62 function compruebaNAS(){
63 com=$( lxc-attach -n NAS1 -- gluster volume info | grep "No
volumes present" )
64 if [ "$com" ]
65 then
66 echo "No hay ningún volumen creado"
67 echo "Cree un nuevo volumen e inténtelo de nuevo"
68 exit 0
69 fi
70 }
71
72 function compruebaMontaje(){
73 com=$( lxc-attach -n WWW1 -- df -h | grep "datastore.vol" )
74 if [ "$com" ]
75 then
76 echo "Ya se encuentra el sistema de ficheros montado"
77 exit 0
78 fi
79 }
80
81 function creaDirectorios(){
82 carpeta1=/var/lib/lxc/WWW1/rootfs/mnt/nas
83 carpeta2=/var/lib/lxc/WWW2/rootfs/mnt/nas
84 carpeta3=/var/lib/lxc/WWW3/rootfs/mnt/nas
85 if [ ! -d $carpeta1 ]
86 then
87 mkdir $carpeta1
88 fi
89 if [ ! -d $carpeta2 ]
90 then
91 mkdir $carpeta2
92 fi
93 if [ ! -d $carpeta3 ]
94 then
95 mkdir $carpeta3
96 fi
97 }
98
99 function compruebaFUSE(){
100 com1=$( lxc-attach -n WWW1 -- ls /dev | grep "fuse" )
101 if [ "$com1" ]
102 then
103 echo "Módulo FUSE ya instalado en WWW1"
104 else
105 echo "Instalando módulo FUSE en WWW1..."
106 lxc-attach -n WWW1 -- mknod -m 666 /dev/fuse c 10 229
107 fi
108

58
Apéndicé B: Scripts dél sistéma dé fichéros

109 com2=$( lxc-attach -n WWW2 -- ls /dev | grep "fuse" )


110 if [ "$com2" ]
111 then
112 echo "Módulo FUSE ya instalado en WWW2"
113 else
114 echo "Instalando módulo FUSE en WWW2..."
115 lxc-attach -n WWW2 -- mknod -m 666 /dev/fuse c 10 229
116 fi
117
118 com3=$( lxc-attach -n WWW3 -- ls /dev | grep "fuse" )
119 if [ "$com3" ]
120 then
121 echo "Módulo FUSE ya instalado en WWW3"
122 else
123 echo "Instalando módulo FUSE en WWW3..."
124 lxc-attach -n WWW3 -- mknod -m 666 /dev/fuse c 10 229
125 fi
126 }
127
128 function asignaPermisos(){
129 lxc-attach -n WWW1 -- chmod 777 /mnt/nas
130 lxc-attach -n WWW2 -- chmod 777 /mnt/nas
131 lxc-attach -n WWW3 -- chmod 777 /mnt/nas
132 lxc-attach -n WWW1 -- chmod 777 /tmp
133 lxc-attach -n WWW2 -- chmod 777 /tmp
134 lxc-attach -n WWW3 -- chmod 777 /tmp
135
136 }
137
138 #Programa principal
139 clear
140 echo "MONTAR/DESMONTAR EL SISTEMA DE FICHEROS"
141 echo "Seleccione la opción a realizar:"
142 echo "1 - Montar sistema de ficheros"
143 echo "2 - Desmontar sistema de ficheros"
144 echo -n "Opción seleccionada: "
145 read opcion
146 clear
147
148 case $opcion in
149 "1")
150 echo "MONTAJE DEL SISTEMA DE FICHEROS"
151 compruebaNAS
152 compruebaMontaje
153 creaFstab
154 creaDatastore
155 copiaFstab
156 copiaDatastore
157 creaDirectorios
158 compruebaFUSE
159 lxc-attach -n WWW1 -- mount -a
160 lxc-attach -n WWW2 -- mount -a
161 lxc-attach -n WWW3 -- mount -a
162 echo "Sistema de ficheros montado correctamente"
163 ;;
164

59
Apéndicé B: Scripts dél sistéma dé fichéros

165 "2")
166 echo "DESMONTAJE DEL SISTEMA DE FICHEROS"
167 lxc-attach -n WWW1 -- umount -l /mnt/nas
168 lxc-attach -n WWW2 -- umount -l /mnt/nas
169 lxc-attach -n WWW3 -- umount -l /mnt/nas
170 echo "Sistema de ficheros desmontado correctamente"
171 ;;
172 esac

60
Apéndice C: Código de la Aplicación Web
A continuación se muestran los diferentes archivos que han sido creados para la
Aplicación Web del centro de datos.

 index.html

1 <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 ~~~ Servidor Web X (10.1.2.1X) ~~~
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
4
5 <html>
6 <head>
7 <title>Almacenamiento de ficheros</title>
8 </head>
9 <frameset rows="86,*,45z" frameborder="0" border="0"
framespacing="0">
10 <frame name="topNav" src="webTop_nav.html">
11 <frameset cols="200,*" frameborder="0" border="0"
framespacing="0">
12 <frame name="menu" src="webMenu.html" marginheight="0"
marginwidth="0" scrolling="auto" noresize>
13 <frame name="content" src="webContent.html"
marginheight="0" marginwidth="0" scrolling="auto" noresize>
14 </frameset>
15 <frame name="footer" src="webFooter.html">
16 </frameset>
17 </html>

 webTop_nav.html

1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>Top Nav</title>
5 <style type="text/css">
6 body {
7 font-family:verdana,arial,sans-serif;
8 font-size:14.2pt;
9 margin:30px;
10 background-color:#a08029;}
11 </style>
12 </head>
13
14 <body>
15 <h3>Desarrollo de Escenarios Virtuales para Prácticas de
Laboratorio sobre Arquitecturas de Servicios en la Nube</h3>
16 </body>
17 </html>

61
Apéndicé C: Codigo dé la Aplicacion Wéb
 webMenu..html

1 <html>
2 <head>
3 <title>Menu</title>
4 <style type="text/css">
5 body {
6 font-family:verdana,arial,sans-serif;
7 font-size:10pt;
8 margin:15px;
9 background-color:#ff9900;}
10 </style>
11 </head>
12
13 <body>
14 <p><a href="webContent.html" target="content">INICIO</a></p>
15 <p><a href="pagSubida.php" target="content">Subida de
ficheros</a></p>
16 <p><a href="pagDescarga.php" target="content">Descarga de
ficheros</a></p>
17 <p><a href="pagBorrado.php" target="content">Borrado de
ficheros</a></p>
18 </body>
19 </html>

 webContent.html

1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>Content</title>
5 <style type="text/css">
6 body {
7 font-family:verdana,arial,sans-serif;
8 font-size:10pt;
9 margin:30px;
10 background-color:#ffcc00;}
11 </style>
12 </head>
13
14 <body>
15 <h1>Bienvenido</h1>
<h2>Desde esta página web podrá realizar el almacenamiento de
16 ficheros</h2>
17 <ul>
18 <li><a href="pagSubida.php" target="content">Subida de
ficheros</a></li><p/>
19 <li><a href="pagDescarga.php" target="content">Descarga de
ficheros</a></li><p/>
20 <li><a href="pagBorrado.php" target="content">Borrado de
ficheros</a></li>
21 </ul>
22 </body>
23 </html>

62
Apéndicé C: Codigo dé la Aplicacion Wéb
 webFooter.html

1 <html>
2 <head>
3 <meta charset="utf-8">
4 <title>Footer</title>
5 <style type="text/css">
6 body {
7 font-family:verdana,arial,sans-serif;
8 font-size:10pt;
9 margin:10px;
10 text-align: right;
11 background-color:black;
12 color:white;}
13 </style>
14 </head>
15
16 <body>
17 <table width="100%">
18 <tr>
19 <td align="left"><strong>Raúl Álvarez
Pinilla</strong></td>
20 <td align="right"><strong>Escuela Técnica Superior
de Ingenieros de Telecomunicación (UPM)</strong></td>
21 </tr>
22 </table>
23 </body>
24 </html>

63
Apéndicé C: Codigo dé la Aplicacion Wéb
 pagSubida.php

1 <html>
2 <head>
3 <title>Subida</title>
4 <style type="text/css">
5 body {
6 font-family:verdana,arial,sans-serif;
7 font-size:10pt;
8 margin:30px;
9 background-color:#a1f861;}
10 </style>
11 <script type="text/javascript" src="funciones.js"></script>
12 </head>
13
14 <body>
15 <h1>Subida de ficheros</h1>
16 <ol>
17 <li value="1">
18 <span><input id="archivos" type="file"
name="archivos[]" multiple="multiple"/></span><p/>
19 </li>
20 <li>
21 <button onclick="subido();"/>Subir</button>
22 </li>
23 </ol>
24 </body>
25 </html>

 scriptSubir.php

1 <?php
2 $ruta="/mnt/nas/";
3 foreach($_FILES as $key)
4 {
5 if($key["error"]==UPLOAD_ERR_OK){
6 move_uploaded_file($key["tmp_name"],$ruta.$key["name"]);
7 echo "Subida realizada correctamente\n";
8 }else{
9 echo $key["Error en la subida"];
10 }
11 }
12 ?>

64
Apéndicé C: Codigo dé la Aplicacion Wéb
 pagDescarga.php

1 <html>
2 <head>
3 <title>Descarga</title>
4 <style type="text/css">
5 body {
6 font-family:verdana,arial,sans-serif;
7 font-size:10pt;
8 margin:30px;
9 background-color:#58FAD0;}
10 </style>
11 <script type="text/javascript" src="funciones.js"></script>
12 </head>
13
14 <body>
15 <h1>Descarga de ficheros</h1>
16 <?php
17 $ruta="/mnt/nas/";
18 $archivos=scandir($ruta);
19 $lista="";
20 foreach($archivos as $value){
21 if($value!="."&&$value!=".."){
22 $lista.=
23 '<form
action="javascript:getFile(\''.$value.'\');">
24 <input type="submit" value="Descargar
archivo =>"><a>'.$value.'</a>
25 </form><p/>';
26 }
27 }
28 echo $lista;
29 ?>
30 </body>
31 </html>

 scriptBajar.php

1 <?php
2 $ruta="/mnt/nas/";
3 $name=$_GET["file"];
4 $archivo=$ruta.$name;
5 if(file_exists($archivo)){
6 header("Content-Description: File transfer");
7 header("Content-Type: application/octect-stream");
8 header("Content-Disposition: attachment;
filename=".basename($archivo));
9 header("Content-Transfer-Encoding: binary");
10 header("Expires: 0");
11 header("Cache-Control: must-revalidate");
12 header("Pragma: public");
13 ob_clean();
14 flush();
15 readfile($archivo);
16 exit;
17 }
18 ?>

65
Apéndicé C: Codigo dé la Aplicacion Wéb
 pagBorrado.php

1 <html>
2 <head>
3 <title>Borrado</title>
4 <style type="text/css">
5 body {
6 font-family:verdana,arial,sans-serif;
7 font-size:10pt;
8 margin:30px;
9 background-color:#F5A9A9;}
10 </style>
11 <script type="text/javascript" src="funciones.js"></script>
12 </head>
13
14 <body>
15 <h1>Borrado de ficheros</h1>
16 <?php
17 $ruta="/mnt/nas/";
18 $archivos=scandir($ruta);
19 $lista="";
20 foreach($archivos as $value){
21 if($value!="."&&$value!=".."){
22 $lista.=
23 '<form
action="javascript:deleteFile(\''.$value.'\');">
24 <input type="submit" value="Borrar archivo
=>"><a>'.$value.'</a>
25 </form><p/>';
26 }
27 }
28 echo $lista;
29 ?>
30 </body>
31 </html>

 scriptBorrar.php

1 <?php
2 $ruta="/mnt/nas/";
3 unlink($ruta.$_POST["file"]);
4 echo $_POST["file"]." ha sido borrado";
5 ?>

66
Apéndicé C: Codigo dé la Aplicacion Wéb
 funciones.js

1 //SUBIDA DE FICHEROS
2 function subido(){
3 var archivo =document.getElementById("archivos").files;
4 if(archivo.length==0){
5 alert("No se ha subido ningún fichero");
6 return;
7 }
8 createFile(archivo);
9 }
10 function createFile(archivo){
11 var xhr=new XMLHttpRequest();
12 var data=new FormData();
13 for (var i=0; i<archivo.length; i++){
14 data.append("archivo"+i,archivo[i]);
15 }
16 xhr.open("POST", "scriptSubir.php", true);
17 xhr.onreadystatechange= function(){
18 if(xhr.readyState!=4){
19 return;
20 }
21 if(xhr.status==200){
22 alert(xhr.responseText);
23 location.href="pagDescarga.php";
24 }
25 };
26 xhr.send(data);
27 }
28
29 //DESCARGA DE FICHEROS
30 function getFile(file){
31 location.href="scriptBajar.php?file="+file;
32 }
33
34 //BORRADO DE FICHEROS
35 function deleteFile(file){
36 var xhr=new XMLHttpRequest();
37 var data=new FormData();
38 data.append("file",file);
39 xhr.open("POST", "scriptBorrar.php", true);
40 xhr.onreadystatechange= function(){
41 if(xhr.readyState!=4){
42 return;
43 }
44 if(xhr.status==200){
45 alert(xhr.responseText);
46 location.href="pagBorrado.php";
47 }
48 }
49 xhr.send(data);
50 }

67
68
Apéndice D: Balanceador de carga
(Controlador POX)
El fichero pox/misc/ip_loadbalancer.py es el encargado de la función de balanceador de
carga del escenario. Viene por defecto tras la instalación del controlador pero es
necesario realizar diversos cambios para el correcto funcionamiento en el escenario.

A continuación se muestra su contenido:

1 # Copyright 2013 James McCauley


2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """
16 A very sloppy IP load balancer.
17
18 Run it with --ip=<Service IP> --servers=IP1,IP2,...
19
20 Please submit improvements. :)
21 """
22
23 from pox.core import core
24 import pox
25 log = core.getLogger("iplb")
26
27 from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST
28 from pox.lib.packet.ipv4 import ipv4
29 from pox.lib.packet.arp import arp
30 from pox.lib.addresses import IPAddr, EthAddr
31 from pox.lib.util import str_to_bool, dpid_to_str
32
33 import pox.openflow.libopenflow_01 as of
34
35 import time
36 import random
37
38 FLOW_IDLE_TIMEOUT = 5
39 FLOW_MEMORY_TIMEOUT = 60 * 5
40 selected_server=0
41
42
43 class MemoryEntry (object):
44 """
45 Record for flows we are balancing
46

69
Apéndicé D: Balancéador dé carga (Controlador POX)

47 Table entries in the switch "remember" flows for a period of time, but
48 rather than set their expirations to some long value (potentially leading
49 to lots of rules for dead connections), we let them expire from the
50 switch relatively quickly and remember them here in the controller for
51 longer.
52
53 Another tactic would be to increase the timeouts on the switch and use
54 the Nicira extension which can match packets with FIN set to remove them
55 when the connection closes.
56 """
57 def __init__ (self, server, first_packet, client_port):
58 self.server = server
59 self.first_packet = first_packet
60 self.client_port = client_port
61 self.refresh()
62
63 def refresh (self):
64 self.timeout = time.time() + FLOW_MEMORY_TIMEOUT
65
66 @property
67 def is_expired (self):
68 return time.time() > self.timeout
69
70 @property
71 def key1 (self):
72 ethp = self.first_packet
73 ipp = ethp.find('ipv4')
74 tcpp = ethp.find('tcp')
75
76 return ipp.srcip,ipp.dstip,tcpp.srcport,tcpp.dstport
77
78 @property
79 def key2 (self):
80 ethp = self.first_packet
81 ipp = ethp.find('ipv4')
82 tcpp = ethp.find('tcp')
83
84 return self.server,ipp.srcip,tcpp.dstport,tcpp.srcport
85
86
87 class iplb (object):
88 """
89 A simple IP load balancer
90
91 Give it a service_ip and a list of server IP addresses. New TCP flows
92 to service_ip will be randomly redirected to one of the servers.
93
94 We probe the servers to see if they're alive by sending them ARPs.
95 """
96 def __init__ (self, connection, service_ip, servers = []):
97 self.service_ip = IPAddr(service_ip)
98 self.servers = [IPAddr(a) for a in servers]
99 self.con = connection
100 #self.mac = self.con.eth_addr
101 self.mac = EthAddr("00:00:00:11:22:33")
102 self.live_servers = {} # IP -> MAC,port
103

70
Apéndicé D: Balancéador dé carga (Controlador POX)

104 try:
105 self.log = log.getChild(dpid_to_str(self.con.dpid))
106 except:
107 # Be nice to Python 2.6 (ugh)
108 self.log = log
109
110 self.outstanding_probes = {} # IP -> expire_time
111
112 # How quickly do we probe?
113 self.probe_cycle_time = 5
114
115 # How long do we wait for an ARP reply before we consider a server dead?
116 self.arp_timeout = 3
117
118 # We remember where we directed flows so that if they start up again,
119 # we can send them to the same server if it's still up. Alternate
120 # approach: hashing.
121 self.memory = {} # (srcip,dstip,srcport,dstport) -> MemoryEntry
122
123 self._do_probe() # Kick off the probing
124
125 # As part of a gross hack, we now do this from elsewhere
126 #self.con.addListeners(self)
127
128 def _do_expire (self):
129 """
130 Expire probes and "memorized" flows
131
132 Each of these should only have a limited lifetime.
133 """
134 t = time.time()
135
136 # Expire probes
137 for ip,expire_at in self.outstanding_probes.items():
138 if t > expire_at:
139 self.outstanding_probes.pop(ip, None)
140 if ip in self.live_servers:
141 self.log.warn("Server %s down", ip)
142 del self.live_servers[ip]
143
144 # Expire old flows
145 c = len(self.memory)
146 self.memory = {k:v for k,v in self.memory.items()
147 if not v.is_expired}
148 if len(self.memory) != c:
149 self.log.debug("Expired %i flows", c-len(self.memory))
150
151 def _do_probe (self):
152 """
153 Send an ARP to a server to see if it's still up
154 """
155 self._do_expire()
156
157 server = self.servers.pop(0)
158 self.servers.append(server)
159

71
Apéndicé D: Balancéador dé carga (Controlador POX)

160 r = arp()
161 r.hwtype = r.HW_TYPE_ETHERNET
162 r.prototype = r.PROTO_TYPE_IP
163 r.opcode = r.REQUEST
164 r.hwdst = ETHER_BROADCAST
165 r.protodst = server
166 r.hwsrc = self.mac
167 r.protosrc = self.service_ip
168 e = ethernet(type=ethernet.ARP_TYPE, src=self.mac,
169 dst=ETHER_BROADCAST)
170 e.set_payload(r)
171 self.log.debug("ARPing for %s", server)
172 msg = of.ofp_packet_out()
173 msg.data = e.pack()
174 msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
175 msg.in_port = of.OFPP_NONE
176 self.con.send(msg)
177
178 self.outstanding_probes[server] = time.time() + self.arp_timeout
179
180 core.callDelayed(self._probe_wait_time, self._do_probe)
181
182 @property
183 def _probe_wait_time (self):
184 """
185 Time to wait between probes
186 """
187 r = self.probe_cycle_time / float(len(self.servers))
188 r = max(.25, r) # Cap it at four per second
189 return r
190
191 def _pick_server (self, key, inport):
192 """
193 Pick a server for a (hopefully) new connection, round robin based
194 """
195 global selected_server
196 a=self.live_servers.keys()
197 if selected_server<=-(len(self.live_servers)):
198 selected_server=0
199 #print selected_server, len(self.live_servers)
200 b=a[selected_server]
201 selected_server-=1
202 return b
203 #return random.choice(self.live_servers.keys())
204
205 def _handle_PacketIn (self, event):
206 inport = event.port
207 packet = event.parsed
208
209 def drop ():
210 if event.ofp.buffer_id is not None:
211 # Kill the buffer
212 msg = of.ofp_packet_out(data = event.ofp)
213 self.con.send(msg)
214 return None
215
216 tcpp = packet.find('tcp')

72
Apéndicé D: Balancéador dé carga (Controlador POX)

217 if not tcpp:


218 arpp = packet.find('arp')
219 if arpp:
220 # Handle replies to our server-liveness probes
221 if arpp.opcode == arpp.REPLY:
222 if arpp.protosrc in self.outstanding_probes:
223 # A server is (still?) up; cool.
224 del self.outstanding_probes[arpp.protosrc]
225 if (self.live_servers.get(arpp.protosrc, (None,None))
226 == (arpp.hwsrc,inport)):
227 # Ah, nothing new here.
228 pass
229 else:
230 # Ooh, new server.
231 self.live_servers[arpp.protosrc] = arpp.hwsrc,inport
232 self.log.info("Server %s up", arpp.protosrc)
233 return
234
235 # Not TCP and not ARP. Don't know what to do with this. Drop it.
236 return drop()
237
238 # It's TCP.
239
240 ipp = packet.find('ipv4')
241
242 if ipp.srcip in self.servers:
243 # It's FROM one of our balanced servers.
244 # Rewrite it BACK to the client
245
246 key = ipp.srcip,ipp.dstip,tcpp.srcport,tcpp.dstport
247 entry = self.memory.get(key)
248
249 if entry is None:
250 # We either didn't install it, or we forgot about it.
251 self.log.debug("No client for %s", key)
252 return drop()
253
254 # Refresh time timeout and reinstall.
255 entry.refresh()
256
257 #self.log.debug("Install reverse flow for %s", key)
258
259 # Install reverse table entry
260 mac,port = self.live_servers[entry.server]
261
262 actions = []
263 actions.append(of.ofp_action_dl_addr.set_src(self.mac))
264 actions.append(of.ofp_action_nw_addr.set_src(self.service_ip))
265 actions.append(of.ofp_action_output(port = entry.client_port))
266 match = of.ofp_match.from_packet(packet, inport)
267
268 msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
269 idle_timeout=FLOW_IDLE_TIMEOUT,
270 hard_timeout=of.OFP_FLOW_PERMANENT,
271 data=event.ofp,
272 actions=actions,
273 match=match)
274 self.con.send(msg)
275

73
Apéndicé D: Balancéador dé carga (Controlador POX)

276 elif ipp.dstip == self.service_ip:


277 # Ah, it's for our service IP and needs to be load balanced
278
279 # Do we already know this flow?
280 key = ipp.srcip,ipp.dstip,tcpp.srcport,tcpp.dstport
281 entry = self.memory.get(key)
282 if entry is None or entry.server not in self.live_servers:
283 # Don't know it (hopefully it's new!)
284 if len(self.live_servers) == 0:
285 self.log.warn("No servers!")
286 return drop()
287
288 # Pick a server for this flow
289 server = self._pick_server(key, inport)
290 self.log.info("Directing from %s (%s) to %s (%s)",
291 ipp.srcip,tcpp.srcport,server,tcpp.dstport)
292 entry = MemoryEntry(server, packet, inport)
293 self.memory[entry.key1] = entry
294 self.memory[entry.key2] = entry
295
296 # Update timestamp
297 entry.refresh()
298
299 # Set up table entry towards selected server
300 mac,port = self.live_servers[entry.server]
301
302 actions = []
303 actions.append(of.ofp_action_dl_addr.set_dst(mac))
304 actions.append(of.ofp_action_nw_addr.set_dst(entry.server))
305 actions.append(of.ofp_action_output(port = port))
306 match = of.ofp_match.from_packet(packet, inport)
307
308 msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
309 idle_timeout=FLOW_IDLE_TIMEOUT,
310
311 hard_timeout=of.OFP_FLOW_PERMANENT,
312 data=event.ofp,
313 actions=actions,
314 match=match)
315 self.con.send(msg)
316
317
318 # Remember which DPID we're operating on (first one to connect)
319 _dpid = None
320
321 def launch (ip, servers):
322 servers = servers.replace(","," ").split()
323 servers = [IPAddr(x) for x in servers]
324 ip = IPAddr(ip)
325
326 # Boot up ARP Responder
327 from proto.arp_responder import launch as arp_launch
328 arp_launch(eat_packets=False,**{str(ip):True})
329 import logging
330 logging.getLogger("proto.arp_responder").setLevel(logging.WARN)
331
332 def _handle_ConnectionUp (event):
333 global _dpid

74
Apéndicé D: Balancéador dé carga (Controlador POX)

334 if _dpid is None:


335 log.info("IP Load Balancer Ready.")
336 core.registerNew(iplb, event.connection, IPAddr(ip), servers)
337 _dpid = event.dpid
338
339 if _dpid != event.dpid:
340 log.warn("Ignoring switch %s", event.connection)
341 else:
342 log.info("Load Balancing on %s", event.connection)
343
344 # Gross hack
345 core.iplb.con = event.connection
346 event.connection.addListeners(core.iplb)
347
348
349 core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)

75

También podría gustarte