Tabla de contenido

 

 

INTROCUCCIÓN

 

1. Introducción. 2

 

1.1. Descripción del proyecto. 2

1.2. Justificación del proyecto. 2

1.3. Motivación personal 2

1.4. Organización del documento. 2

1.5. La doble utilidad del documento. 2

1.6. Convenciones y tipografía. 2

 

2. Análisis preliminar 2

 

2.1. Situación actual 2

2.2. Objetivos del proyecto. 2

2.3. Requerimientos del proyecto. 2

 

 

PRIMERA PARTE: SISTEMAS DE CLUSTERING

 

3. Clusters. 2

 

3.1. ¿Qué es un cluster?. 2

3.2. Un poco de historia. 2

3.3. Tipos de cluster 2

 

4. Cluster Filesystems. 2

 

4.1. Glosario. 2

4.2. Sistemas de ficheros distribuidos. 2

4.2.1. Network File System (NFS) 2

4.2.2. Samba. 2

4.3. Sistemas de ficheros paralelos. 2

4.3.2. Lustre. 2

4.3.3. GlusterFS. 2

 

5. Software de Clustering. 2

 

5.1. openMosix. 2

5.2. Condor 2

5.3. PBS. 2

5.4. Sun Grid Engine. 2

 

6. Alta disponibilidad. 2

 

6.1. Funcionamiento de un sistema HA.. 2

6.2. Soluciones de HA en entornos Linux. 2

 

 

SEGUNDA PARTE: DISEÑO E IMPLEMENTACIÓN

 

7. Estudio, análisis y diseño de una solución. 2

 

7.1. Análisis del sistema inicial 2

7.2. Revisión de objetivos y requisitos. 2

7.2.1. Requisitos funcionales. 2

7.2.2. Requisitos no funcionales. 2

7.3. El nuevo cluster 2

7.3.1. El sistema base. 2

7.3.2. Sistema de pruebas. 2

7.3.4. Sistema de ficheros. 2

7.3.5. Alta disponibilidad. 2

7.3.6. Sistema de imágenes. 2

7.3.7. Sistema de Monitorización. 2

7.3.8. Servicios auxiliares. 2

 

8. Implementación. 2

 

9. Lustre. 2

 

9.1. Arquitectura propuesta (versión 1.0) 2

9.2. Instalación (versión 1.0) 2

9.2.1.  DRBD.. 2

9.2.2. Lustre. 2

9.3. Configuración (versión 1.0) 2

9.3.1. Consideraciones previas. 2

9.3.2. DRBD.. 2

9.3.3. Lustre. 2

9.4. Pruebas (versión 1.0) 2

9.4.1. Test de estabilidad. 2

9.5. Revisión de la arquitectura (versión 1.1) 2

9.6. Pruebas del nuevo modelo (versión 1.1) 2

9.6.1. Test de estabilidad. 2

9.6.2. Pruebas de rendimiento. 2

9.6.2.1. Throughput máximo. 2

9.6.2.2. Test ad-hoc. 2

9.6.3. Pruebas de usabilidad. 2

 

10. GlusterFS. 2

 

10.1. Arquitectura propuesta (versión 2.0) 2

10.2. Instalación (versión 2.0) 2

10.3. Configuración (versión 2.0) 2

10.3.1 Servidores. 2

10.3.2. Namespace. 2

10.3.3. Clientes. 2

10.4. Pruebas. 2

10.4.1. Test de estabilidad. 2

10.4.2. Pruebas de rendimiento. 2

10.4.2.1. Throughput máximo. 2

10.4.2.2. Test ad-hoc. 2

10.4.3. Pruebas de usabilidad. 2

 

11. Sun Grid Engine. 2

 

11.1. Instalación. 2

11.1.1. Instalación del Master host 2

11.1.2. Instalación de un Execution host 2

11.2. Configuración. 2

11.2.1. Zona Spool de mater hosts. 2

11.2.2. Zona common. 2

11.2.3. Colas. 2

11.2.3. Usuarios. 2

11.2.4. Políticas. 2

 

12. Heartbeat 2

 

12.1. Instalación. 2

12.2. Configuración. 2

12.2.1. Cluster con GlusterFS (versión 2.0) 2

12.3. Split-Brain. 2

 

13. Tivoli 2

 

13.1. Instalación. 2

13.2. Configuración. 2

13.3. Creación de una imagen. 2

13.4. Personalización de imágenes. 2

 

14. Ganglia. 2

 

14.1. Instalación. 2

14.2. Configuración. 2

14.3. Personalización. 2

14.3.1. Trabajos en ejecución: 2

14.3.2. Trabajos encolados. 2

14.3.3. Sensor de temperatura. 2

14.3.4. Personalización web. 2

 

15. Nagios. 2

 

15.1. Instalación. 2

15.2. Configuración. 2

15.2.1. Configuración en cliente. 2

15.2.2. Configuración en servidor 2

 

16. Servicios auxiliares. 2

 

16.1. DHCP. 2

16.1.1. Instalación. 2

16.1.2. Configuración del servidor 2

16.1.3. Configuración de los clientes. 2

16.2. Exim.. 2

16.2.1. Instalación. 2

16.2.2. Configuración. 2

16.3. NTP. 2

16.3.1. Instalación. 2

16.3.2. Configuración. 2

16.4. Dsh. 2

16.4.1. Instalación. 2

16.4.2. Configuración. 2

16.5. Backup. 2

16.5.1. Instalación. 2

16.5.2. Configuración. 2

16.6. Estadísticas web. 2

16.6.1. Instalación. 2

16.6.2. Configuración. 2

16.7. Wake on LAN.. 2

16.8. NAT. 2

 

17. Tareas administrativas. 2

 

17.1. Alta de nodo. 2

17.2. Alta de usuario. 2

 

 

TERCERA PARTE: CONCLUSIONES

 

18. Conclusiones. 2

 

18.1. Objetivos y requisitos cumplidos. 2

18.1.1. El nuevo cluster 2

18.1.2. La documentación. 2

18.2. Planificación y estudios de costes. 2

18.2.1. Planificación temporal 2

18.2.2. Coste económico. 2

18.3. Mejoras y ampliaciones del sistema. 2

18.3.1. Infraestructura de red. 2

18.3.2. IP bonding. 2

18.3.3. Sistema de almacenamiento. 2

18.3.4. Tunning de Sun Grid. 2

18.3.5. Checkpointing (transparente) de procesos. 2

18.3.6. Nuevos nodos. 2

 

 

 

APÉNDICES

 

19. Apéndices. 2

 

19.1. Ficheros de configuración y scripts. 2

19.1.1. Fichero menu.lst 2

19.1.2. Fichero drbd.conf 2

19.1.3. Fichero glusterfs-server.vol 2

19.1.4. Fichero glusterfs-client.vol 2

19.1.5. Fichero ha.cf de master-cluster1. 2

19.1.6. Fichero ha.cf de master-cluster2. 2

19.1.7. Fichero haresources. 2

19.1.8. Script sungrid de heartbeat 2

19.1.9. Fichero drbd.conf de zona spool 2

19.1.10. Fichero glusterfs-server_sge-common.vol 2

19.1.11. Fichero glusterfs-client-sge.vol 2

19.1.12. Fichero bootnode-gluster.shtml 2

19.1.13. Script post_boot.sh. 2

19.1.14. Fichero gmond.conf 2

19.1.15. Fichero gmetad.conf 2

19.1.16. Script jobs_run.sh. 2

19.1.17. Script jobs_run-slave.sh. 2

19.1.18. Script jobs_queued.sh. 2

19.1.19. Script temp_max.sh. 2

19.1.20. Fichero cluster_extra.tpl 2

19.1.21. Fichero meta_view.tpl 2

19.1.22. Fichero graph.php. 2

19.1.23. Script check_sge.sh. 2

19.1.24. Fichero dhcp.conf 2

19.1.25. Fichero update.exim4.conf en master-cluster1. 2

19.1.26. Fichero update.exim4.conf en nodos de computación y servidores de disco. 2

19.1.27. Fichero ntp.conf en nodos master-cluster 2

19.1.28. Fichero ntp.conf en nodos de computación y servidores de disco. 2

19.1.29. Fichero /etc/exports. 2

19.1.30. Fichero awstats.conf 2

19.1.31. Fichero .htaccess. 2

19.1.32. Script wakeup-cluster.sh. 2

19.1.33. Script halt-cluster.sh. 2

19.1.34. Script alta_nodo.sh. 2

19.1.35. Script alta_usuario.sh. 2

19.1.36. Script build_users.sh. 2

19.1.37. Script build_homes.sh. 2

19.1.38. Script master_lectura.sh. 2

19.1.39. Script slave.sh. 2

19.1.40. Script test-disco_lectura.sh. 2

19.1.41. Script master_escritura.sh. 2

19.1.42. Script slave2.sh. 2

19.1.43. Script test-disco_escritura.sh. 2

19.1.44. Fichero resultado_lectura.sh. 2

19.1.45. Listado de paquetes de software instalado. 2

19.2. Índice de Figuras. 2

19.3. Juegos de pruebas. 2

19.3.1. Test de estabilidad. 2

19.3.2. Benchmarks sintéticos. 2

19.3.2.2. Test ad-hoc. 2

19.3.3. Test de usabilidad. 2

19.4. Referencias bibliográficas. 2

 


1. Introducción

 

De igual manera que en la década de los 70s el advenimiento de los miniordenadores dio un giro a la idea de computación masiva, relegando a los poderosos y caros mainframes a aplicaciones prácticas muy concretas, hoy en día cada vez son más las empresas e instituciones, públicas y privadas, que se decantan por utilizar clusters en detrimento de grandes máquinas.

 

La idea que hay detrás de los clusters de computación es simple. Si la potencia de los ordenadores personales de hoy en día es considerable, ¿por qué no utilizar la potencia conjunta de unas decenas, centenares o incluso miles de éstos para que, trabajando conjuntamente, puedan llevar a cabo tareas más complicadas en un menor tiempo y a un menor coste?

 

En los últimos años, paralelamente al crecimiento en potencia del hardware, ha aumentado la cantidad y calidad de las soluciones software que proveen el sistema necesario para hacer que un conjunto de máquinas interconectadas trabajen al unísono como una gran máquina. Los avances en redes de computadores y el abaratamiento del hardware han contribuido a universalizar el uso de clusters.

 

Si bien la mayoría de las grandes empresas del sector informático han desarrollado algún sistema de clustering propio, no hay que menospreciar el esfuerzo de la comunidad open source que, contando con una cantidad ingente de desarrolladores en todo el mundo, ofrecen soluciones totalmente válidas que de hecho, se utilizan en las universidades más prestigiosas del mundo amen de muchas empresas punteras.

           

Este proyecto, ubicado en Laboratorio de Cálculo del Departamento de Lenguajes y Sistemas Informáticos (LCLSI), está formado por distintos grupos de investigación en los que se llevan a cabo tareas que requieren de una gran potencia de cálculo. Está claro que el modelo “ejecuto mis simulaciones en mi PC”, a estos niveles, no es una solución válida. Para dar respuesta a estas necesidades se barajan tres posibles opciones, que pasan por disponer de:

 

·        Una máquina muy potente (muchas CPUs, mucha memoria)

·        Alquiler de recursos de un superordenador (Marenostrum)

·        Un cluster de computación propio, más escalable y económico.

 

Las dos primeras opciones pueden resultar prohibitivas para una sección de un Departamento como LSI, por exigir un fuerte desembolso inicial, de tal forma que la compra de un cluster parece lo más razonable. Y lo es más si tenemos en cuenta que la sección puede hacer un desembolso inicial, comenzar a explotar el hardware disponible e ir comprando más ordenadores (nodos) a medida que dispongan de los fondos necesarios.

 

 

 

1.1. Descripción del proyecto

 

El proyecto que nos ocupa consiste en la implantación de un nuevo sistema de clustering o computación masiva para el Departamento de Lenguajes y Sistemas Informáticos de la Universitat Politècnica de Catalunya.

 

Las principales actividades del departamento son la docencia y la investigación.  Es esta faceta la que requiere de una gran potencia de cálculo dada la complejidad y variedad de los proyectos que se tratan.

 

Durante este proyecto llevaremos a cabo un análisis de los requisitos para el nuevo sistema de clustering, estudiaremos las distintas opciones y realizaremos una propuesta que finalmente se implementará.

 

1.2. Justificación del proyecto

 

El Laboratorio de Cálculo de LSI, y por tanto el Departamento, viene utilizando clusters desde el año 2002. Actualmente hay principalmente tres grupos de investigación que utilizan clusters en LSI. Históricamente el primero de ellos se puso en marcha hace cinco años, dando servicio a unos pocos usuarios que hasta entonces ejecutaban sus trabajos en sus PCs de escritorio o en máquinas departamentales, carentes de la potencia necesaria.

 

En su día se optó por un sistema de clustering tipo SSI (Single System Image) bajo sistema operativo Linux. En este modelo todos los nodos del cluster cuentan con un kernel común modificado para que el conjunto del cluster se comporte como una sola máquina con tantas CPUs como nodos, donde las interconexiones de red sustituyen a las conexiones entre CPUs de un sistema multiprocesador. La gran ventaja de este modelo es la potente abstracción del hardware resultante: los usuarios del cluster pueden ejecutar sus procesos de la misma forma que lo hacen en su PC, despreocupándose del hardware subyacente. El middleware OpenMosix se encargaba de balancear la carga del cluster moviendo a discreción los procesos de un nodo a otro, buscando en cada momento la optimización de los recursos disponibles.

 

Esta solución, que ha funcionado bastante bien hasta la fecha, se topa con tres grandes problemas:

           

            1. El sistema no cuenta con ningún mecanismo de protección ante sobrecargas por exceso de trabajos en ejecución, de tal forma que podría llegar a colapsarse cuando se lanzan tantos procesos como para consumir toda la memoria disponible.

 

            2. El proyecto OpenMosix lleva años sin facilitar ninguna actualización, de tal manera que la versión más reciente sólo está disponible para un kernel antiguo que no soporta el hardware de los ordenadores más modernos, obligando a las secciones que quieren comprar nuevos nodos para su cluster a comprar hardware obsoleto.

 

            3. El número de usuarios que utilizan los clusters crece continuamente (actualmente disponemos de unos 100 usuarios), por lo que es imperativo un sistema de colas para que los procesos se ejecuten de forma ordenada, maximizando la utilización del hardware en el tiempo.

           

La gestión del espacio de disco dentro del cluster es otro punto de vital importancia. Este modelo no cuenta con servidores de disco dedicados, sino que los nodos dedicados a computación exportan su espacio de disco al resto de nodos.

 

Nuevamente observamos tres problemas:

           

  1. Es engorroso para el usuario, que cuenta con tantas zonas de disco como nodos tiene el cluster (más de 20 zonas en algún cluster).

 

  1. El sistema de ficheros en red utilizado (NFS) produce un gran overhead en la red.

 

  1. No es tolerable a fallos. En caso de que uno de los nodos falle, los datos que se encuentran en su zona dejan de estar disponibles.

 

Desde el Laboratorio de Cálculo la propuesta que se realiza apuesta por cambiar el paradigma de clustering por uno basado en colas, más escalable, seguro, moderno y con garantías de continuidad.

 

Dado que las soluciones hardware de almacenamiento de disco dedicados quedan fuera de nuestro alcance, optamos por aprovechar el espacio de disco disponible en los nodos de la mejor manera posible, utilizando un sistema de ficheros en red distribuido y paralelo.

 

Tanto el sistema de colas como el sistema de ficheros deben ser tolerables a fallos, de tal forma que la caída de un nodo no comprometa el funcionamiento del resto del cluster ni a nivel de  computación ni a nivel de disponibilidad de información.

 

1.3. Motivación personal

 

Durante nueve años he trabajado en el Laboratorio de Cálculo de LSI, primero como becario y más tarde como personal laboral. Durante este tiempo he desempeñando labores de administrador de sistemas, siempre ligado a entornos UNIX y a clusters de computación.

 

Mi motivación a la hora de encarar este proyecto no puede ser mayor, ya que se me presenta la oportunidad de continuar la labor comenzada seis años atrás cuando decidimos apostar por la tecnología cluster. Igualmente, qué mejor forma de corresponder el compromiso y agradecimiento recibido por parte de los usuarios que implementar un nuevo sistema, más potente y fiable que les permita obtener mayores cotas de productividad y satisfacción.

 

El desarrollo de este proyecto me ha permitido explorar el estado del arte de los distintos elementos que componen un cluster de computación. El punto de partida de cualquier proyecto de esta envergadura debe contemplar las soluciones ya implementadas.

 

En este sentido establecimos contacto con distintos departamentos de nuestra universidad como Arquitectura de Computadores, Matemática Aplicada I y administradores de sistemas del supercomputador Marenostrum, lo que nos permitió conocer de primera mano la forma de encarar la construcción de un cluster desde el punto de vista de departamentos similares al nuestro.

 

Una vez el cluster entró en funcionamiento decidimos compartir la experiencia adquirida con todos aquellos que nos abrieron sus puertas, así como todo aquel administrador de sistemas de la UPC interesado en clusters de computación, mediante la realización de una presentación en noviembre de 2008.

 

Por otra parte los conocimientos adquiridos en el desarrollo de este proyecto han servido como base para la presentación de la ponencia que llevó por título Sistemes de computació d’altes prestacions i programari lliure en las VII Jornades de programari Lliure, que tuvieron lugar en Junio de 2008. La documentación de la ponencia puede consultarse en:

 

http://gabriel.verdejo.alvarez.googlepages.com/cluster

 

1.4. Organización del documento

 

Un cluster de computación es un sistema complejo, formado por multitud de elementos hardware y software en cuya construcción se realiza una verdadera labor de ingeniería. La optimización de los recursos disponibles buscando el máximo rendimiento al menor coste implica un conocimiento exhaustivo de las tecnologías que utiliza; a saber: sistemas operativos, redes de datos, software de clustering, filesystems paralelos, alta disponibilidad, etc.

 

Este documento consta de cuatro partes:

 

·        Una primera parte de introducción donde se presentan los diferentes componentes de un cluster y se exploran diversas alternativas para cada componente

 

·        Una segunda parte donde se realiza el análisis técnico del proyecto, se analizan las distintas alternativas y propone una solución.

 

·        Una tercera parte que comprende la implementación de la solución propuesta, explicando el proceso de instalación y configuración de cada uno de los componentes y la implantación del nuevo cluster en sustitución del actual.

 

·        Finalmente un apartado de bibliografía y anexos. Por lo general toda referencia aparecerá en los anexos.

 

Este documento pretende servir como obra de referencia en la construcción y mantenimiento de un cluster de computación. Se asume un cierto conocimiento de informática en general y de  administración de sistemas UNIX en particular, ya que es imposible profundizar completamente en todos los temas tratados. De todas formas, el documento está redactado de forma que un lector menos experto, pero con interés, pueda seguir los procedimientos explicados obviando los detalles más técnicos.

1.5. La doble utilidad del documento

 

Este escrito, además de documentar este proyecto, pretende servir también como referencia a las personas encargadas de la administración del cluster.

 

En este sentido es interesante que, además de existir una copia en papel, exista una copia disponible en formato electrónico. Esto permitirá una mayor facilidad de consulta y abrirá la puerta a posibles correcciones y actualizaciones.

 

El cluster cuenta con su propio servidor web que, además de ofrecer servicios relacionados con la monitorización y administración del cluster sirve un repositorio de documentación propia:

 

http://master-cluster1.lsi.upc.edu/docu

 

En esta url, además de una copia de este documento, se encuentra información adicional como manuales y presentaciones.

 

1.6. Convenciones y tipografía

 

Para una mejor comprensión de este documento, dada la elevada naturaleza técnica de su contenido se seguirán una serie de convenciones tipográficas.

 

Convenciones tipográficas

 

Como ya se ha podido ver, los nombres propios de origen extranjero, así como los nombres de instituciones u organizaciones (como Departamento de Lenguajes y Sistemas Informáticos) aparecen en cursiva.

 

Igualmente, todos aquellos anglicismos que necesariamente aparecen en este texto, así como cualquier otro vocablo del ámbito de la informática, aparecerán también en cursiva la primera vez que se referencien. Lo mismo sucederá con palabras que, si bien son de origen foráneo, forman ya parte de nuestro lenguaje (como por ejemplo software).

 

Una parte importante de este proyecto consiste en código fuente de programas, contenido de ficheros datos y configuración, nombres de directorios, ficheros, etc. En estos casos el texto aparecerá en fuente de ancho fijo (como /etc/dhcp3), y los comandos o nombres de programas o scripts, además, en negrita (como check_sge.sh).

 

Convenciones no tipográficas

 

La ambigüedad propia del lenguaje también está presente, en gran medida, en los documentos de carácter técnico. De esta forma, a lo largo del documento, utilizamos indistintamente el término sistema de clustering para denotar tanto al hardware que conforma un cluster como al software que lo gobierna. Siempre que la utilización de estos términos pueda llevar a equívoco se aclarará su significado.

 

Siglas y acrónimos serán utilizados, previa introducción de su significado, para facilitar la lectura del texto.

 


2. Análisis preliminar

 

 

2.1. Situación actual

 

En el momento de comenzar este proyecto, el Departamento de Lenguajes y Sistemas Informáticos contaba con tres clusters de computación. Cada uno ellos propiedad de un grupo de investigación distinto.

 

El modelo HPC[1]  utilizado basado en openMosix que proporcionaba un entorno confortable y productivo para la cantidad inicial de usuarios, ha quedado obsoleto ante el continuo crecimiento tanto en número de usuarios como en necesidades de cálculo y espacio de disco.

 

Igualmente, el esquema lógico de la infraestructura hardware así como el sistema que sustenta los datos de usuario, no cuentan con ningún mecanismo que proporcione tolerancia a fallos (caída de un nodo, fallo de un disco) ni alta disponibilidad.

 

Más adelante, en apartado [7.1] dedicado al análisis del sistema actual, se detallará a nivel técnico las carencias del modelo actual.

 

2.2. Objetivos del proyecto

 

La finalidad de este proyecto es doble. Por una parte, la sustitución de los  clusters por uno nuevo que se adapte a las nuevas necesidades del Departamento y por otra, la creación de una documentación que sirva como  referencia técnica al Laboratorio de Cálculo.

 

El sistema debe proveer a los usuarios un entorno de trabajo sencillo, amigable y proporcionar una escalabilidad que permita afrontar el futuro sentando unas bases sólidas.

 

2.3. Requerimientos del proyecto

 

Una vez expuestos los objetivos del proyecto, enumeraré los requerimientos que tendremos en cuenta a la hora de llevar a cabo el diseño y la implementación:

 

·        La infraestructura hardware del nuevo cluster debe hacer uso del hardware existente (nodos, red y discos).

 

·        Debe soportar una carga de trabajo superior a la actual, dada la tendencia creciente en cuanto a número de usuarios y, por tanto, de volumen de trabajo.

 

·        Debe ser tolerable a fallos. El fallo de una parte del sistema no puede comprometer el funcionamiento del conjunto del cluster.

 

·        Debe ser escalable, tanto a nivel de software como a nivel de infraestructura hardware.

 

En cuanto a la documentación, debe ser clara, concisa y no omitir información básica pero necesaria para el entendimiento completo de conceptos más complejos. Al fin y al cabo esta documentación debe permitir a cualquier persona cualificada del Laboratorio de Cálculo entender el funcionamiento del cluster y poder actuar en caso de que se produzca cualquier incidencia.


PRIMERA PARTE

SISTEMAS DE CLUSTERING

 

 

 


3. Clusters

 

En este apartado daremos una visión general de lo que es un cluster de cómputo, repasaremos brevemente su historia y los clasificaremos atendiendo a diversos criterios según la bibliografía existente.

 

3.1. ¿Qué es un cluster?

 

Cuando hablamos de Clusters en el ámbito de la computación nos referimos al conjunto de hardware y software que aglutina a grupos de ordenadores que, unidos mediante redes de alta velocidad, trabajan de forma conjunta en la resolución de problemas.

 

Los clusters se usan habitualmente para mejorar el rendimiento y/o la disponibilidad por encima de la que provee un solo ordenador, resultando mucho más económico que grandes ordenadores de velocidad y disponibilidad comparables.

 

Cualquier cluster ofrece uno o varios de los siguientes servicios:

 

·        Alto rendimiento: el conjunto del cluster ofrece una capacidad computacional por encima de la de cualquiera de los elementos que lo conforman.

 

·        Alta disponibilidad: la redundancia del hardware permite mantener el servicio que ofrecen aún y cuando falle alguno de los componentes del cluster.

 

·        Balanceo  de carga: la calidad de servicio mejora repartiendo el trabajo entre los nodos del cluster.

 

·        Escalabilidad: la adición de nuevos elementos al cluster provoca un aumento proporcional de su capacidad.

 

En general, un cluster necesita de varios componentes software y hardware para funcionar:

 

·        Nodos

·        Sistema de almacenamiento

·        Sistema Operativo

 

·        Conexión de red

·        Middleware

·        Protocolos de comunicación y servicios

·        Aplicaciones

 

Nodos

 

Pueden ser desde ordenadores corrientes hasta caros sistemas multiprocesador. En general, cuando hablamos de nodo dentro del ámbito de la computación nos referimos a cada uno de los ordenadores que lo conforman. Los nodos pueden ser dedicados si se dedican exclusivamente a labores del cluster o no dedicados si lo hacen de forma parcial o compartida con alguna otra tarea.

 

Sistema de almacenamiento

 

El sistema de almacenamiento en un cluster no es un tema baladí. En un cluster de tamaño medio puede haber cientos de nodos, cada uno ejecutando uno o varios trabajos que acceden simultáneamente  a datos. Si estos datos no son accesibles de forma eficiente, el rendimiento del cluster se verá afectado.

 

Los sistemas de almacenamiento típicos son:

 

·        NAS (Network Attached Storage): es un dispositivo dedicado al almacenamiento de datos y a su compartición en red. Cuenta con un sistema operativo optimizado que permite el acceso a los datos a través de diversos protocolos como CIFS y NFS.

 

·        SAN (Storage Area Network): son unidades de almacenamiento externo que se conectan a uno o varios servidores.

 

·        Discos locales: se utilizan los discos locales de los nodos, ya sean IDE, SATA, SCSI o SAS.

 

La elección de un sistema u otro depende en gran parte de la disponibilidad económica. Los discos duros locales siempre están disponibles en cualquier nodo que se adquiera y siempre pueden sustituirse por discos de mayor tamaño por poco dinero.

 

Los sistemas NAS y SAN son sistemas de un rendimiento superior pero que requieren de un desembolso inicial importante. Posteriormente estos sistemas pueden crecer añadiendo más discos.

 

Como lo habitual es que todos los nodos tengan acceso a los mismos datos, la información del sistema de almacenamiento disponible se exporta mediante algún sistema de ficheros distribuido como NFS (Network Filesystem) o distribuido paralelo como Lustre o GlusterFS.

 

Sistema operativo

 

El sistema operativo de un cluster debe ser  multiproceso y multiusuario. Existen distribuciones específicas que se componen de un sistema operativo y del software de clustering, si bien también es posible añadir la capacidad de clustering a casi cualquier sistema operativo.

 

Sin lugar a dudas es dentro del mundo UNIX donde encontramos la mayor oferta de sistemas de clustering. Más concretamente Linux, dado su carácter libre y su gran difusión es, en cualquiera de sus variantes, el sistema operativo más extendido para estos sistemas de cómputo.

 

Conexión de red

 

La interconexión de los nodos juega un papel muy importante dentro de la arquitectura de un cluster, siendo una parte crítica en determinados tipos de clusters. No en vano las conexiones de red en un cluster vienen a ser lo que las conexiones interprocesador son en un ordenador multiprocesador.

 

La tecnología de conexión puede ser desde la más barata y extendida ethernet hasta las más caras y avanzadas como Myrinet o Infiniband. Estas últimas cuentan con mayor ancho de banda y menor latencia, la cual cosa las hace ideales para clusters de tipo HPC.

 

Middleware

 

El middleware es una pieza de software que se sitúa entre el sistema operativo y las aplicaciones con el fin de proveer:

 

·        Abstracción del hardware: los usuarios ven el cluster como un único ordenador muy potente con el que interactúan, desentendiéndose de la arquitectura subyacente.

 

·        Herramientas de gestión del sistema: migración de procesos, checkpointing, balanceo de carga, tolerancia a fallos, etc.

 

·        Escalabilidad: detección e incorporación automática de nuevos nodos al cluster.

 

El middleware recoge los trabajos enviados al cluster por los usuarios y los distribuye entre los nodos de computación de la mejor manera posible, atendiendo a políticas más o menos sofisticadas de planificación.

 

Aplicaciones

 

Son las tareas que los usuarios envían al cluster. El sistema de clustering debe estar preparado para atender los requisitos de ejecución de las tareas, que pueden ser desde simples scripts a complejos programas paralelos. Estos últimos necesitan del apoyo de librerías de programación paralela como MPI o PVM, que deben integrarse adecuadamente en el sistema.

 

3.2. Un poco de historia

 

La bibliografía no fija una fecha concreta para el origen del término cluster pero es bien sabido que comenzó a utilizarse entre finales de los años 50s y principios de los 60s.

 

 La idea de la explotación de sistemas de ordenadores como un medio para acelerar el cálculo paralelo data de 1967 cuando Gene Amdahl de IBM, publicó su famosa ley, que describe matemáticamente la ganancia esperada al paralelizar tareas en una arquitectura paralela. El artículo define la base para la ingeniería multiprocesador, que es extrapolable a clusters de computación, donde la comunicación interprocesador es sustituida por conexiones de red.

 

La historia de los primeros clusters trascurre paralela a la historia de las primeras redes. Una de las principales motivaciones para el desarrollo de las redes de entonces era conectar recursos de cálculo, creando de hecho un gigantesco cluster.

 

Las redes de conmutación de paquetes fueron inventadas por la corporación RAND en 1962. Utilizando esta tecnología, en 1969, el proyecto ARPANET creó la primera red de computadoras, que unían los recursos de cuatro centros de cálculo. El proyecto ARPANET creció  hasta convertirse lo que hoy en día es Internet.

 

El desarrollo de PCs y clusters de grupos de investigación continuó de la mano con el de las redes y el sistema operativo Unix que a principios de los 1970s, ya incluía protocolos de comunicaciones de red como TCP/IP.

 

Pero no fue hasta 1983 cuando, gracias a los conceptos formalizados por BSD Unix e implementados por Sun Microsystems, el público contó con verdaderas herramientas que permitiesen la compartición  recursos, como ficheros gracias a la inclusión del sistema de ficheros distribuido NFS.

 

ARCnet, el primer cluster comercial desarrollado por Datapoint en 1977, no tuvo una gran acogida. Sin embargo en 1984 Digital introdujo con gran éxito el VAXcluster, acompañado del sistema operativo VAX/VMS. Ambos sistemas no permitían el procesamiento paralelo, pero sí la compartición de recursos como archivos y periféricos.

 

Otros productos pioneros fueron el Tandem Himalaya en 1994 como producto de alta disponibilidad  y el IBM S/390 Parallell Sysplex destinado a grandes empresas.

 

Cabe remarcar también el papel jugado por el software Parallel Virtual Machine (PVM), creado en 1989. Este proyecto open source basado en comunicaciones TCP/IP permitió la creación de superordenadores creados por cualquier cantidad de sistemas conectados por red. Rápidamente estos clusters superaron con creces la potencia de los grandes y caros superordenadores de la época.

 

Finalmente, en 1995 se creó el primer Beowulf, cluster con sistema operativo Linux caracterizado por utilizar ordenadores y redes convencionales con el fin único de procesar tareas paralelas con un gran throughput.

3.3. Tipos de cluster

 

El término cluster tiene diferentes connotaciones en función de los servicios que ofrecen. Si atendemos a una categorización según el fin para el que fueron concebidos, tenemos los siguientes tipos:

 

·        HPC (High Performance Clusters o Clusters de Alto Rendimiento): Llevan a cabo tareas de una gran capacidad computacional, que ejecutadas en ordenadores corrientes serían inabarcables, ya sea por sus altos requisitos de memoria, potencia de cálculo o de ambas.

 

·        HTC (High Throughput Clusters o Clusters de Alta Eficiencia): Están diseñados para llevar a cabo la mayor cantidad de tareas en el menor tiempo posible. Los datos de las tareas son individuales entre si y la latencia entre los nodos no es tan importante como en los clusters HPC. 

 

·        HA (High Availability Clusters o clusters de Alta Disponibilidad): También conocidos como clusters Failover, su principal cometido es mejorar la disponibilidad de los servicios que proporciona. Su arquitectura se compone de nodos redundantes que proveen el servicio cuando algún componente falla.

 

 Normalmente están formados por dos nodos, que es lo mínimo necesario para tener redundancia. La existencia de redundancia en el hardware evita tener un único punto de fallo, maximizando así la disponibilidad.

 

Parte del éxito de los clusters radica en su extrema flexibilidad desde el punto de vista de la arquitectura. En este sentido encontramos las siguientes categorías:

 

·        Clusters Homogéneos: Todos los nodos cuentan con el mismo hardware y sistema operativo.

 

·        Clusters Heterogéneos: Nodos con diferente hardware y sistema operativo.

 

·        Clusters Semihomogéneos: Hardware y sistemas operativos similares, pero con distinto rendimiento.

 


4. Cluster Filesystems

 

Cuando hablamos de un sistema de ficheros para un cluster se suele pensar en sistemas de ficheros complejos, extraños y alejados de los utilizados habitualmente en sistemas más convencionales. Nada más lejos de la realidad. Un cluster no tiene porqué contar con el filesystem más complejo ni con el que usan los clusters más potentes, ni siquiera con uno concebido a tal efecto. Para cada cluster, o mejor dicho, dependiendo del uso y de la exigencia que se vaya a dar, hay un abanico enorme de posibilidades que van desde filesystems distribuidos ordinarios a complejos filesystems paralelos.

 

4.1. Glosario

 

En este apartado estudiaremos algunos filesystems susceptibles de ser utilizados dentro de un cluster de computación como el que proyectamos. Antes es necesario dar algunas definiciones para facilitar su comprensión:

 

·        Filesystem: método de almacenamiento y organización de ficheros y los datos que permite su búsqueda y acceso.

 

·        Servidor: máquina que pone a disposición de otras máquinas (clientes) conectadas por red un sistema de ficheros.

 

·        Cliente: máquina que accede al sistema de ficheros de una máquina remota (servidor).

 

·        Daemon: o demonio es un programa que se ejecuta en segundo plano (background) de forma indefinida encargado de recibir y procesar peticiones.

 

·        Automounter: sistema que monta sistemas de ficheros bajo demanda, reduciendo así el overhead de mantener la conexión entre servidor y clientes cuando los clientes no están accediendo al filesystem remoto.

 

·        Bloqueo: o en inglés lock, es un mecanismo que permite asegurar la integridad de los datos cuando son accedidos de forma concurrente.

 

·        Stripe: aplicado a filesystems paralelos, cada una de las partes en que se divide un fichero y que son guardadas en servidores de datos distintos para aumentar el rendimiento de lectura y escritura.

 

·        Network filesystem o distributed filesystem: es un sistema de ficheros que soporta la compartición de ficheros, impresoras u otros recursos de forma persistente a través de una red.

 

·        Parallel filesystem: sistemas de ficheros distribuidos que distribuyen los datos en varios servidores para obtener un mayor rendimiento. Suelen utilizarse en clusters de alto rendimiento (HPC).

 

4.2. Sistemas de ficheros distribuidos

 

Un sistema de ficheros distribuido se muestra a los usuarios como un sistema de ficheros local convencional. La multiplicidad y la dispersión de los servidores y su almacenamiento queda oculto. De hecho, los programas que tratan con datos no distinguen si éstos son locales o no.

 

El rendimiento esperado de un sistema de ficheros distribuido es menor que el de un sistema de ficheros local, ya que al tiempo de acceso a disco y proceso de CPU hay que sumar el overhead producido por la comunicación por la red. Esto incluye el tiempo de realizar la petición al servidor y el tiempo en obtener la respuesta en ambas direcciones más el overhead de CPU que provoca el protocolo de comunicaciones.

4.2.1. Network File System (NFS)

 

NFS es un protocolo de nivel de aplicación según el modelo OSI que se utiliza en sistemas de archivos distribuidos en redes de área local. Permite que distintos sistemas conectados a una misma red tengan acceso a ficheros remotos como si fueran locales. Fue desarrollado en 1984 por Sun Microsystems con el objetivo de que fuera independiente de la máquina, el sistema operativo y el protocolo de transporte.

 

 

nfscomponents

Figura 4.1. El protocolo NFS en los modelos OSI y TCP/IP

 

 

El protocolo NFS está incluido por defecto en los sistemas operativos UNIX. NFS utiliza un esquema cliente-servidor, donde los clientes acceden de forma remota a los datos que se encuentran almacenados en el servidor.

 

Los clientes utilizan menos espacio de disco, ya que los datos están centralizados en un servidor, evitando así tener datos replicados. La centralización del home de usuarios es un uso habitual de NFS dentro de organizaciones.

 

Todas las operaciones sobre ficheros son síncronas. Esto quiere decir que la operación sólo retorna cuando se ha completado el trabajo asociado, que en el caso de una escritura será cuando el servidor escriba físicamente los datos en disco. De esta forma la integridad de los ficheros queda garantizada.

 

Actualmente hay tres versiones en uso:

 

·        Versión 2: originalmente desarrollada sobre UDP,  es la más antigua y está soportada por muchos sistemas operativos.

 

·        Versión 3: incluye soporte 64 bits que permite manejar ficheros de más de 4 GB, escrituras asíncronas para mejorar el rendimiento, atributos extendidos y en algunas implementaciones, soporte TCP como transporte.

 

·        Versión 4: influenciado por AFS y CIFS, incluye cambios orientados a mejorar el rendimiento y la seguridad como soporte Kerberos y ACLs.

4.2.2. Samba

 

Samba es un software opensource para sistemas UNIX que implementa el protocolo SMB (Server Message Protocol) de archivos compartidos de Microsoft Windows, que permite la compartición de ficheros e impresoras entre sistemas Windows y UNIX.

 

Samba implementa una docena de protocolos entre los que se encuentran NetBIOS, WINS la suit de protocolos de dominio NT, Active Directory y SMB, también conocido como CIFS.

 

Como hemos comentado, Samba permite la compartición de recursos en sistemas heterogéneos. Ahora bien, limitaciones como la incompatibilidad con los atributos de ficheros y los enlaces simbólicos de los sistemas de ficheros del mundo UNIX, lo desaconsejan como filesystem distribuido para clusters formados exclusivamente por máquinas UNIX.

 

4.3. Sistemas de ficheros paralelos

 

Los sistemas de ficheros distribuidos paralelos surgen de la necesidad de solucionar los problemas que nos encontramos al utilizar sistemas de ficheros distribuidos convencionales en clusters de computación.

 

Sistemas de ficheros distribuidos como NFS provocan un gran overhead de red que en condiciones de E/S intensiva llegan a saturar el acceso a los datos. Si imaginamos un escenario con un cluster de tamaño medio de unos pocos centenares de nodos es fácil hacerse a la idea de la cantidad ingente de peticiones de E/S que pueden generarse en un disco compartido.

 

Los sistemas de ficheros distribuidos paralelos solucionan este problema reduciendo el overhead de red y distribuyendo los datos entre varios servidores para paralelizar las lecturas y escrituras.

 

4.3.1. GPFS

 

General Parallel Filesystem (GPFS) es un sistema de ficheros distribuido paralelo desarrollado por IBM. Proporciona acceso compartido concurrente de alta velocidad a aplicaciones que se ejecutan en distintos nodos de un cluster.

 

Inicialmente fue diseñado para soportar las altas tasas de transferencia requeridas por las aplicaciones multimedia, pero su diseño resultó muy adecuado para la computación científica. Fue desarrollado en 1993, pero no vio la luz comercialmente hasta 1998 cuando fue publicado para el sistema operativo AIX. Desde 2001 también hay disponible una versión para Linux.

 

El principio de funcionamiento de GPFS es el mismo que el de cualquier sistema de ficheros paralelo. En un cluster de almacenamiento GPFS hay nodos servidores, que almacenan datos, y nodos clientes que acceden a ellos. Cuando se realiza una operación de escritura sobre este filesystem los datos se trocean  y se distribuyen en tiras (stripes) que son almacenadas en varias máquinas servidoras de disco. De esta forma se obtiene un mayor rendimiento al acceder a los distintos bloques en paralelo. Además GPFS permite alta disponibilidad, ya que los datos pueden guardarse replicados en varios servidores.

4.3.2. Lustre

 

Lustre es un sistema de ficheros distribuido paralelo para clusters escalable, robusto y con alta disponibilidad. Desarrollado y mantenido por Sun Microsystems, está disponible bajo licencia GNU GPL.

 

Proporciona  un sistema de almacenamiento que escala correctamente desde sistemas con decenas de nodos y terabytes de capacidad de almacenamiento hasta grandes clusters con decenas de miles de nodos con petabytes de información.

 

Lustre es considerado el mejor filesystem distribuido paralelo. De hecho 15 de los 30 mayores superordenadores del mundo[2] hacen uso de Lustre y su gran escalabilidad.

 

Durante la fase de pruebas/integración comprobaremos si, el que sobre el papel es el mejor sistema de ficheros distribuido paralelo, se adapta a nuestras necesidades. Nuestro sistema de cluster no llega al centenar de nodos y tiene algunas limitaciones hardware por lo que, como veremos, será necesario aunar distintas tecnologías para tener un sistema funcional.

 

 

kompass_lustre

Figura 4.2: Ejemplo de cluster Lustre

 

4.3.3. GlusterFS

 

GlusterFS es un sistema de ficheros paralelo distribuido, disponible bajo licencia GNU v3, capaz de escalar hasta varios petabytes. GlusterFS aglutina varias unidades de almacenamiento independientes en un gran sistema de ficheros paralelo sencillo y altamente escalable. Cada unidad de almacenamiento cuenta con su propia CPU, memoria, bus de E/S, almacenamiento RAID e interfaz de red. El rendimiento pico teórico sería el rendimento agregado de todas las unidades. GlusterFS está diseñado para escalar linealmente en clusters de gran tamaño.

 

El servidor GlusterFS permite exportar volúmenes sobre la red. El cliente GlusterFS monta los volúmenes del servidor en el kernel VFS. La mayor parte de la funcionalidad de GlusterFS está implementada mediante translators.

 

La idea de translator está basada en el sistema operativo GNU/Hurd (http://hurd.gnu.org). Los Translators son un mecanismo muy potente que permite a GlusterFS extender sus capacidades a través de un interfaz bien definido. Los translators del lado cliente y servidor son compatibles, por lo que se pueden cargar indiferentemente en cada parte. Son objetos binarios compartidos (.so) que se cargan en tiempo de ejecución según el ficheros de especificación del volumen.

 

Glusterfs-cluster

Figura 4.3: Ejemplo de configuración de GlusterFS con 4 nodos de almacenamiento y 1 nodo cliente


5. Software de Clustering

 

Como hemos visto en el capítulo [3] no basta con conectar una serie de ordenadores en red para tener un cluster. Es necesario un software o middleware que se encargue de distribuir los trabajos de los usuarios entre los nodos disponibles de forma óptima.

 

A continuación veremos varios ejemplos de sistemas de clustering, profundizando especialmente en openMosix por ser el middleware de los tres clusters en producción. Más adelante, en el análisis del sistema actual (apartado [7.1]), volveremos a hablar de openMosix y expondremos las limitaciones que nos han llevado a su sustitución.

 

5.1. openMosix

 

openMosix tiene su origen en Mosix, un sistema de clustering SSI (Single System Image), cuyo desarrollo comenzó en 1981 en la Hebrew University of Jerusalem. Tras diversas encarnaciones en diferentes sistemas UNIX, Mosix es portado a Linux en 1999.

 

A finales de 2001 Mosix deja de distribuirse bajo licencia GPL, y es entonces cuando nace openMosix, la versión abierta de Mosix, bajo licencia full GPL2. Esto permitió que el proyecto openMosix contase con una amplia comunidad respaldándolo y contribuyendo a su desarrollo.

 

OpenMosix es un software que permite que ordenadores conectados en red funcionando bajo GNU/Linux trabajen de forma cooperativa. Es capaz de balancear automáticamente  la carga entre los diferentes nodos del cluster y permite la adición o sustracción de nodos en caliente sin necesidad de interrumpir el servicio.

 

La carga se distribuye entre los distintos nodos atendiendo a parámetros como tipo de conexión, memoria disponible y velocidad de CPU.

 

Dado que openMosix forma parte del kernel y mantiene total compatibilidad con Linux, los programas de usuario, ficheros y otros recursos funcionarán igualmente sin cambio alguno. El usuario final no notan diferencia alguna entre ejecutar sus aplicaciones en su sistema Linux o en un cluster openMosix. Para ellos, la totalidad del cluster se presenta como un gran sistema multiprocesador.

 

OpenMosix consta de un parche de kernel Linux compatible con plataformas IA32. Este parche introduce las modificaciones necesarias en el kernel que permiten la comunicación entre los nodos del cluster. Todos los nodos de un cluster openMosix cuentan con el mismo kernel modificado, de ahí el nombre de cluster Single System Image (SSI).

 

El algoritmo de balanceo de carga migra los procesos entre los distintos nodos de forma transparente, intentando optimizar su utilización en todo momento, si bien el administrador puede modificar manualmente este algoritmo.

 

El hecho de que la migración de procesos se haga de forma transparente hace que el conjunto del cluster se muestre como un gran sistema multiprocesador (SMP) con tantos procesadores disponibles como el sumatorio de los procesadores de todos los nodos.

 

 

 

Figura 5.1: Arquitectura de un cluster tipo SSI

 

 

Características de openMosix

 

·        Alta escalabilidad.

·        Algoritmo adaptativo de balanceo de carga.

·        Migración dinámica de procesos.

·        Middleware de clustering en kernel, por lo que no son necesarias librerías externas.

·        Totalmente transparente a usuario y aplicaciones.

·        Fácil instalación y administración.

·        Posibilidad de añadir y eliminar nodos en caliente.

·        Integración con librerías de paralelización MPI/PVM.

 

Funcionamiento de openMosix

 

OpenMosix consta de una parte de sistema (kernel space) y otra de usuario (user space):

 

La parte de usuario dispone de una serie de herramientas que permiten monitorizar el cluster y la modificación del comportamiento por defecto de openMosix.

 

La parte de sistema consiste en un parche de kernel que a su vez consta de cuatro subsistemas:

 

  1. Migración de procesos: Cada proceso tiene su nodo raíz (UHN, Unique Home Node) que se corresponde con el nodo que lo ha creado. El concepto de migración implica la división del proceso en dos partes: la parte de sistema y la de usuario. La parte de sistema (deputy) permanece en su UHN durante toda la vida del proceso, mientras que la parte de usuario puede moverse libremente por todos los nodos del cluster.

 

 

 

Figura 5.2: División de procesos en openMosix

 

 

El sistema de migración utiliza algoritmos del campo de la economía para decidir cuándo migrar un proceso. A cada recurso  (CPU, memoria, E/S) de cada nodo se le da un coste.

 

Estos costes son unificados en un GFC (global cost function). El valor del CFG de un nodo no se publicita a todo el cluster, sino a un subconjunto aleatorio de sus vecinos.

 

Los procesos son migrados al nodo donde tienen el menor coste: se obtiene así la distribución más “económica” posible. Cada proceso puede migrar cuantas veces sea necesario.

 

  1. Memory ushering: Este subsistema se encarga de migrar las tareas que superan la memoria disponible en el nodo en el que se ejecutan. Las tareas que superan este límite son migradas forzosamente a otros nodos con la suficiente memoria como para ejecutar el proceso sin necesidad de hacer swap a disco, evitando así una gran pérdida de rendimiento.

 

  1. Mosix File System (MFS): MFS permite que sistemas de ficheros de nodos remotos sea accesibles localmente. Si se habilita esta opción en el kernel, el sistema de ficheros del nodo local y los demás aparecerán montados en /mfs.

 

  1. Direct File System Access (DFSA): esta opción permite a los procesos hacer operaciones de E/S de forma local en nodos remotos. Sin DFSA, cada operación de E/S que se produzca en un nodo “migrado” será enviada al UHN, donde se resolverá.

 

5.2. Condor

 

Condor es un software que crea un entorno de computación HTC formado por estaciones de trabajo UNIX conectadas en red. Fue creado por la University of Winsconsin-Madison (UW-Madison) a principios de los años 90s. Como otros sistemas de colas, Condor provee un sistema de encolado de trabajos, políticas de planificación, prioridades, monitorización y control de recursos. Los usuarios envían sus trabajos al planificador, que les asigna una cola y elije cuándo y dónde ejecutarlos en base a una política preestablecida, monitoriza su progreso y finalmente informa a los usuarios de su finalización. Como todo sistema HTC lo que se busca es obtener un gran rendimiento a largo plazo.

 

Condor puede configurarse para utilizar los ciclos libres en máquinas conectadas a la red y que no están pensadas como máquinas de computación, como de PCs de escritorio. En este caso, en momentos en los que estas máquinas no son utilizadas pasan a formar parte del cluster. Cualquier evento de usuario como un input de teclado o ratón, provoca que la máquina salga del cluster.

 

Este modelo es especialmente interesante para organizaciones que cuentan con una gran número de PCs de usuario con muchos ciclos libres; por ejemplo, durante las noches o fuera del horario laboral. Durante estos espacios de tiempo, el cluster Condor crecería considerablemente, incrementando notablemente el thoughput de cómputo.

 

5.3. PBS

 

PBS (Portable Batch System) es un sistema de trabajos batch y un sistema de gestión de recursos. Fue desarrollado por la NASA a principios de los años 90s conforme al estándar POSIX 1300.2d Batch Environment Standard . Como tal acepta trabajos batch en forma de shellscript con atributos de control, preserva y protege el trabajo hasta que está listo para ser ejecutado, lo ejecuta y, finalmente, devuelve la salida al usuario.

 

PBS consta de cuatro componentes:

 

·        Commands: PBS proporciona una serie de comandos en línea así como un interfaz gráfico, ambos conforme al estándar POSIX 1003.2d. Estos comandos permiten enviar, monitorizar, modificar y borrar trabajos.

 

·        Job Server: es la parte central de PBS. Todos los comandos y daemons se comunican con el servidor. La principal función de éste es proveer los servicios batch básicos como recibir y crear un trabajo, modificarlo, protegerlo de posibles caídas del sistema y ponerlo en ejecución.

 

·        Job Executor: es el daemon que realmente pone el trabajo en ejecución. Su nombre, mom, se debe a que es la madre de todos los procesos en ejecución. Mom pone en ejecución el trabajo cuando recibe una copia del servidor. También reproduce la sesión del usuario propietario del trabajo  (shell, .login, .csh, etc). Finalmente, al acabar el trabajo, devuelve la salida al usuario.

 

·        Job Scheduler: este daemon contiene las políticas que controlan qué trabajo, cuándo u dónde se ejecutan los trabajos.

 

5.4. Sun Grid Engine

 

Sun Grid Engine (SGE) es un sistema de gestión de colas open source desarrollado por Sun Microsystems.

 

En el año 2000 Sun adquirió Gridware, empresa especializada en sistemas de gestión de resursos de computación para ofrecer una versión free de Gridware para Solaris y Linux a la que llamó Sun Grid Engine.

 

En 2001, liberó el código y adoptó el modelo de desarrollo open source, tras lo que surgieron ports para otros sistemas UNIX.

 

Es un sistema altamente configurable, sencillo de de administrar y de utilizar por parte de los usuarios. Su escalabilidad lo ha llevado a ser el sistema de clustering de mayor éxito entre los mayores clusters de supercomputación.

 

Como sistema de gestión de colas, SGE se encarga de aceptar, planificar y ejecutar grandes cantidades de trabajos. También se encarga de la gestión y planificación de recursos distribuidos como procesadores, memoria, disco y licencias de software.

 

Un cluster Sun Grid se compone de un master host y uno o más execution host. Además pueden configurarse múltiples shadow hosts como hot spares capaces de tomar el control del master host cuando falle, proporcionando alta disponibilidad.

 

Al igual que Condor y PBS, Sun Grid trabaja con shellscripts que definen los requisitos de los trabajos de los usuarios, pero además puede tratar directamente con binarios e incluso ejecutar trabajos interactivos.

 

Se trata, sin lugar a dudas, del producto más completo disponible en el mercado, tanto por rendimiento como por facilidad de uso y capacidad de configuración. A todo esto hay que sumar el hecho de que se trata de un proyecto opensource con una comunidad de desarrolladores y administradores ingente y, algo de lo que pecan otros proyectos, el respaldo de una empresa del prestigio como Sun Microsystems.

 

 

 

 


6. Alta disponibilidad

 

 

En el apartado [3.3] hemos visto que los clusters HA o de alta disponibilidad son un tipo de clusters con nodos redundantes encargados de mantener un servicio en caso de fallo hardware. En este capítulo explicaremos los principios básicos de la alta disponibilidad.

 

En servicios críticos suelen implementarse sistemas tolerables a fallos (fault tolerant o FT) en los que el servicio siempre está disponible. Estos sistemas son extremadamente caros, por lo que suelen quedar fuera del abasto de empresas e instituciones de tamaño medio.

 

Los sistemas de alta disponibilidad intentan obtener prestaciones cercanas a la tolerancia a fallos a un precio mucho menor. La alta disponibilidad está basada en la replicación de elementos, lo que resulta mucho más barato que contar con un solo elemento tolerable a fallos.

 

A efectos prácticos, la diferencia entre los sistemas tolerables a fallos y los de alta disponibilidad es el periodo de tiempo en el cual el servicio no está disponible (downtime). En sistemas tolerables a fallos este tiempo no existe, mientras que en los sistemas de alta disponibilidad se intenta minimizar pero existen, pudiendo ser de unos segundos a varios minutos, dependiendo del timeout que decide si el sistema ha fallado.

 

Un sistema de alta disponibilidad se basa en la replicación de elementos, ya sean piezas hardware concretas o servidores completos, tomando como modelo los RAID (Redundant Array of Independent Disks). El objetivo de la replicación es eliminar los puntos de fallo únicos (SPOF, Single Point of Failure). Cualquier elemento no replicado es susceptible de fallar y producir un corte en el servicio. Cuando lo que se replica es un servidor completo hablamos de un cluster HA.

 

6.1. Funcionamiento de un sistema HA

 

A continuación definiremos una serie de conceptos básicos para la alta disponibilidad:

 

Failover

 

Es el nombre genérico que se da a un nodo que puede asumir la responsabilidad de otro, importar sus recursos y levantar sus servicios. Cuando se da esta situación, en el caso de servicios con nodos duplicados, nos encontramos temporalmente en un escenario de SPOF hasta que el administrador restaure el nodo caído.

 

Takeover

 

Es un failover automático que se produce cuando un nodo detecta el fallo de otro. Para ello es necesario mecanismos de monitorización del servicio. Debe haber mecanismos que obliguen al nodo fallado a ceder sus servicios para evitar inconsistencias de funcionamiento.

 

Switchover o Giveaway

 

Es un failover manual que consiste en ceder los servicios del nodo que ha fallado a otro nodo mientras se llevan a cabo las actuaciones administrativas pertinentes.

 

Splitbrain

 

Para la gestión de un cluster HA es necesario un mecanismo de comunicación y verificación de los nodos que lo integran. Cada nodo debe gestionar sus propios recursos según el estado del cluster a la vez que chequea el estado de los otros nodos y servicios.

 

Se produce un splitbrain cuando la comunicación entre los nodos falla. En esta situación cada nodo cree que es el único activo y como no puede saber el estado de su compañero considera que ha fallado y fuerza un takeover.

 

Esta situación es peligrosa, ya que los dos nodos intentan apropiarse de los recursos. El peligro es aún mayor cuando el servicio es, por ejemplo, un sistema de almacenamiento de datos, en el que cada nodo podría escribir por su cuenta y provocar corrupción de datos.

 

Para solucionar este tipo de situaciones, cuando un nodo detecta un fallo reserva un recurso compartido llamado quórum. El quórum es un recurso exclusivo, que sólo puede ser reservado por un nodo. El nodo que intente reservarlo y no pueda entiende que debe abandonar el cluster y ceder sus servicios.

 

6.2. Soluciones de HA en entornos Linux

 

A continuación analizamos algunas soluciones que implementan mecanismos de alta disponibilidad en entornos Linux:

 

Heartbeat

 

Heartbeat es considerado como el estándar de facto de la alta disponibilidad en entornos Linux. Se engloba dentro del proyecto Linux-HA (Linux High Availability) y es ampliamente adoptado por miles de clusters en todo el mundo que proveen servicios críticos.

 

Heartbeat forma parte de la mayoría de las distribuciones Linux, si bien se trata de un software altamente portable que corre sin problemas en sistemas FreeBSD, Solaris, OpenBSD y MacOS/X. Cuenta con licencia GPL. Sus principales características son:

 

·        No hay limitación en el  número de nodos que puede monitorizar. Puede utilizarse para monitorizar desde clusters sencillos hasta clusters muy grandes.

 

·        Monitorización de recursos: los recursos pueden relanzarse o moverse a otro nodo en caso de fallo.

 

·        Dispone de sofisticadas políticas de gestión de recursos.

 

·        Permite definir distintas políticas en función del tiempo.

 

·        Incluye scripts para la gestión de recursos como BBDD, servidores web, filesystems, siendo fácil crear scripts personalizados para nuevo servicios.

 

LVS

 

LVS (Linux Virtual Server) permite crear clusters de balanceo de carga, en los que un nodo master se encarga de gestionar y repartir las conexiones entre varios nodos slave. LVS puede llegar a gestionar hasta 200 nodos slave.

 

Ldirectord es un daemon que se ejecuta en el nodo master LVS que se encarga de comprobar el servicio en los nodos slave y eliminarlos e insertarlos en el cluster dinámicamente.

 

En la práctica resulta un producto menos versátil que heartbeat.

 

Piranha

 

Es el nombre de la solución de RedHat basada en LVS, a la que se ha añadido una interfaz de usuario que facilita su configuración.

 

UltraMonkey

 

Es una variante de LVS creada por VA Linux que utiliza Heartbeat para ofrecer clusters de alta disponibilidad con balanceo de carga. En este tipo de clusters se añade un segundo nodo master para eliminar el SPOF de los clusters LVS.


SEGUNDA PARTE

DISEÑO E IMPLEMENTACIÓN

 

 


7. Estudio, análisis y diseño de una solución

 

Una vez explicados los distintos componentes que forman un cluster, estamos en disposición de revisar las especificaciones y concretar los requisitos de nuestro proyecto.

 

El análisis de los requisitos nos llevará a lo largo del proyecto a plantear varios diseños y arquitecturas[3] posibles para el nuevo cluster, que tras implementarlos y llevar a cabo las pertinentes pruebas de integración, estabilidad y rendimiento nos conducirán a la propuesta final.

 

7.1. Análisis del sistema inicial

 

En el apartado [2.1] hemos introducido los clusters existentes en el Departamento de LSI. A continuación realizaremos un análisis en profundidad de sus componentes y su funcionamiento.

 

El Departamento de LSI tiene tres clusters de computación. Cada uno de ellos era independiente de los otros, tanto a nivel físico como lógico. Se trata de tres clusters del mismo del mismo tipo, diferenciándose sólo en el número de nodos que lo conforman.

 

A nivel hardware, cada cluster está compuesto de una serie de máquinas (PCs enracables) conectados a una red privada mediante  un switch gigabit ethernet. Una de las máquinas está conectada a la red de LSI y a la red privada del cluster, sirviendo de puerta de acceso al mismo.

 

A nivel software todas las máquinas que pertenecen a un mismo cluster cuentan con el mismo sistema operativo y la misma imagen de kernel, requisito imprescindible al tratarse de máquinas con un sistema de clustering tipo SSI.

 

Cada máquina cuenta con uno o dos discos duros, en cuyo caso se configuran en modo RAID1[4], en los que se crea una partición para datos de usuario. Esta partición se exporta al resto de máquinas del cluster por NFS, de tal forma, que en cada nodo del cluster tenemos N zonas NFS montadas, una por cada una de las N máquinas que componen el cluster.

 

La figura [7.1] muestra el esquema de los clusters actuales, con un nodo de acceso y N máquinas dedicadas a cómputo y a servidor disco.

 

Los motivos que nos llevan a abandonar este modelo de cluster son los siguientes:

 

·        openMosix

 

o       No tiene ningún mecanismo de limitación de recursos: cualquier usuario puede, en un momento dado, lanzar tantos procesos como quiera y saturar un nodo o el cluster completo.

 

o       Presenta problemas con varios tipos de aplicaciones: el mecanismo de migración automática de openMosix no funciona con aplicaciones que hacen uso de threads o memoria compartida.

 

o       Estrechamente ligado al kernel: openMosix impone el kernel de los nodos, siendo el más reciente de la rama 2.4, sin soporte para el hardware de los nuevos nodos.

 

o       Proyecto cancelado el 1/4/2008.

 

 

 

 

Figura 7.1: Esquema de cluster openMosix de LSI

 

 

·        Sistema de zonas de disco NFS

 

o       N zonas: Cada usuario tiene tantas zonas como nodos hay en el cluster. Se hace difícil controlar dónde están los datos.

 

o       Fragmentación del espacio: no se aprovecha correctamente todo el espacio disponible.

 

o       Rendimiento de NFS: bajo situaciones de estrés con multitud de accesos concurrentes las zonas exportadas por NFS tienen un rendimiento mediocre.

 

7.2. Revisión de objetivos y requisitos  

 

Recordemos que este proyecto tiene dos objetivos:

 

  1. La implantación de un nuevo sistema de cluster para el Departamento de LSI.

 

  1. La creación de una documentación de referencia y administración para el Laboratorio de Cálculo de LSI.

 

Tras exponer los conceptos necesarios para entender el funcionamiento de las partes que conforman un cluster de computación, procedemos a realizar el análisis de los requisitos del nuevo sistema.

7.2.1. Requisitos funcionales                  

 

Veamos qué servicios debe prestar el nuevo cluster.

 

  • En primer lugar, el nuevo cluster debe ofrecer un servicio igual al que ofrece el sistema actual, es decir, debe ser capaz de procesar los trabajos de los usuarios y debe disponer de un espacio de disco para albergar sus datos y programas en un sistema de disco centralizado.

 

  • El middleware elegido debe ser personalizable a nivel de gestión de colas, proyectos, grupos de usuarios, etc.

 

  • Además debe contar con un software de gestión de imágenes de sistema que permita instalar y modificar fácilmente el sistema en los nodos que la componen, de forma que la instalación y posterior mantenimiento de los nodos (más de 50) sea asumible.

 

  • El cluster debe ser monitorizable, es decir, el administrador debe tener las herramientas necesarias para controlar el estado de sus componentes y percatarse de cualquier fallo.

 

7.2.2. Requisitos no funcionales   

 

  • El nuevo cluster también debe cumplir ciertos requerimientos de eficacia y seguridad. Concretamente debe ser capaz de soportar una mayor carga de trabajo y debe ser capaz de mantener el servicio a pesar del fallo de cualquiera de sus componentes.

 

  • Como hemos comentado, el número de usuarios de los clusters ha crecido considerablemente los últimos años y con ellos el volumen de trabajo que el cluster debe procesar. El nuevo sistema debe ser capaz de procesar el volumen actual y futuro de trabajo haciendo uso del hardware disponible. En este sentido, el aumento del volumen de trabajo por encima de cierto umbral nunca debe llevar a un fallo en el cluster.

 

  • El incremento del número de usuarios trae consigo una mayor necesidad de capacidad de almacenamiento de datos. El nuevo cluster debe contar con un sistema rápido, no fragmentado, transparente y escalable, que pueda crecer cuando sea necesario.

 

  • Se establece una batería de pruebas o benchmarks (ver apartado  [19.3]) encaminados a probar la estabilidad, el rendimiento y la usabilidad de los sistemas propuestos.

 

7.3. El nuevo cluster

 

Una vez introducidos los conceptos necesarios y descritos los distintos componentes del nuevo sistema estamos en disposición de explicitar y analizar la solución propuesta.

 

En primer lugar describiremos el sistema base, es decir, la infraestructura hardware y software que sustentará el sistema de clustering. Los siguientes puntos detallarán cada uno de los componentes y servicios un cluster de computación.

7.3.1. El sistema base

 

Uno de los requerimientos no funcionales del proyecto es que debemos reutilizar el hardware que conforman los tres clusters existentes.

 

Contamos, inicialmente, con el hardware de los tres clusters de LSI:

 

·        20 nodos de eixam

·        10 nodos de tenada

·        10 nodos de nozomi

·        1 switch 3Com gigabit de 48 puertos

·        2 switches 3Com gigabit de 16 puertos

·        3 Multiplexadores de puertos KVM

 

Además de estos nodos, cada grupo había comprado nodos que aún no habían sido instalados porque su hardware no era compatible con el kernel de openMosix:

 

 

·        6 nodos de eixam

·        4 nodos de tenada

·        6 nodos de nozomi

 

Algunos de estos nodos cuentan con discos de gran capacidad (750GB) que utilizaremos para crear el filesystem distribuido.

 

 

CPD1.jpg

 

Figura 7.2: El CPD de UPC en el edificio Omega

 

 

El nuevo cluster estará ubicado en el CPD de UPC (Edificio Omega en el Campus Nord), donde se encuentran todos los servidores del Departamento de LSI. Por cuestiones de limitación de espacio llegamos a un acuerdo con los responsables de los clusters para liberar espacio retirando las máquinas más obsoletas. Se retiran máquinas Pentium IV con chasis de 2U, que además son poco eficientes desde el punto de vista energético.

 

Los nodos de entrada de los tres clusters antiguos también se retiraron. Se trata de máquinas  menos potentes  ya que, por la naturaleza descentralizada de openMosix, su única función era proveer acceso a la red del cluster.

 

Además se llega al acuerdo con los distintos grupos de investigación de comprar dos máquinas que correrán los servicios principales  del cluster, que proporcionarán alta disponibilidad y servirán como punto de entrada al cluster. Ambos servidores son idénticos, y cuentan con las siguientes características:

 

  • Dell PowerEdge R200
  • Procesador Intel Xeon E3110 a 3 Ghz, 6 MB de cache
  • 8 GB de memoria RAM
  • 2 tarjetas de red gigabyte Ethernet
  • 2 discos SAS de 450 GB
  • Chasis enrackable de 1U

 

Todos los nodos cuentan con sistema operativo Linux Debian. La elección de esta distribución viene dada por ser el sistema operativo utilizado en todos los servidores y estaciones de trabajo Linux del Departamento de LSI. Debian es una distribución con gran tradición dentro del mundo Linux, estable, con un repositorio de software importante y muy enfocado hacia el segmento de los servidores. Concretamente se ha escogido la versión Etch por ser la versión estable en el momento de desarrollar este proyecto.

 

La instalación del sistema operativo es igual en todas las máquinas, con la única diferencia de los servicios que ejecutan, que se personalizan mediante scripts creados a tal efecto.

 

Siempre que ha sido posible se ha instalado el software vía el repositorio oficial de Debian. El listado completo de los paquetes instalados puede encontrarse en los apéndices [19.1.34].

7.3.2. Sistema de pruebas

 

A excepción de las máquinas compradas más recientemente, que no pueden correr openMosix, el resto del hardware pertenece a alguno de los tres clusters existentes. Así pues, para hacer las pruebas de los distintos subsistemas del nuevo cluster crearemos una réplica a escala de lo que será el futuro cluster. El diseño modular nos permitirá abstraernos del número y tipo de máquinas instaladas.

 

El cluster de pruebas está formado por:

 

  • 16 nodos Dell con procesadores Intel Xeon de doble o cuádrule núcleo y 4 u 8 GB de memoria RAM.
  • 1 switch 3Com gigabit de 16 puertos
  • 1 multiplexador de puertos KVM

 

7.3.3. Software de clustering

 

Como sistema de gestión para el nuevo cluster hemos elegido Sun Grid Engine, que es quizás el sistema de colas más utilizado, tanto en ámbitos empresariales como en centros de investigación.

 

Se trata de un producto estable, maduro, con gran tradición dentro del ámbito de la supercomputación y que cuenta con una numerosísima comunidad de usuarios y administradores. Se trata, en fin, de uno de los proyectos de clustering más vivos que además es de código abierto.

7.3.4. Sistema de ficheros

 

Nuestra primera opción como filesystem fue Lustre, de SunMicrosystems. Se trata del sistema de ficheros distribuido paralelo más potente y escalable disponible y se adapta perfectamente a entornos de clustering. Como veremos, las peculiaridades y limitaciones de nuestro hardware harán que el filesystem no rinda como se esperaba y nos veremos obligados a revisar nuestra elección. El overhead del sistema software de sincronización de discos castiga el rendimiento en exceso, motivo por el que desechamos Lustre en nuestra solución. Más adelante se explica con detenimiento los problemas que nos encontramos.

 

La segunda opción fue GlusterFS, un filesystem más modesto, no tan escalable pero que en entornos medianos como el nuestro, y con hardware no tan dedicado, puede dar un rendimiento adecuado.

7.3.5. Alta disponibilidad

 

Como software de alta disponibilidad elegimos Heartbeat, que forma parte del proyecto Linux-HA y que es el sistema de alta disponibilidad más extendido en el mundo Linux.

 

Se trata de un sistema de monitorización sencillo capaz de comprobar el status de dos hosts unidos por una conexión dedicada. Su funcionamiento es simple: si la conexión de uno de los hosts se interrumpe, el host que queda en funcionamiento toma el control de los servicios que han caído.

 

Este mecanismo de monitorización nos proporcionará alta disponibilidad de los servicios de clustering y de sistema de ficheros, protegiéndonos ante el fallo de uno de los nodos master o de cualquiera de los nodos servidores de disco.

7.3.6. Sistema de imágenes

 

Desde que pusimos en marcha el primer cluster, vimos que era necesario disponer de un sistema de replicación de imágenes de sistema que permitiese automatizar la gestión del software de las máquinas del cluster. Instalar un nodo manualmente es un proceso tedioso que consume un tiempo, instalar N nodos de esta forma no es práctico. La elección en su día fue Rembo. Se trata de un software que permite una gran personalización de las imágenes gracias a su sistema de scripts y con un amplio soporte de tarjetas ethernet. Además contamos con licencia de campus UPC.

 

En 2006 IBM adquirió Rembo, incorporándolo dentro de su suite Tivoli. Dadas las buenas experiencias obtenidas con Rembo nos decidimos a utilizar Tivoli, que también cuenta con licencia UPC.

7.3.7. Sistema de Monitorización

 

El interés de monitorización es doble. Por una parte queremos un sistema que nos informe del estatus del cluster y que sea capaz de aglutinar toda la información generada por la gran cantidad de elementos que lo conforman. La información mostrada debe adaptarse tanto a las necesidades de los administradores del sistema como a los usuarios. En este sentido ganglia proporciona un interfaz web perfectamente adaptado a la idiosincrasia de los clusters, y que con algunas modificaciones se adapta perfectamente a nuestra infraestructura.

 

Por otra parte, como administradores de sistemas, necesitamos saber el estatus de los componentes del cluster. De poco sirve tener un sistema de alta disponibilidad con dos hosts si al caer uno de ellos no somos informados. En el Laboratorio de Cálculo todos los servicios críticos se monitorizan con el sistema operativo (so), así que lo que haremos será incluir los servicios del cluster dentro del sistema de monitorización nagios de LCLSI.

7.3.8. Servicios auxiliares

 

Además de los componentes propios del cluster, son necesarios una serie de servicios complementarios para el correcto funcionamiento del sistema. Servicios como:

 

·        Servicio de nombres, que se encarga de la correspondencia entre las direcciones IPs de los nodos y sus nombres.

 

·        Servicio de correo, que permite la gestión de los emails administrativos generados por los nodos de computación dentro de SunGrid.

 

·        Servicio de tiempo. Configuraremos nuestro propio servidor de tiempo que mantendrá la hora de todos los nodos sincronizada.

 

·        Servicio de backup. Incorporamos el espacio de disco compartido del cluster al sistema de backups departamentales.

 


8. Implementación

 

 

Una vez diseñado el nuevo sistema, describiremos la implementación del diseño propuesto.

 

Primero nos centraremos en el proceso de instalación y configuración de cada uno de los servicios que conformarán el Cluster:

 

·        Lustre o GlusterFS como sistema de ficheros.

·        SunGrid como sistema de clustering.

·        Heratbeat como sistema de alta disponibilidad.

·        Tivoli como sistema de replicación de imágenes.

·        Ganglia y Nagios como sistemas de monitorización.

·        Otros servicios (DHCP, correo, tiempo, etc).

 

Cabe notar que tanto en la instalación como en la configuración de cada uno de estos componentes seguiremos una serie de reglas:

 

·        Siempre que sea posible utilizaremos el software proporcionado por el sistema operativo, lo que nos permitirá mantener el software actualizado fácilmente.

 

·        Todo el software adicional común se instalará en un directorio dentro de /usr/local, accesible en cada nodo para todos los usuarios.

 

·        Los distintos componentes del cluster se instalarán de forma independiente y lo más aislados posibles del resto del sistema operativo. Esto nos permitirá actuar en cada uno de ellos sin afectar al resto.

 

·        Se tratará de independizar el cluster, en la medida de lo posible, del resto de servicios del Departamento, lo que nos proporcionará una robustez añadida.

 


9. Lustre

 

9.1. Arquitectura propuesta (versión 1.0)

 

Uno de los objetivos del nuevo cluster es proporcionar  a los usuarios un espacio de disco unificado, solucionando el problema de zonas de usuario fragmentadas en el modelo de los clusters anteriores. En este volumen único, que será visible desde todos los nodos del cluster, los usuarios guardarán sus programas, datos, salidas de procesos, etc.

 

Todas las máquinas del cluster cuentan con un espacio de disco libre que va desde los 60 GB en las máquinas más antiguas con discos de 80 GB hasta más de 700 GB en las máquinas más modernas. El espacio total resultante de sumar todos estos volúmenes da como resultado una cantidad de disco considerable.

 

Lustre como sistema de ficheros paralelo permite crear un volumen unificado a partir de diferentes espacios de disco heterogéneo accesible por conexiones TCP/IP. Estos espacios de disco pueden ser NAS, SAN o, como en nuestro caso, hosts con discos locales.

 

Un sistema Lustre cuenta con tres unidades funcionales principales:

 

1.      Un metadata target (MDT) por filesystem que almacena metadatos, como nombres de ficheros, directorios, permisos y file layout en el metadata server (MDS).

 

2.      Uno o más object store targets (OSTs) que guardan los datos de los ficheros en uno o más object storage servers (OSSs). Dependiendo del hardware de los servidores, un OSS normalmente sirve entre dos y ocho targets, con cada target un sistema de ficheros en disco local con hasta 8 terabytyes de tamaño. La capacidad de un sistema Lustre es la suma de las capacidades de los targets.

 

3.      Cliente(s) que acceden y usan los datos.

 

MDT, OST y cliente pueden estar en distintos nodos o en el mismo. En general estas funciones se separan en nodos distintos, de dos a cuatro OSTs por nodo OSS. Lustre soporta varios tipos de redes, incluyendo Infiniband, TCP/IP en ethernet, Myrinet, Quadrics y otras tecnologías propietarias.

 

El MDT y los OSTs pueden contar con un nodo configurado como failover que es capaz de acceder a sus datos en caso de que el nodo servidor falle.

 

La figura [4.2] en el apartado [4.3.2] muestra el esquema de un cluster Lustre complejo, con diversos OSSs con OSTs albergados en SANs, sistemas de failover, etc.

 

La alta disponibilidad es uno de los objetivos que nos hemos marcado a la hora de diseñar el nuevo espacio de disco. Aprovechando las facilidades que proporciona Lustre, dotaremos de alta disponibilidad tanto al MDT como a los distintos OSTs. En nuestro caso esto implica tener dos hosts sirviendo el MDT y otros dos por cada OST. El segundo host, configurado como failover, debe ver el mismo disco que el host primario para ser capaz, en caso de fallo de éste, de tomar el control y continuar sirviendo disco.

 

Lo más habitual en sistemas de alto rendimiento es disponer de un SAN (Storage Area Network) conectado a dos hosts. El SAN en estos casos cuenta con varias controladoras que permiten su conexión a distintos hosts. Los hosts se configuran como primary y failover. El nodo primary es el que sirve el disco a la zona Lustre. En caso de caída del nodo primary, Lustre se dará cuenta y automáticamente comenzará a utilizar el nodo failover.

 

En nuestro caso utilizaremos los discos locales de las máquinas como espacio de disco compartido. Agruparemos las máquinas del cluster  por parejas. Habrá una pareja que sirva el MDT y el resto de parejas servirán OSTs. La Suma del espacio de los OSTs dará como resultado el espacio total del disco. Las máquinas que conforman una pareja deben contar con discos del mismo tamaño.

 

drbd-sepinterface

Figura 9.1: Esquema de dos hosts con replicación de datos vía conexión de red dedicada

 

 

Cada uno de los hosts tienen acceso solamente a su disco local, y Lustre sólo "habla" con el host que actúa como primario. Es necesario algún mecanismo adicional que replique los datos que se escriben en el host primario al failover. Es más, esos datos deben mantenerse estrictamente sincronizados para evitar problemas de incoherencia de datos. En este sentido DRBD (Distributed Replicated Block Device) nos proporciona un mecanismo transparente de replicación de bloques entre dispositivos, particiones de discos duros en este caso, que se encuentran en hosts conectados por red. Algunas características de DRBD son:

           

·        Trabaja en tiempo real. La replicación de datos es continua, mientras las aplicaciones modifican el contenido del dispositivo.

 

·        Es transparente. Las aplicaciones que trabajan en el dispositivo replicado no son conscientes de que los datos están en varios servidores.

 

·        La replicación puede ser síncrona o asíncona.  Trabajando de forma síncrona, las escrituras por parte de aplicaciones se consideran finalizadas sólo cuando la escritura se ha realizado en los dos servidores que conforman el dispositivo replicado. La replicación asíncrona implica que las escrituras se consideran finalizadas cuando se han completado de forma local, antes de que se hayan propagado al peer.

 

Dos hosts compartiendo un dispositivo de bloques DRBD juegan roles primary y secondary. El host primary  es el host que monta el dispositivo DRBD y es sobre su disco físico local sobre el que se realizan las lecturas. Las escrituras se realizan en primer lugar en el disco del host primary y posteriormente en el host secondary. En nuestro caso configuraremos DRBD en modo síncrono, de tal forma que una escritura no se considerará realizada hasta que no se haya realizado en los discos de los hosts primary y secondary.

 

Los roles primary y secondary se corresponden con los roles primary y failover de Lustre.

 

 

Figura 9.2: Arquitectura del cluster con Lustre (versión 1.0)

 

 

La replicación de datos entre parejas de hosts se realizará utilizando una conexión de red dedicada, tal y como se muestra en la figura [9.2]. Todos los nodos del cluster cuentan con al menos 2 interfaces de red gigabit ethernet. La interconexión de los hosts de cada pareja mediante una conexión de este tipo permite que la sincronización de datos se realice de forma óptima, sin ocupar el ancho de banda de la red privada del cluster.

 

Como hemos comentado anteriormente, Lustre es capaz de detectar el fallo de un servidor, ya sea de un MDT o de un OST, y utilizar en su lugar un host configurado como failover. En el caso por ejemplo de un OST formado por dos hosts en configuración failover sirviendo el disco de un SAN, si fallase el host primary, el host failover tendría acceso de forma "automática" al SAN y Lustre pasaría a comunicarse con él. En nuestro caso, con las zonas replicadas con DRBD, necesitamos un mecanismo extra que nos permita detectar el fallo del host primary y que, en caso de fallo, configure el host seconday como primary y monte la zona DRBD. Heartbeat, tratado en el capítulo [12], permite monitorizar el estatus de servicios de alta disponibilidad y ejecutar scripts que los activen/desactiven.

 

9.2. Instalación (versión 1.0)

9.2.1.  DRBD

 

La funcionalidad principal de DRBD está implementada como módulo del kernel. Concretamente, DRBD proporciona un driver para un dispositivo de bloques especial.

La última versión disponible es la 8.2.6, que podemos descargar de la url:

 

http://oss.linbit.com/drbd/8.2/drbd-8.2.6.tar.gz

 

Como con todo el software que instalamos y que no viene con la distribución de software del sistema operativo, dejamos copia en /root/files.

Compilamos e instalamos el software:

 

master-cluster1> tar xvfz drbd-8.2.6.tar.gz

master-cluster1> cd drbd-8.2.6/drbd

master-cluster1> make && make install

 

El módulo de kernel queda instalado en el directorio correspondiente a dispositivos de bloques en /lib/modules y las utilidades de administración en /sbin.

 

Comprobamos que el módulo carga correctamente:

 

master-cluster1> modprobe drbd

 

El siguiente mensaje indica que el módulo se ha cargado:

 

drbd: initialised. Version: 8.2.6 (api:88/proto:86-88)

 

Para automatizar el proceso de carga del módulo drbd al iniciar el sistema, lo incluimos en el fichero /etc/modules.

 

 

 

9.2.2. Lustre

 

Lustre está dividido en tres partes:

 

  1. Parches de kernel
  2. Módulo de kernel
  3. Utilidades de espacio de usuario

 

El primer paso es disponer de un kernel con los parches necesarios para Lustre. Sun nos ofrece la posibilidad de instalar alguno de sus kernels precompilados o  modificar nuestro kernel con sus parches. En nuestro caso preferimos adecuar nuestro kernel3 (2.6.18-5) a Lustre en lugar de instalar un nuevo kernel, la cual  cosa nos dará más juego en caso de tener que realizar futuros ajustes en el mismo.

 

El software necesario está disponible en la web de Sun:

 

https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_SMI-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=LUSTRE-1651-G-F@CDS-CDS_SMI

 

Como queremos parchear nuestro propio kernel, seleccionamos la plataforma Source y descargamos el fichero "Lustre source code - lustre-1.6.5.1.tar.gz".

 

Descomprimimos el código fuente de Lustre:

 

master-cluster1> tar xvfz lustre-1.6.5.1.tar.gz -C /tmp

 

Los parches Lustre se instalan con la herramienta de gestión de parches quilt. La instalamos:

 

master-cluster1> apt-get install quilt

 

Copiamos el fichero con la configuración del kernel[5] (versión 2.6.18) en nuestra estructura de kernel:

 

master-cluster1> cp lustre/kernel_patches/kernel_configs/kernel-2.6.18-2.6-vanilla-i686.config /usr/src/linux/

 

Creamos sendos soft-links que utilizará quilt para parchear nuestro kernel:

 

master-cluster1> cd /usr/src/linux

master-cluster1> ln -s /tmp/lustre-

1.6.5.1/lustre/kernel_patches/series/2.6.18-vanilla.series series

master-cluster1> ln -s /tmp/lustre-1.6.5.1/lustre/kernel_patches/patches patches

 

Ahora aplicamos los parches indicados en el fichero series:

 

master-cluster1> quilt push -av

 

Una vez aplicados los parches debemos recompilar el kernel:

 

master-cluster1> make && make modules_install

 

Generamos el ramdisk del kernel que acabamos de compilar:

 

master-cluster1> mkinitramfs -o /boot/linux-2.6.18-lustre-1.6.5.1

 

Por último hacemos este sea el kernel de arranque por defecto. Añadimos una nueva entrada en el gestor de arranque GRUB. El fichero de configuración /boot/grub/menu.lst puede encontrarse en los apéndices [19.1.1].

 

Rebotamos la máquina y comprobamos que el nuevo kernel se carga correctamente y que todos los dispositivos se reconocen.

 

El siguiente paso es compilar el módulo Lustre y las utilidades de gestión:

 

master-cluster1> cd/tmp/lustre-1.6.5.1

master-cluster1> ./configure --prefix=/

master-cluster1> make && make install

 

Para hacer que el módulo Lustre se cargue automáticamente, creamos un fichero lustre en /etc/modutils con el fin de que la herramienta update-modules cree la información necesaria en /etc/modules.conf:

 

options lnet networks="tcp"

options ost oss_num_threads=4

options mds mds_num_threads=10

 

En este fichero debemos indicar el tipo de red que utilizará lnet para comunicar los hosts Lustre:

 

options lnet networks="tcp"

 

Para comprobar que el fichero modules.conf incluye correctamente la información de los módulos Lustre ejecutamos el comando update-modules, que se ejecuta cada vez que se inicia el sistema:

 

master-cluster1> update-modules.modutils

 

9.3. Configuración (versión 1.0)

9.3.1. Consideraciones previas

 

Una vez instalado el módulo de kernel y las utilidades, debemos configurar el recurso DRBD. En primer lugar, debemos asegurarnos de que la replicación se realizará sobre dispositivos de idéntico tamaño. El sistema de distribución de imágenes Tivoli junto con el script de personalización de imagen nos asegura contar con parejas de nodos con una partición home del mismo tamaño (ver capítulo [13]).

 

También contamos con un interfaz de red dedicado a la sincronización de datos del dispositivo DRBD. El script de personalización de sistema se encarga de configurar este interfaz en cada máquina asignándole la dirección IP correspondiente según juegue el rol primary o secondary.

9.3.2. DRBD

 

La configuración de DRBD reside en /etc/drbd.conf. Este fichero cuenta con varias secciones a configurar: global, common y resources, en las que se definen los recursos a replicar. Este fichero puede encontrarse en los apéndices [19.1.2].

 

En la sección resource definimos un recurso denominado r0 que está formado por la partición RAID1 /dev/md2 de los nodos 1 y 2. La comunicación entre los nodos se establece por el interfaz dedicado y el puerto especificado.

 

Tras configurar el recurso correctamente, procedemos a crear e inicializar el dispositivo drbd. Para ello, debemos seguir los siguientes pasos en todos los nodos:

 

1.      Creamos el dispositivo:

 

nodei> drbdadm create-md r0

 

2.      Asociamos el recurso DRBD con su dispositivo físico:

 

nodei> drbdadm attach r0

 

3.      Conectamos el recurso DRBD con su compañero:

 

nodei> drbdadm connect r0

 

Comprobamos en /proc/drbd el estatus del recurso r0:

 

nodei> cat /proc/drbd

version: 8.2.4 (api:88/proto:86-88)GIT-hash: fc00c6e00a1b6039bfcebe37afa3e7e28dbd92fa build by buildsystem@linbit, 2008-01-11 12:44:36

 0: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent C r---

    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0

        resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0

        act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0

 

Como vemos en los logs ambos dispositivos del recuso están configurados como secondary. El siguiente paso establece el nodo que jugará el rol de primary en la pareja DRBD e inicia la sincronización entre ellos. Debe ejecutarse sólamente en los nodos primary:

 

nodei> dbdadm -- --overwrite-data-of-peer primary r0

 

 

Tras ejecutar este comando comienza la sincronización, que puede ser monitorizada vía /proc/drbd:

 

nodei> cat /proc/drbd

version: 8.2.6 (api:88/proto:86-88)

GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by root@master-cluster1, 2008-10-01 10:56:55

 1: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---

ns:14596512 nr:0 dw:14351652 dr:887881 al:59 bm:39 lo:0 pe:0 ua:0 ap:0 oos:0

 

Después de ejecutar este comando el dispositivo drbd ya es completamente funcional, eso sí, con un rendimiento reducido mientras dura la sincronización. El siguiente paso es formatear el dispositivo para crear el filesystem; en nuestro caso Lustre.

9.3.3. Lustre

 

Debido al requisito de alta disponibilidad en todos los puntos del filesystem, el MDT estará formado por dos MDS, master-cluster1 y master-cluster2.

 

En primer lugar formateamos el MDT desde el MDS activo (master-cluster1):

 

master-cluster1> mkfs.lustre --fsname=lustrefs --mdt --mgs --failnode=master-cluster2 /dev/drbd0

 

Una vez la zona está formateada, montamos la zona MDT:

 

mastercluster1> mount -t lustre /dev/drbd0 /mnt/lustrefs/mdt

 

Para cada uno de los 7 OSTs procedemos de forma análoga. En primer lugar formateamos el dispositivo DRBD de los nodos primary (node1, node3, node5 y node7) y posteriormente montaremos la zona:

 

nodei> mkfs.lustre --fsname=lustrefs --mgsnode=master-cluster1,master-cluster2 --ost --failnode=node2 /dev/drbd0

nodei> mount -t lustre /dev/drbd0 /mnt/lustrefs/ost

 

Cada vez que se monta un nuevo OST, el MDT lo reconoce como propio (mismo fsname) y lo agrega al filesystem. Desde el momento que formateamos el primer OST estamos en disposición de montar la zona lustre en los nodos cliente.

 

9.4. Pruebas (versión 1.0)

 

Una vez nuestro filesystem paralelo es funcional, procedemos a realizar las pruebas pertinentes, tal y como está descritas en el apartado [19.3].


9.4.1. Test de estabilidad

 

Durante la fase de pruebas del filesystem nos encontramos con importantes problemas de estabilidad que provocaban la pérdida del control sobre el filesystem, obligando a reiniciar los servicios Lustre, y en ocasiones la totalidad del sistema a las 24 horas aproximadamente de funcionamiento intensivo.

 

Los problemas eran fácilmente reproducibles mediante el acceso concurrente de lectura y escritura a los datos por parte de varias decenas de procesos. Iniciada la situación de estrés era cuestión de horas que el filesystem se quedase inestable.

 

Probamos varias versiones de kernel y de utilidades Lustre, pero el problema persistía. Finalmente, tras consultar extensivamente los foros oficiales, encontramos un artículo sobre Lustre que indicaba que la combinación servidor OST y cliente en un mismo nodo no es una configuración estable. Los nodos cliente, que montan el filesystem, no pueden realizar funciones de OSS.

 

Esto nos hizo  replantearnos la arquitectura de nuestro sistema de pruebas, puesto que la estabilidad es un requisito fundamental.

 

Por otra parte como pudimos comprobar, el hecho de disponer los nodos de computación como máquinas servidoras de disco Lustre, añade un overhead de uso de CPU, memoria y red que perjudicaría el rendimiento del trabajo de los usuarios en un entorno de computación.

 

9.5. Revisión de la arquitectura (versión 1.1)

 

Los graves problemas de estabilidad descritos en el apartado anterior nos obligan a replantearnos la arquitectura de nuestro filesystem paralelo. Los nodos servidores de disco deben ser nodos dedicados.

 

A tal efecto configuramos seis máquinas provenientes del antiguo cluster eixam que iban a ser retiradas. Se trata de máquinas con unos 5 años de antigüedad, con prestaciones a nivel de cómputo muy inferiores a las últimas adquiridas, pero que pueden jugar un papel correcto como servidoras de disco.

 

Las seis máquinas son idénticas y cuentan con las siguientes características:

 

·        Procesador: Intel Pentium IV 3.0 Ghz

·        Memoria: 4 GB RAM

·        Disco: 2 discos SATA de 750 GBytes

·        Red: 2 tarjetas de red gigabyte Ethernet

·        Chasis: Enracable 2U

 

Así pues todos los nodos con los que contábamos anteriormente dejan de servir disco y pasan a ser exclusivamente clientes de la zona de disco paralela formada por las 6 máquinas dedicadas.

 

El nuevo modelo se muestra en la figura [9.3].

 

 

 

Figura 9.3: Arquitectura revisada del cluster con Lustre  (versión 1.1)

 

9.6. Pruebas del nuevo modelo (versión 1.1)

9.6.1. Test de estabilidad

 

Una vez separados los nodos servidores de disco de los nodos cliente, los problemas de estabilidad desaparecieron. El nuevo modelo se mostró estable ejecutando el test de estrés por periodos de tiempo de una semana. De esta forma pudimos centrarnos en las pruebas de rendimiento y usabilidad.

9.6.2. Pruebas de rendimiento

 

Las pruebas de rendimiento se basaron, por una parte, en una serie de tests sintéticos de rendimiento teórico, que nos proporcionaría el rendimiento pico máximo. Por otra parte realizamos pruebas de estrés basadas en la ejecución masiva de procesos con lecturas y escrituras concurrentes. Los detalles de las distintas pruebas de rendimiento se explican en el apartado [19.3.2].

 

9.6.2.1. Throughput máximo

 

En primer lugar mostramos el throughput máximo arrojado por la pruebas de lecturas y escrituras sobre el filesystem Lustre:

 

 

Número de instancias

MB/s en lectura

MB/s en escritura

1

45.5

18.7

2

90.3

36.1

3

135.1

54.2

4

133.0

49.5

5

129.2

46.4

 

 

Como era de esperar las pruebas de rendimiento con Lustre arrojan resultados muy buenos, superando a partir de 2 instancias concurrentes el rendimiento de un disco local. El througput escala linealmente con el número de OSTs. Dado que disponemos de 3 OSTs las lecturas y escrituras se realizan en 3 nodos (parejas de nodos) en paralelo.

 

 

Lecturas

 

 

 

Escrituras

 

Figura 9.4: Throughput de lectura y escritura del filesystem Lustre

 

 

Podemos estimar que el máximo throughput teórico sería la velocidad de  un OST multiplicado por el número de OSTs, que en nuestro caso serían 135.5 MB/s para las lecturas y 56.1 MB/s para las escrituras. Como podemos ver, los resultados con distintas concurrencias se aproximan a los máximos teóricos, confirmando la excelente escalabilidad de Lustre.

 

Las escrituras están penalizadas, sin duda alguna, por el sistema de replicación utilizado. Recordemos que los datos escritos en un OST se envían al nodo primary y éste los reenvía a su vez al nodo secondary de forma síncrona mediante DRBD. De todas formas las tasas de escritura son más que correctas y superan con creces las que puede ofrecer un sistema tipo NFS.

 

9.6.2.2. Test ad-hoc

 

El siguiente test consiste en la ejecución concurrente de procesos con un alto uso de E/S. La descripción de la batería de pruebas puede consultarse en los apéndices [19.3.2.2].

 

A continuación mostramos los resultados obtenidos correspondientes a ejecutar un determinado número de procesos de lectura:

 

 

Concurrencia

Tiempo

Throughput agregado (MB/s)

MB/s por proceso

1

47.0’’

104.5

104.5

2

47.6”

206.4

103.2

3

48.5”

303.9

101.3

6

1’ 38”

300.0

50.0

9

2’ 32”

292.5

32.5

18

5’ 37”

264.3

14.6

36

12’ 14”

215.2

5.9

 

 

Las cifras de throughput agregado demuestran la alta escalabilidad del filesystem Lustre. Dado que contamos con 3 OSTs el rendimiento máximo esperado seria de 104.5 * 3 = 313.5 MB/s. Cuando la concurencia aumenta  las cifras de throughput agregado se siguen manteniendo bastante estables.

 

 

Throughput agregado

 

 

 

Throughput por proceso

 

Figura 9.5: Throughput del filesystem Lustre en lecturas

 

 

Las pruebas de escritura arrojan los siguientes resultados:

 

 

Concurrencia

Tiempo

Throughput agregado (MB/s)

MB/s por proceso

1

3’ 11’’

19.0

19.0

2

4’ 25”

37.3

18.6

3

4’ 30”

54.7

18.2

6

6’ 12’’

52.3

8.71

9

14’ 19”

51.5

5.72

18

29’ 40’’

49.7

2.76

36

1h 3’

46.8

1.3

 

 

De nuevo tenemos resultados muy estables a lo largo de todas las pruebas. El throughput agregado se mantiene estable cerca del máximo teórico, limitado por el sistema de replicación DRBD.

 

 

Throughput agregado

 

 

 

Throughput por proceso

 

Figura 9.6: Throughput del filesystem Lustre en escrituras

 

9.6.3. Pruebas de usabilidad

 

Por último las pruebas de usabilidad sirvieron para medir el grado de interactividad de los usuarios con la zona de disco compartido mientras el sistema estaba sometido a distintos niveles de carga de trabajo.

 

El uso conjunto del sistema de replicación de bloques DRBD y Lustre hacen crecer el tiempo de proceso y la latencia de ciertas llamadas al sistema sobre ficheros a niveles no asumibles.

 

Concretamente, un sistema como el nuestro sometido a una carga de 36 procesos simultáneos leyendo y escribiendo, tarda del orden de 10 segundos en procesar el comando ls sobre la zona compartida y entre 10 y 20 segundos en hacer un close de un fichero.

 

Esta falta de interactividad nos lleva a desechar la solución Lustre+DRBD. De todas maneras, en caso de incorporar algún día un SAN al cluster, liberados de la necesidad de utilizar DRBD, volveríamos a evaluar la posibilidad de utilizar Lustre como filesystem. Esta mejora se ha planteado en el apartado [18.3.3].

 

 


10. GlusterFS

 

10.1. Arquitectura propuesta (versión 2.0)

 

Los problemas de rendimiento de la solución Lustre + DRBD nos obligaron a revisar nuestra elección de filesystem. Tras analizar varias opciones nos decantamos por GlusterFS, por tratarse de un sistema de ficheros paralelo con una característica muy interesante: AFR (Automatic File Replication). Así como Lustre es un filesystem de un rendimiento y una escalabilidad de primer nivel, la inclusión del sistema de replicación de bloques DRBD hacía que el filesystem en su conjunto adoleciese de latencias altas en escenarios de estrés de disco y en operaciones de apertura/cierre de fichero.

 

 

Figura 10.1: Arquitectura del cluster con GlusterFS (versión 2.0)

 

 

AFR es un translator que permite que un brick[6] o unidad de almacenamiento esté compuesto por más de un disco (en hosts distintos, por supuesto). La replicación de datos se hace de forma transparente, iniciada por los nodos clientes, que configurando volúmenes AFR, indican de forma explícita sobre qué nodos se va a realizar la replicación de datos.

 

Los datos se escriben a la vez en los dos nodos que conforman un AFR, al contrario de lo que sucedía con DRBD, donde los datos se enviaban al nodo primario y este los reenviaba al secundario.

 

GlusterFS tiene la misma limitación que Lustre en cuanto a montar el filesystem en un host servidor de disco. Los problemas de estabilidad nos llevan a decantarnos una vez más por una solución con nodos dedicados a servir disco, similar al modelo de cluster versión 1.1.

 

Con este fin, al igual que en la revisión del sistema Lustre, contamos con 6 máquinas dedicadas en exclusiva a servir disco. La figura [10.1] muestra el esquema del cluster con GlusterFS (versión 2.0).

 

Además de las máquinas servidoras de disco, GlustrerFS necesita una máquina que se encargue de almacenar el namespace del filesystem. Guardaremos el namespace en las máquinas master-cluster, replicado utilizando AFR.

 

Las máquinas servidoras de disco se agruparán por parejas, replicando por AFR la zona de disco que exportan. Los nodos clientes configurarán el filesystem global unificando el sumatorio de las tres zonas AFR y utilizando el namespace del AFR de las máquinas master-cluster.

 

10.2. Instalación (versión 2.0)

 

Obtenemos la última versión[7] de GlusterFS de su web:

 

http://ftp.zresearch.com/pub/gluster/glusterfs/CURRENT/

 

Descomprimimos y compilamos el código fuente:

 

master-cluster1> tar xfz glusterfs-1.3.9.tar.gz -C /tmp

 

master-cluster1> cd /tmp

 

master-cluster1> ./configure --prefix=/

 

master-cluster1> make && make install

 

Las utilidades quedan instaladas en /sbin, los ficheros de configuración en /etc y los logs en /var/log/glusterfs.

 

GlusterFS utiliza FUSE (Filesystem in Userspace) para montar las zonas, por lo que es necesario contar con soporte en el kernel. La configuración por defecto de Debian soporta FUSE, por lo que no son necesarias instalaciones adicionales.

10.3. Configuración (versión 2.0)

10.3.1 Servidores

 

Cada uno de los seis nodos servidores de disco cuenta con dos discos de 750 GB, que tras instalar sistema y swap nos dejan una partición  exportable de unos 700GB. Lo habitual en nuestros servidores es utilizar una configuración RAID1 que permita el fallo de un disco sin pérdida de datos. En el caso del sistema GlusterFS con AFR los datos de cada nodo ya están replicados en su peer, por lo que optamos por una configuración RAID0[8]. De esta manera no se pierde espacio y el acceso al volumen resultante es más rápido.

 

Creamos el raid en cada nodo servidor:

 

node1> mdadm --create /dev/md2 --level=0 --raid-devices=2 /dev/sda3 /dev/sdb3

 

Comprobamos que el raid se ha creado correctamente:

 

node1> cat /proc/mdstat

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]

md2 : active raid0 sda3[1] sdb3[0]

1417045248 blocks 64k chunks

 

El siguiente paso es formatear y montar la partición que exportaremos:

 

node1> mke2fs -j /dev/md2

node1> mount /dev/md2 /mnt/glusterfs/home

 

Una vez disponemos de la zona de disco que queremos exportar, configuramos el lado servidor de GlusterFS, que será idéntico en todos los nodos servidores de disco. La estructura del fichero de configuración es la siguiente:

 

Recurso a exportar

Translator 1

Translator 2

Translator n

Definición del volumen servidor

 

El fichero de configuración de los nodos servidores de GlusterFS se puede encontrar en los apéndices [19.1.3].

 

La primera declaración en el fichero de configuración indica sobre qué directorio vamos a trabajar. Las siguientes declaraciones son distintos translators[9] que aportan soporte para bloqueo de ficheros (posix-locks) e introducen mejoras de rendimiento (iothreads, wb, ra). La declaración server indica qué zona se va a exportar, el transporte utilizado y las restricciones de acceso.

 

Por último sólo queda lanzar el demonio GlusterFS con la configuración que hemos creado:

 

node1> /sbin/glusterfsd -f /etc/glusterfs/glusterfs-server.vol

10.3.2. Namespace

 

A continuación guardaremos el namespace de la zona de usuario GlusterFS en los dos nodos master. Ambos nodos contarán con una partición idéntica en la que, por AFR, se replicará el namespace.

 

Los nodos master cuentan con dos discos de 500GB. Creamos una partición de 200 GB[10] en cada uno de los discos para, posteriormente crear un volumen RAID0 en las dos máquinas master:

 

master-cluster1> mdadm --create /dev/md2 --level=0 --raid-devices=2 /dev/sda3 /dev/sdb3

 

Formateamos y montamos el dispositivo, utilizando ext3 por ser un filesystem con journaling y ampliamente soportado por herramientas de recuperación de datos.

 

master-cluster1> mke2fs -j /dev/md2

master-cluster1> mount /dev/md2 /mnt/glusterfs/home-ns

 

Configuramos el servidor GlusterFS en los nodos master-cluster. La configuración será idéntica en los dos nodos:

 

volume brick-ns

type storage/posix

option directory /mnt/glusterfs/home-ns

end-volume

 

volume server

type protocol/server

subvolumes brick-ns

option transport-type tcp/server

option auth.ip.brick-ns.allow *

end-volume

 

Arrancamos el servidor GlusterFS en los dos nodos master-cluster:

 

master-cluster1> /sbin/glusterfsd -f /etc/glusterfs/glusterfs-server.vol

 

Después de estos pasos ya tenemos el lado servidor de la zona GlusterFS configurado.

10.3.3. Clientes

 

En un sistema GlusterFS los servidores exportan recursos, ya sea zonas de disco o namespace, sin saber el destino que se les va a dar o qué exportan el resto de servidores. La comunicación inter-servidor no existe. Son los clientes los que agregan  los recursos que exportan los servidores para crear volúmenes grandes.

 

En nuestro caso la configuración de todos los nodos clientes será idéntica. Se creará un volumen formado por tres AFRs, que serán parejas de nodos servidores: disc1+disc2, disc3+disc4 y disc5+disc6. El namespace será el AFR formado por la zona exportada por master-cluster1+master-cluster2.

 

El fichero de configuración de los nodos clientes puede consultarse en los apéndices [19.1.4].

 

En primer lugar describimos todos los recursos que vamos a utilizar, definidos como client0-ns y client1-ns (namespaces) y client1,..,client6 (servidores de disco). Posteriormente definimos los volúmenes AFRs y su composición. Finalmente creamos un volumen que unifica los tres AFRs y el namespace. Este volumen será la zona de disco que verán todos los clientes que monten la zona GlusterFS.

 

En la definición indicamos que la política de escritura será round-robin, que establece el orden de escritura de los ficheros de forma cíclica entre los AFRs (AFR1→AFR2→AFR3→AFR1→…), además dejamos un mínimo de un 1% de espacio libre en cada AFR.

 

Ya estamos en disposición de lanzar el cliente GlusterFS, que montará el volumen recién configurado. Como segundo parámetro indicamos el punto de montaje del volumen:

 

master-cluster1> /sbin/glusterfs -f /etc/glusterfs/glusterfs-client.vol /home

 

10.4. Pruebas

10.4.1. Test de estabilidad

 

Una vez separados los nodos servidores de disco de los nodos cliente, los problemas de estabilidad desaparecieron. El nuevo modelo se mostró estable ejecutando el test de estrés por periodos de tiempo de una semana. De esta forma pudimos centrarnos en las pruebas de rendimiento y usabilidad del nuevo modelo.

 

10.4.2. Pruebas de rendimiento

 

Las pruebas de rendimiento se basaron, por una parte, en una serie de tests sintéticos de rendimiento teórico, que nos proporcionaría el rendimiento pico máximo. Por otra parte realizamos pruebas de estrés basadas en la ejecución masiva de procesos con lecturas y escrituras concurrentes. Los detalles de las distintas pruebas de rendimiento se explican en el apartado [19.3.2].

10.4.2.1. Throughput máximo

 

En primer lugar, mostramos las cifras de throughput máximo arrojado por la pruebas de lecturas y escrituras concurrentes con el comando dd:

 

 

Número de instancias

MB/s en lectura

MB/s en escritura

1

42.3

39.3

2

83.2

59.7

3

118.9

80.9

4

119.2

77.9

5

119.1

73.6

 

 

Como podemos ver los resultados de las pruebas de lectura son muy buenos. El filesystem escala linealmente con el número de AFRs.

 

En el caso de las escrituras, el throughput máximo teórico puede enviar cada nodo cliente es de 62 MB/s, que corresponde a la mitad de la capacidad de nuestra red. Recordemos que nuestro filesystem hace uso del translator AFR como mecanismo de replicación de datos. Con AFR los nodos clientes envían los datos duplicados por la red, una copia para cada uno de los nodos de cada AFR.

 

 

Lecturas

 

 

 

Escrituras

 

Figura 10.2: Throughput de lectura y escritura con GlusterFS

 

 

AFR proporciona por un lado un mecanismo sencillo de alta disponibilidad, pero por otro lado limita la tasa de escritura de cada nodo cliente a la mitad. De todas formas 62 MB/s es una cifra muy buena, cercana a la capacidad de escritura máxima de un disco local.

 

El uso de la red por parte de Lustre es mucho más racional. Los datos que se escriben en el filesystem se envía por la red una sola vez, y se delega la posible replicación al backend de almacenamiento, en nuestro caso la pareja de nodos con replicación DRBD.

10.4.2.2. Test ad-hoc

 

El siguiente test consiste en la ejecución concurrente de procesos con un alto uso de E/S. La descripción de la batería de pruebas puede consultarse en los apéndices [19.3.2.2].

 

A continuación mostramos los resultados obtenidos correspondientes a ejecutar un determinado número de procesos de lectura:

 

Concurrencia

Tiempo

Throughput agregado (MB/s)

MB/s por proceso

1

48.5’’

101.3

101.3

2

49.2”

199.8

99.9

3

51.7”

285.2

95.0

6

1’ 50”

267.4

44.5

9

3’ 32”

243.3

27.0

18

6’ 44”

219.0

12.16

36

17’ 25”

171.6

4.7

 

 

Los resultados no distan mucho de los obtenidos con el fielsystem Lustre. GlusterFS también demuestra ser un filesystem altamente escalable a tenor de los valores  de throughput agregado obtenido. Si bien las cifras se quedan un poco por debajo de las obtenidas con Lustre, no dejan de ser muy buenas.

 

 

Throughput agregado

 

 

 

Throughput por proceso

 

Figura 10.3: Throughput del filesystem GlusterFS en lecturas

 

 

De nuevo observamos una escalabilidad lineal con el número de elementos que componen el filesystem. En este caso contamos con 3 AFRs, por lo que es con 3 lecturas concurrentes cuando obtenemos el throughput máximo, cercano a los 300 MB/s.

 

Según se incrementa el número de procesos de lectura concurrentes el throughput del filesystem cae ligeramente, debido en parte al mayor estrés de los díscos físicos de cada AFR, y en parte también a la saturación en los nodos clientes, que deben procesar más instancias de nuestro benchmark, que requiere de cierta capacidad de proceso.

 

Además como hemos comentado previamente, con AFR los datos se envían dos veces por la red, una copia para cada nodo de la pareja. Este hecho limita la cantidad de información que puede enviar un nodo cliente a la mitad.

 

Las pruebas de escritura arrojan los siguientes resultados:

 

Concurrencia

Tiempo

Throughput agregado (MB/s)

MB/s por proceso

1

2’ 28”

33.1

33.1

2

2’ 49”

58.0

29.0

3

3’ 12”

76.7

25.5

6

7’ 0’’

70.2

11.7

9

11’ 13”

66.5

7.3

18

24’ 49’’

60.1

3.3

36

52’ 30”

56.3

1.56

 

En esta ocasión los resultados obtenidos son netamente superiores a los del filesystem Lustre, lastrado por el sistema de replicación DRBD. Nuevamente el throughput agregado se mantiene bastante estable a lo largo de todas las pruebas.

 

 

Throughput agregado

 

 

 

Throughput por proceso

 

Figura 10.4: Throughput del filesystem GlusterFS en escrituras

10.4.3. Pruebas de usabilidad

 

Por último las pruebas de usabilidad sirvieron para medir el grado de interactividad del usuario con la zona de disco compartido mientras el sistema estaba sometido a distintos niveles de carga de trabajo.

 

En esta ocasión y al contrario de lo que sucedía con el modelo de cluster versión 1.1, todas las pruebas de usabilidad resultaron un éxito. Incluso a niveles de carga altísimos el tiempo de respuesta apreciado por los distintos beta testers fue similar al de un filesystem local.

 

El éxito de esta prueba junto con el de la prueba de estabilidad y los buenos resultados cosechados en las pruebas de rendimiento nos lleva a elegir este modelo.

 


11. Sun Grid Engine

 

11.1. Instalación

 

Obtenemos la última versión[11] de Sun Grid Engine (en adelante Sun Grid) de la página web de Sun. El software está empaquetado en dos archivos, una parte común y otra con binarios y librerías dependiente de la arquitectura, lx24-x86 en nuestro caso. Las descargamos y descomprimimos los archivos en /usr/local/sge:

 

master-cluster1> tar xfz sge-6.1u2-common.tar.gz -C /usr/local/sge

master-cluster1> tar xfz sge-6.1u2-bin-lx24-x86.tar.gz -C /usr/local/sge

 

Como paso previo a la instalación es necesario definir los servicios de red que utiliza SunGrid. Los añadimos a todas las máquinas del cluster en el fichero /etc/services:

 

# Sun grid ports

sge_qmaster     536/tcp

sge_execd       537/tcp

 

También es necesario identificar los distintos roles que juegan los nodos de un sistema Sun Grid y asignarlos a nuestros nodos:

 

·        Master host: controla el sistema Sun Grid. Este host ejecuta los daemons sge_master y sge_sched. El host que actúa como master debe ser estable, no estar excesivamente cargado con otros procesos y disponer de al menos 1 GB de memoria libre.

 

·        Shadow master hosts: actúan como backup de la funcionalidad ofrecida por el master host en caso de que éste falle. Los hosts que actúan como shadow master deben ejecutar el daemon sge_shadowd, encargado de monitorizar al master host y compartir el status y la configuración del master host, por  lo que la zona sge-root/cell/common debe ser una zona común.

 

·        Administration hosts: son hosts desde los que se pueden llevar a cabo tareas administrativas como reconfigurar colas, añadir usuarios, etc. Los hosts master lo son por defecto.

 

·        Submit hosts: los trabajos sólo pueden ser enviados al sistema desde estos hosts. Por defecto el nodo master es submit host. En nuestro caso, los dos nodos master-cluster.

 

·        Execution host: ejecutan los trabajos que los usuarios envían al sistema Sun Grid. Un nodo de ejecución debe estar configurado previamente como nodo administrativo.

 

En nuestro cluster contamos con dos tipos de nodos diferenciados: los nodos master y los nodos de cómputo. Los nodos master, desde el punto de vista del sistema Sun Grid serán master hosts, administrative hosts y submit hosts. Los nodos de cómputo serán execution hosts y administrative hosts.

 

Cabe destacar que pese a tener dos hosts que potencialmente pueden actuar como master hosts, no configuramos uno de ellos como shadow_master. En lugar de esto configuramos SunGrid como un servicio más de alta disponibilidad monitorizado por heartbeat (ver apartado [12]). De esta manera, cuando el nodo master que actúa como master host cae, heartbeat lo detecta y activa el servicio en el failnode.

11.1.1. Instalación del Master host

 

La instalación se hace de forma interactiva, ejecutando el script install_qmaster de /usr/local/sge.

 

Checking $SGE_ROOT directory

 

The Grid Engine root directory is not set!

Please enter a correct path for SGE_ROOT.

 

If this directory is not correct (e.g. it may contain an automounter

prefix) enter the correct path to this directory or hit <RETURN>

to use default [/usr/local/sge] >>

 

Grid Engine TCP/IP service >sge_qmaster<

 

Using the service

 

sge_qmaster

 

for communication with Grid Engine.

 

Hit <RETURN> to continue >>

 

A continuación configuramos el nombre de nuestro cluster o cell, útil en caso de contra con varias instancias de cluster.

 

Grid Engine cells

 

Grid Engine supports multiple cells.

 

If you are not planning to run multiple Grid Engine clusters or if you don't

know yet what is a Grid Engine cell it is safe to keep the default cell name

 

default

 

If you want to install multiple cells you can enter a cell name now.

 

The environment variable

 

   $SGE_CELL=<your_cell_name>

 

will be set for all further Grid Engine commands.

 

Enter cell name [default] >>

 

En la siguiente pantalla configuramos la localización del directorio spool.

 

 

Grid Engine qmaster spool directory

 

The qmaster spool directory is the place where the qmaster daemon stores

the configuration and the state of the queuing system.

 

Your account on this host must have read/write access

to the qmaster spool directory.

 

If you will install shadow master hosts or if you want to be able to start

the qmaster daemon on other hosts (see the corresponding section in the

Grid Engine Installation and Administration Manual for details) the account

on the shadow master hosts also needs read/write access to this directory.

 

The following directory

 

[/tmp/sge/default/spool/qmaster]

 

will be used as qmaster spool directory by default!

 

Do you want to select another qmaster spool directory (y/n) [n] >>n

 

Sun Grid permite la ejecución de trabajos en máquinas Windows. En nuestro caso no lo nenesitamos.

 

Windows Execution Host Support

 

Are you going to install Windows Execution Hosts? (y/n) [n] >>n

 

Select default Grid Engine hostname resolving method

 

Are all hosts of your cluster in one DNS domain? If this is

the case the hostnames

 

>hostA< and >hostA.foo.com<

 

would be treated as equal, because the DNS domain name >foo.com<

is ignored when comparing hostnames.

 

Are all hosts of your cluster in a single DNS domain (y/n) [y] >>y

 

Making directories

 

Hit <RETURN> to continue >>

 

La siguiente pantalla permite configurar el modelo de base de datos utilizado para guardar la información de spool.

 

Setup spooling

 

Your SGE binaries are compiled to link the spooling libraries

during runtime (dynamically). So you can choose between Berkeley DB

spooling and Classic spooling method.

Please choose a spooling method (berkeleydb|classic) [berkeleydb] >>berkeleydb

 

The Berkeley DB spooling method provides two configurations!

 

Local spooling:

The Berkeley DB spools into a local directory on this host (qmaster host)

This setup is faster, but you can't setup a shadow master host

 

Berkeley DB Spooling Server:

If you want to setup a shadow master host, you need to use

Berkeley DB Spooling Server!

In this case you have to choose a host with a configured RPC service.

The qmaster host connects via RPC to the Berkeley DB. This setup is more

failsafe, but results in a clear potential security hole. RPC communication

(as used by Berkeley DB) can be easily compromised. Please only use this

alternative if your site is secure or if you are not concerned about

security. Check the installation guide for further advice on how to achieve

failsafety without compromising security.

 

Do you want to use a Berkeley DB Spooling Server? (y/n) [n] >>n

 

Berkeley Database spooling parameters

 

Please enter the Database Directory now, even if you want to spool locally,

it is necessary to enter this Database Directory.

 

Default: [/usr/local/sge/default/spool/spooldb] >> /usr/local/sge/default/spool/spooldb

 

Cada trabajo ejecutado desde Sun Grid es un procso de sistema más. Como tal tendrán un pid asociado. En la siguiente pantalla se configura el rango de pids reservados para los procesos de Sun Grid.

 

Grid Engine group id range

 

When jobs are started under the control of Grid Engine an additional group id

is set on platforms which do not support jobs. This is done to provide maximum

control for Grid Engine jobs.

 

This additional UNIX group id range must be unused group id's in your system.

Each job will be assigned a unique id during the time it is running.

Therefore you need to provide a range of id's which will be assigned

dynamically for jobs.

 

The range must be big enough to provide enough numbers for the maximum numberof Grid Engine jobs running at a single moment on a single host. E.g. a rangelike >20000-20100< means, that Grid Engine will use the group ids from20000-20100 and provides a range for 100 Grid Engine jobs at the same timeon a single host.

 

You can change at any time the group id range in your cluster configuration.

 

Please enter a range >>20000-25000

 

Seguidamente indicamos la dirección de correo del administrador del cluster, tras lo cual se crea una primera configuración del sistema.

 

Grid Engine cluster configuration

 

Please give the basic configuration parameters of your Grid Engine

installation:

 

<execd_spool_dir>

 

The pathname of the spool directory of the execution hosts. User >ivanc<

must have the right to create this directory and to write into it.

 

Default: [/usr/local/sge/default/spool] >>/usr/local/sge/default/spool

 

Grid Engine cluster configuration (continued)

 

<administrator_mail>

 

The email address of the administrator to whom problem reports are sent.

 

It's is recommended to configure this parameter. You may use >none<

if you do not wish to receive administrator mail.

 

Please enter an email address in the form >user@foo.com<.

 

Default: [none] >>cluster@lsi.upc.edu

 

The following parameters for the cluster configuration were configured:

 

execd_spool_dir        /usr/local/sge/default/spool

administrator_mail     cluster@lsi.upc.edu

 

Do you want to change the configuration parameters (y/n) [n] >>n

 

Creating local configuration

 

Creating >act_qmaster< file

Adding default complex attributes

Reading in complex attributes.

Adding default parallel environments (PE)

Reading in parallel environments:

        PE "make".

PE "make.sge_pqs_api".

Adding SGE default usersets

Reading in usersets:

Userset "defaultdepartment".

Userset "deadlineusers".

Adding >sge_aliases< path aliases file

Adding >qtask< qtcsh sample default request file

Adding >sge_request< default submit options file

Creating >sgemaster< script

Creating >sgeexecd< script

Creating settings files for >.profile/.cshrc<

 

Hit <RETURN> to continue >>

 

Una vez configurado, el sistema se inicia el servicio qmaster por primera vez, tras lo cual introducimos la lista de los hosts de ejecución.

 

Grid Engine qmaster and scheduler startup

 

Starting qmaster and scheduler daemon. Please wait ...

starting sge_qmaster

starting sge_schedd

starting up GE 6.1u2 (lx24-x86)

Hit <RETURN> to continue >>

 

Adding Grid Engine hosts

 

Please now add the list of hosts, where you will later install your execution

daemons. These hosts will be also added as valid submit hosts.

 

Please enter a blank separated list of your execution hosts. You may

press<RETURN> if the line is getting too long. Once you are finished

simply press <RETURN> without entering a name.

 

You also may prepare a file with the hostnames of the machines where you plan

to install Grid Engine. This may be convenient if you are installing Grid

Engine on many hosts.

 

Do you want to use a file which contains the list of hosts (y/n) [n] >>n

 

Adding admin and submit hosts

 

Please enter a blank seperated list of hosts.

 

Stop by entering <RETURN>. You may repeat this step until you are

entering an empty list. You will see messages from Grid Engine

when the hosts are added.

 

Sun Grid permite tener una configuración de alta disponibilidad del master host mediante el uso de un shadow master host. Nosotros utilizaremos nuestra propia configuración HA, por lo que no configuramos ningún shadow master.

 

Host(s):

If you want to use a shadow host, it is recommended to add this host

to the list of administrative hosts.

 

If you are not sure, it is also possible to add or remove hosts after the

installation with <qconf -ah hostname> for adding and <qconf -dh hostname>

for removing this host

 

Attention: This is not the shadow host installationprocedure.

You still have to install the shadow host separately

 

Do you want to add your shadow host(s) now? (y/n) [y] >>n

 

SGE_ROOT directory: /usr/local/sge

Cell name: default

Grid Engine qmaster spool directory: /usr/local/sge/default/spool/qmaster

Windows Execution Host Support: no

Setup spooling: berkeleydb

Use Berkeley DB Spooling Server: no

Berkeley Database spooling directory: /usr/local/sge/default/spool/spooldb

Grid Engine group id range: 20000-25000

Grid Engine spool directory on execution hosts: /usr/local/sge/default/spool

Administration email address: cluster@lsi.upc.edu

 

Tras estos pasos se inician los daemons qmaster y schedd.

 

Grid Engine qmaster and scheduler startup

 

Starting qmaster and scheduler daemon. Please wait ...

starting sge_qmaster

starting sge_schedd

starting up GE 6.1u2 (lx24-x86)

Hit <RETURN> to continue >>

 

 

A continuación podemos indicar al sistema qué hosts seran nodos de ejecución.

 

Adding Grid Engine hosts

 

Please now add the list of hosts, where you will later install your execution

daemons. These hosts will be also added as valid submit hosts.

 

Please enter a blank separated list of your execution hosts. You may

press<RETURN> if the line is getting too long. Once you are finished

simply press <RETURN> without entering a name.

 

You also may prepare a file with the hostnames of the machines where you plan

to install Grid Engine. This may be convenient if you are installing Grid

Engine on many hosts.

 

Do you want to use a file which contains the list of hosts (y/n) [n] >>n

 

En la siguiente pantalla se configuran los hosts desde los que se enviarán los trabajos y aquellos con permisos administrativos.

 

Adding admin and submit hosts

 

Please enter a blank seperated list of hosts.

 

Stop by entering <RETURN>. You may repeat this step until you are

entering an empty list. You will see messages from Grid Engine

when the hosts are added.

 

Host(s):

If you want to use a shadow host, it is recommended to add this host

to the list of administrative hosts.

 

If you are not sure, it is also possible to add or remove hosts after the

installation with <qconf -ah hostname> for adding and <qconf -dh hostname>

for removing this host

 

Attention: This is not the shadow host installationprocedure.

You still have to install the shadow host separately

 

Do you want to add your shadow host(s) now? (y/n) [y] >>n

Creating the default <all.q> queue and <allhosts> hostgroup

 

root@master-cluster1 "@allhosts" to host group list

root@master-cluster2 "all.q" to cluster queue list

 

Hit <RETURN> to continue >>

 

En la siguiente pantalla seleccionamos el nivel logs generado por el shceduler. Lo dejamos en Normal.

 

Scheduler Tuning

 

The details on the different options are described in the manual.

 

Configurations

 

1) Normal

          Fixed interval scheduling, report scheduling information,

actual + assumed load

 

2) High

          Fixed interval scheduling, report limited scheduling information,

actual load

 

3) Max

          Immediate Scheduling, report no scheduling information,

actual load

 

Enter the number of your prefered configuration and hit <RETURN>!

Default configuration is [1] >>1

 

We're configuring the scheduler with >Normal< settings!

Do you agree? (y/n) [y] >>y

 

El master host ya está  configurado. La sieguiente pantalla muestra información sobre la definición de variables de entorno necesarias para que Sun Grid funcione correctamente.

 

Using Grid Engine

 

You should now enter the command:

 

source /usr/local/sge/default/common/settings.csh

 

if you are a csh/tcsh user or

 

   # /usr/local/sge/default/common/settings.sh

 

if you are a sh/ksh user.

 

This will set or expand the following environment variables:

 

   - $SGE_ROOT         (always necessary)

   - $SGE_CELL         (if you are using a cell other than >default<)

   - $SGE_QMASTER_PORT (if you haven't added the service >sge_qmaster<)

   - $SGE_EXECD_PORT   (if you haven't added the service >sge_execd<)

   - $PATH/$path       (to find the Grid Engine binaries)

   - $MANPATH          (to access the manual pages)

 

Hit <RETURN> to see where Grid Engine logs messages >>

 

La siguiente pantalla informa de la localización de  scripts de inicio.

 

Grid Engine messages

 

Grid Engine messages can be found at:

 

   /tmp/qmaster_messages (during qmaster startup)

   /tmp/execd_messages   (during execution daemon startup)

 

After startup the daemons log their messages in their spool directories.

 

   Qmaster:     /usr/local/sge/default/spool/qmaster/messages

   Exec daemon: <execd_spool_dir>/<hostname>/messages

 

 

Grid Engine startup scripts

 

Grid Engine startup scripts can be found at:

 

   /usr/local/sge/default/common/sgemaster (qmaster and scheduler)

   /usr/local/sge/default/common/sgeexecd (execd)

 

Do you want to see previous screen about using Grid Engine again (y/n) [n] >>n

 

Finalmente se informa de la correcta instalación del sistema Sun Grid.

 

Your Grid Engine qmaster installation is now completed

 

Please now login to all hosts where you want to run an execution daemon

and start the execution host installation procedure.

 

If you want to run an execution daemon on this host, please do not forget

to make the execution host installation in this host as well.

 

All execution hosts must be administrative hosts during the installation.

All hosts which you added to the list of administrative hosts during this

installation procedure can now be installed.

 

You may verify your administrative hosts with the command

 

   # qconf -sh

 

and you may add new administrative hosts with the command

 

   # qconf -ah <hostname>

 

Please hit <RETURN>>>

11.1.2. Instalación de un Execution host

 

A continuación ejecutamos el script de instalación install_execd. Como requisito previo, es necesario que haya un master host con los servicios qmaster y qschedd corriendo.

 

Checking $SGE_ROOT directory

 

The Grid Engine root directory is:

 

   $SGE_ROOT = /usr/local/sge

 

If this directory is not correct (e.g. it may contain an automounter

prefix) enter the correct path to this directory or hit <RETURN>

to use default [/tmp/sge] >>

 

En primer lugar indicarmos en qué cell o cluster podrá ejecutar trabajos el execution host que estamos configurando. En nuestro caso en el cell por defecto default.

 

Grid Engine cells

 

Please enter cell name which you used for the qmaster

installation or press <RETURN> to use [default] >>

 

En la siguiente pantalla configuramos la localización del directorio de spool del execution host.

 

Local execd spool directory configuration

 

During the qmaster installation you've already entered a global

execd spool directory. This is used, if no local spool directory is configured.

 

Now you can configure a local spool directory for this host.

ATTENTION: The local spool directory doesn't have to be located on a local

drive. It is specific to the <local> host and can be located on network drives,

too. But for performance reasons, spooling to a local drive is recommended.

 

FOR WINDOWS USER: On Windows systems the local spool directory MUST be set

to a local harddisk directory.

Installing an execd without local spool directory makes the host unuseable.

Local spooling on local harddisk is mandatory for Windows systems.

 

Do you want to configure a local spool directory

for this host (y/n) [n] >>y

 

Please enter the local spool directory now! >>/usr/local/sge/default/spool/node1

 

Por defecto todo sistema Sun Grid dispone de una cola llamada all.q, que incluye todos los nodos de ejecución.

 

Adding a queue for this host

 

We can now add a queue instance for this host:

 

   - it is added to the >allhosts< hostgroup

   - the queue provides 2 slot(s) for jobs in all queues

referencing the >allhosts< hostgroup

 

You do not need to add this host now, but before running jobs on this host

it must be added to at least one queue.

 

Do you want to add a default queue instance for this host (y/n) [y] >>y

 

node1 modified "@allhosts" in host group list

node1 "all.q" in cluster queue list

 

Los servicios Sun Grid ya están instalados correctamente en este host. La siguiente pantalla muestra variables de entorno necesarias para el correcto funcionamiento de Sun Grid.

 

Using Grid Engine

 

You should now enter the command:

 

source /tmp/sge/default/common/settings.csh

 

if you are a csh/tcsh user or

 

# . /tmp/sge/default/common/settings.sh

 

if you are a sh/ksh user.

 

This will set or expand the following environment variables:

 

   - $SGE_ROOT         (always necessary)

   - $SGE_CELL         (if you are using a cell other than >default<)

   - $SGE_QMASTER_PORT (if you haven't added the service >sge_qmaster<)

   - $SGE_EXECD_PORT   (if you haven't added the service >sge_execd<)

   - $PATH/$path       (to find the Grid Engine binaries)

   - $MANPATH          (to access the manual pages)

 

Hit <RETURN> to see where Grid Engine logs messages >>

 

Por ultimo se indica la localización de los logs y los scripts necesarios para iniciar Sun Grid en los execution hosts.

 

Grid Engine messages

 

Grid Engine messages can be found at:

 

   /tmp/qmaster_messages (during qmaster startup)

   /tmp/execd_messages   (during execution daemon startup)

 

After startup the daemons log their messages in their spool directories.

 

   Qmaster:     /tmp/sge/default/spool/qmaster/messages

   Exec daemon: <execd_spool_dir>/<hostname>/messages

 

 

Grid Engine startup scripts

 

Grid Engine startup scripts can be found at:

 

   /tmp/sge/default/common/sgemaster (qmaster and scheduler)

   /tmp/sge/default/common/sgeexecd (execd)

 

Do you want to see previous screen about using Grid Engine again (y/n) [n] >>n

 

Your execution daemon installation is now completed.

 

11.2. Configuración

 

Hemos instalado un master host y un execution host. Durante la instalación del master host se nos ha preguntado por diversos paths donde almacenar información de configuración del cluster, scheduling de procesos, etc.

 

En los siguientes pasos aprovecharemos los conocimientos adquiridos en filesystems paralelos y HA para integrar este servicio en nuestro sistema de heartbeat y dotarlo de  alta disponibilidad.

 

Asumimos que partimos de la arquitectura versión 2.0, con GlusterFS instalado.

11.2.1. Zona Spool de mater hosts

 

En el apartado de configuración del master host hemos indicado la ruta donde residirá el spool del nodo master (/usr/local/sge/default/spool/qmaster). Este directorio contiene la información de scheduling de procesos que necesita el daemon sge_qmaster para funcionar. Si queremos tener un master host alternativo que tome el control del grid en caso de fallo del master host "primario", ambas máquinas deben tener acceso a la zona referida.

 

Nuevamente, lo ideal sería disponer de un SAN conectado a los dos nodos master, pero no disponemos de estos recursos. En cambio, hemos visto una solución que ya utilizamos como sistema de replicación de bloques en el sistema de ficheros Lustre. DRBD permite crear un dispositivo de bloques virtual formado por los discos locales de dos máquinas conectadas por red.

 

En la figura [11.1] se muestra un esquema con las zonas que albergan los nodos master-cluster, incluyendo la zona common de Sun Grid.

 

En un esquema DRBD los nodos que contienen los discos juegan los roles de primary y secondary. El nodo primary tiene pleno acceso al disco, mientras que el secondary se limita a recibir la replicación de datos desde primary. En el caso que nos toca, el nodo primary será el nodo que esté configurado como master host Sun Grid en ese momento, mientras que el otro nodo master será el nodo secondary. En caso de fallo del nodo primary, el nodo configurado como secondary se dará cuenta y se configurará como primary.

 

Para configurar esta zona DRBD, en primer lugar debemos crear dos particiones idénticas en ambos nodos master. Como contamos con dos discos por máquina, hacemos un RAID1:

 

master-cluster1> mdadm --create /dev/md3 --level=1 --raid-devices=2 /dev/sda5 /dev/sdb5

 

La configuración DRBD será la misma en ambas máquinas. El fichero drbd.conf se encuentra en el apéndice [19.1.9].

 

En primer lugar es necesario incializar el dispositivo DRBD. Para ello se deben seguir los pasos detallados en el apartado [9.3.2]. Nótese que la sincronización se realiza por una conexión dedicada entre ambos nodos master.

 

Ya disponemos de la zona DRBD funcional:

 

version: 8.2.6 (api:88/proto:86-88)

GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by root@master-cluster1, 2008-10-01 10:56:55

 

 1: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---

ns:9710768 nr:0 dw:9465908 dr:819917 al:59 bm:39 lo:0 pe:0 ua:0 ap:0 oos:0

 

Paramos el daemon sge_qmaster y movemos el contenido del directorio spool a la zona DRBD:

 

master-cluster1> /etc/init.d/sge_qmaster stop

master-cluster1> mount /dev/drbd1 /mnt/sge/default/spool

master-cluster1> cd /usr/local/sge/default/spool

master-cluster1> tar cf - * | (cd /mnt/sge/default/spool;tar xf - )

master-cluster1> cd ..

master-cluster1> rm -rf spool

master-cluster1> ln -s /mnt/sge/default/spool spool

master-cluster1> /etc/init.d/sge_qmaster start

11.2.2. Zona common

 

La zona common contiene información acerca de la configuración del cluster, accounting, etc. De cara a nuestro objetivo de alta disponibilidad, nos resulta interesante el fichero act_qmaster, que contiene el hostname de la máquina que actúa como master host en un momento dado. Todos los nodos del cluster se basan en la información de este fichero para contactar con el master host.

 

En nuestra configuración, si el nodo que actúa como master host falla, hay otro nodo preparado para tomar el control. Para ello es necesario que previa ejecución del daemon sge_qmaster modifique el fichero act_qmaster escribiendo su hostname. Sólo tras hacer esto le será posible lanzar el daemon sge_qmaster.

 

Hemos comentado que todos los nodos del cluster saben quién es el master host gracias al fichero act_qmaster. Si hacemos cambios en este fichero, estos cambios deben ser visibles para los nodos del cluster de forma inmediata. Para ello alojaremos el directorio common en una nueva zona compartida. Además de ser visible por todos los nodos del cluster, debe estar accesible a pesar de la caída de alguno de los nodos master. La solución adoptada consiste en crear una zona GlusterFS con un AFR formado por sendas particiones en los nodos de entrada al sistema (master-cluster1 y master-cluster2). De esta manera en caso de caer una de las dos máquinas master, la otra seguirá teniendo acceso a la zona y ésta en ningún caso dejará de ser visible por el resto de nodos.

 

En la figura [11.1] se muestran las distintas zonas que albergan los nodos master-cluster, entre ellas la zona common.

 

 

Ilustración 11.1: Esquema de las zonas albergadas en los nodos master-cluster

 

 

Nuevamente, habilitamos una partición RAID en cada una de las máquinas master:

 

master-cluster1> mdadm --create /dev/md4 --level=1 --raid-devices=2 /dev/sda6 /dev/sdb6

master-cluster1> mke2fs -j /dev/md4

master-cluster1> mount /dev/md4 /mnt/glusterfs/sge-common

 

Configuramos un nuevo servidor GlusterFS en ambas máquinas master. El correspondiente fichero de configuración glusterfs-server_sge-common.vol se encuentra en los apéndices [19.1.10].

 

Lanzamos el daemon GlusterFS:

 

master-cluster1> /sbin/glusterfsd -f /etc/glusterfs/glusterfs-server_sge-common.vol

 

Creamos una configuración cliente gluster para esta nueva zona. Esta configuración, guardada en /etc/glusterfs/glusterfs-client-sge.vol (ver apéndices [19.1.11]), debe estar en todas las máquinas del cluster, ya que contendrá la zona common necesaria tanto por sge_qmaster como por sge_execd.

 

Montamos esta zona en todas las máquinas del cluster en un directorio habilitado a tal efecto:

 

master-cluster1> /sbin/glusterfs -f /etc/glusterfs/glusterfs-client-sge.vol /mnt/sge/default/common

 

De la misma forma que hicimos con la zona spool, movemos el contenido de la zona common y paramos el daemon sge_execd en todas los execution host, en caso de estar corriendo:

 

node1> /etc/init.d/sge_execd stop

...

 

Movemos lo datos common a la nueva zona compartida:

 

master-cluster1> /etc/init.d/sge_qmaster stop

master-cluster1> cd /usr/local/sge/default/common

master-cluster1> tar cf - * | (cd /mnt/sge/default/common;tar xf -)

master-cluster1> cd ..

master-cluster1> rm -rf common

master-cluster1> /etc/init.d/sge_qmaster start

 

Volvemos a lanzar el daemon sge_execd en todos los execution hosts:

 

node1> /etc/init.d/sge_execd start

...

 

Tras estos pasos el sistema Sun Grid es plenamente operativo con tolerancia a fallos en los nodos master. Queda pendiente la automatización del proceso de inicio de servicios en nodo failover, que veremos el capítulo [12].

11.2.3. Colas

 

La antigua estructura con tres clusters separados tiene su correspondencia en el nuevo cluster en forma de colas. Definiremos tres colas: eixam, nozomi y tenada, que estarán formadas por las máquinas que conformaban los respectivos clusters más las máquinas nuevas que estaban pendientes de instalación.

 

Cuando hablamos de colas en un entorno HTC se da un abuso de lenguaje que puede llevar a equívocos. Una cola Sun Grid realmente es una cola de ejecución, lo que no es más que un conjunto de máquinas que ejecutan los procesos que les envía el planificador o scheduler. No se debe confundir con la cola de espera, que es el espacio “virtual”, donde los trabajos encolados por los usuarios esperan a ser enviados por el scheduler a alguna cola de ejecución.

 

La figura [11.2] muestra el esquema con las tres colas de ejecución de nuestro cluster y la cola de espera. Nótese que hay una única cola de espera en la que conviven los trabajos destinados a cualquiera de las tres colas de ejecución.

 

Figura 11.2: Esquema de cluster con colas de ejecución y de espera

 

 

Sun Grid permite definir tantas colas (de ejecución) como sean necesarias, pudiendo personalizar multitud de aspectos. En cambio, en un cluster, existe una única cola de espera.

 

La idea es que, a pesar de existir un único cluster, los usuarios de cada grupo ejecuten su trabajo en las máquinas que les pertenecen. Las colas pueden crearse desde consola o mediante el frontend gráfico qmon , como muestra la figura [11.3].

 

Si bien inicialmente los usuarios de una cola no pueden utilizar los recursos de las otras, se abre la posibilidad a futuras colaboraciones mediante la creación de colas nice. Estas colas permiten el aprovechamiento de las máquinas desocupadas por parte de los usuarios de los otros grupos. Este mecanismo ha sido probado con éxito en el cluster de pruebas, pero permanecerá desactivado hasta que se produzca un acuerdo de colaboración entre los distintos grupos de investigación.

 

 

Figura11.3: Ventana de creación de colas desde qmon

 

 

Como hemos comentado antes existe una única cola de espera. En esta cola conviven los trabajos de todos los usuarios ordenados en función de una prioridad que se explica en el apartado [11.2.4]. Como los usuarios de cada grupo trabajan solamente en la cola que tienen asignada, los trabajos de usuarios de distintos grupos no interferirán entre sí a la hora de salir de la cola de espera. Por decirlo de alguna manera, en la cola de espera, los trabajos de un usuario dado sólo compiten con trabajos de usuarios de su mismo grupo.

11.2.3. Usuarios

 

Se procedió a dar de alta a todos los usuarios del cluster como usuarios del sistema Sun Grid con el mismo username. Sun Grid permite la gestión de usuarios, grupos, proyectos, etc.

 

Igualmente creamos tres grupos que se corresponden con los tres clusters antiguos y con las tres colas y se establecieron los permisos de acceso a cada una de las colas según estos grupos, de tal forma que en la cola eixam sólo podrán trabajar los usuarios del grupo eixam, en nozomi los del grupo nozomi, etc. La figura [11.4] muestra la ventana de administración de grupos de qmon.

 

A nivel administrativo los grupos facilitan la gestión de los usuarios. Dado que los permisos de las colas se establecen por grupos, si damos de alta o de baja un usuario, no es necesario realizar ninguna modificación en el control de acceso de las colas; el cambio queda reflejado en su grupo y las colas son conscientes inmediatamente.

 

 

Figura 11.4: Ventana de administración de grupos en qmon

11.2.4. Políticas

 

Al hablar de la cola de espera, hemos hecho notar que los trabajos que contiene se ordenan atendiendo a un valor numérico que expresa una prioridad. Junto con los responsables de los tres grupos que trabajan en el cluster, acordamos que, en principio, todos los usuarios contasen con el mismo peso en el sistema, es decir, que los trabajos de cada uno de ellos fuesen igual de prioritario que los del resto de usuarios.

 

Para llevar a cabo esta política “igualitaria”, definimos lo que Sun Grid llama una política funcional. En dicha política a cada usuario se le da un porcentaje o share de los recursos, definidos en forma de tikets. A mayor share mayor prioridad.

 

Como queremos que todos los usuarios tengan el mismo peso, damos a todos los usuarios el mismo share. El resultado de esta política es que, los trabajos en cola de espera de los usuarios con menor número de trabajos en ejecución tendrán mayor prioridad que los trabajos de los usuarios con más trabajos ejecutándose.

 

Para mantener un ratio óptimo entre procesos de usuario y número de CPUs, limitaremos el valor slots de las instancias de cada cola al número de procesadores (o cores) físico de cada nodo. Así un nodo con 4 cores tendrá 4 slots disponibles, lo que limitará el número de trabajos en ejecución de forma simultánea.

 

El planificador de Sun Grid repasa las colas a intervalos de tiempo preestablecidos y ordena los trabajos de usuario en función de sus prioridades. Esta tarea puede llegar a requerir una cantidad de cálculo nada desdeñable en el caso de contar con políticas de scheduling complejas y miles de procesos encolados.

 

Si bien nuestra política de scheduling es convencional, limitamos la ventana de trabajos que entran dentro de la planificación de la cola a 10.000. Igualmente limitamos a 500 el número máximo de trabajos encolados por un solo usuario con el fin de evitar que un solo usuario acapare toda la cola.

 

Finalmente limitamos el número máximo de trabajos en ejecución simultáneos de usuario a 25. El objetivo es evitar la inanición de los trabajos encolados porque un usuario del mismo grupo haya ocupado la totalidad de su cola.

 

La figura [11.5] muestra la ventana que da acceso a las políticas del cluster. Permite variar aspectos como el numero máximo de trabajos funcionales, de tickets, etc.

 

 

 

Figura 11.5: Ventana de control de políticas del cluster desde qmon

 

 

La figura [11.6] muestra la ventana que permite variar la configuración funcional. Nuestra configuración asigna el mismo número de share (100) a todos los usuarios,  para que de esta forma los trabajos de todos los usuarios tengan, a igual número de jobs en el sistema, la misma prioridad.

 

Figura 11.6: Ventana de gestión de la política funcional desde qmon


12. Heartbeat

 

Utilizaremos Heartbeat para proporcionar alta disponibilidad a los principales servicios del cluster, que son Sun Grid y el sistema de ficheros paralelo.

 

12.1. Instalación

 

Heartbeat está disponible dentro del repositorio de software de Debian, por lo que la instalación es la misma que la de cualquier otro programa:

 

master-cluster1> apt-get install heartbeat

 

Los ficheros de configuración, así como los scripts de gestión de servicios que quedan en los directorios /etc/ha.d y en /etc/ha.d/resources.d respectivamente.

 

La instalación configura el arranque de heartbeat automáticamente al inicio del sistema.

 

12.2. Configuración

12.2.1. Cluster con GlusterFS (versión 2.0)

 

Como vimos en el capítulo [10] cuando hablamos de la instalación y configuración de GlusterFS, el propio filesystem incorpora mecanismos de protección ante el fallo de un servidor de disco. El sistema de replicación de datos AFR se encarga de escribir los datos en varios servidores al mismo tiempo, por lo que no es necesario, al contrario de los que sucedía en los modelo con Lustre y DRBD (cluster versiones 1.0 y 1.1), el uso de un sistema de replicación de datos. Así pues, el único servicio que debemos configurar en HA es Sun Grid.

 

Tal y como expusimos en el apartado [11.2] al hablar de la configuración de Sun Grid, hay dos zonas con datos vitales para su correcto funcionamiento. Por una parte el directorio common, encargado de mantener la información de la configuración del sistema, y por otro spool, con información sobre el scheduling de procesos. El directorio common está hospedado en la zona GlusterFS, por lo que queda salvaguardado ante posibles fallos. En cambio el directorio spool se encuentra en una zona DRBD compartida entre los dos nodos master.

 

El funcionamiento de DRBD se explica detalladamente en el apartado [9.1].

 

En caso de que se produzca un fallo hardware en la máquina master, nuestro sistema de alta disponibilidad debe ser capaz de darse cuenta y realizar los pasos que acabamos de describir. En este escenario el nodo que ha fallado habría quedado totalmente invalidado para continuar ofreciendo los servicios de Sun Grid master.

 

El siguiente paso es garantizar que, una vez el failnode tiene control sobre la zona common, se convierta en Sun Grid master. En primer lugar hay que cambiar la identidad de la máquina master Sun Grid en la configuración del sistema de clustering para que todos los nodos sepan que tienen que tratar con una nueva máquina. Después de esto bastará con iniciar los servicios de Sun Grid master.

 

Heartbeat se configura desde dos ficheros: ha.cf y haresources9. En ha.cf se define cómo y cada cuánto tiempo monitorizaremos el peer node, mientras que en haresources definiremos los procedimientos a seguir en caso de fallo del peer node.

 

En estos ficheros de configuración indicamos que el chequeo o heartbeat se realiza vía red (ethernet) unicast a la dirección del interfaz eth0 del peer node. Asumimos que si la red de uno de los dos nodos no responde en 120 segundos, se puede considerar que el nodo ha fallado y debemos tomar las medidas oportunas.

 

Los procedimientos a seguir en caso de fallo se definen en haresources:

 

master-cluster1 Filesystem.drbd::/dev/drbd1::/mnt/sge/default/spool::ext3 sungrid MailTo::cluster@lsi.upc.edu

 

Este fichero es idéntico en ambos nodos. El primer campo indica el nodo que actúa como master normalmente, mientras que los siguientes dos nodos definen acciones concretas:

 

Filesystem::/dev/drbd1::/mnt/sge/default/spool::ext3

 

Ejecuta el script Filesystem, encargado de montar el dispositivo /dev/drbd1, que contiene la zona spool de Sun Grid en /mnt/sge/default/spool.

 

El cambio de rol secondary por primary necesario previo al montaje lo realiza el propio sistema DRBD.

 

Sungrid

 

Este script cambia la configuración del sistema SunGrid indicando el hostname de la nueva máquina master. El script completo se encuentra en el apéndice [19.1.8].

 

Finalmente indicamos la dirección de correo a la que llegarán los avisos en caso de fallo y recuperación.

 


12.3. Split-Brain

 

Al hablar de sistemas de alta disponibilidad debemos tener en cuenta el fenómeno llamado split-brain, que se produce cuando la comunicación entre los dos nodos se interrumpe y ambos intentan ser propietarios del mismo recurso.

 

De los dos recursos que tratamos, sólo la zona DRBD es susceptible de sufrir problemas por split-brain. Imaginemos que master-cluster1 es el nodo master y se queda sin conexión de red (eth0) aunque sigue funcionando. Master-cluster2 lo detectaría por heartbeat, asumiría que ha fallado e intentaría montar el dispositivo DRBD, pero no podría ya que no es un nodo primary. Master-cluster1 seguiría siendo primary porque la replicación DRBD se realiza vía un interfaz dedicado (eth1) que seguiría funcionando. Así pues, en este escenario no nos veríamos afectados por split-brain.

 

Supongamos ahora que falla la conexión dedicada (eth1), pero no la conexión de red (eth0). En este caso sería el sistema DRBD el que detectaría un fallo en los nodos e intentaría cambiar los roles. En este caso, muy poco probable, sí que podría producirse split-brain, ya que podríamos tener ambos nodos master configurados como primary, si bien no llegaría a producirse corrupción de datos porque el nodo configurado inicialmente como secondary nunca llegaría a montar el dispositivo DRBD (recordemos que como eth0 no ha fallado heartbeat no detecta fallo alguno).

 

Otro caso en el que se produciría split-brain sería aquel en el que ambas conexiones de red se interrumpieran pero los nodos siguiesen funcionando. En este caso en el nodo secondary el sistema DRBD dectaría el fallo en eth1 y se configuraría como primary. Algo más tarde (recordemos, 120 segundos) heartbeat montaría el dispositivo DRBD e intentaría configurarse como Sun Grid master, pero no lo conseguiría porque no hay conexión de red.

 

Así pues ambos nodos master tienen el control sobre la zona DRBD, pero sólo uno de ellos, en el que sigue ejecutándose los daemons de Sun Grid master, es susceptible de escribir en la zona, evitando así corrupción de datos.

 

Al volver la conexión de red DRBD detectaría la situación anómala con los dos nodos primary. Llegados a este punto DRBD cuenta con distintas estrategias de recuperación de split-brain, pero dado lo poco probable y delicado del tema preferimos ser avisados vía email y actuar manualmente.

 


13. Tivoli

 

Utilizaremos Tivoli como software de gestión de  las imágenes de sistema de los nodos del cluster. Este software nos permitirá instalar por red una imagen limpia del sistema cada vez que una máquina arranca. Por otro lado el realizar nuevas versiones de la imagen o instalar nuevo software es trivial con este mecanismo.

 

Además de la instalación del sistema en sí, Tivoli permite realizar operaciones previas sobre la máquina utilizando un lenguaje de programación propio denominada Rembo-C. Gracias a ello, podremos añadir nuevas máquinas al cluster inicializando los discos y el sistema de forma desatendida.

 

13.1. Instalación

 

Uno de los motivos de la elección de Tivoli como software de gestión de imágenes es, además de su potencia y versatilidad, la disponibilidad de licencia. El software puede encontrarse en la intranet de distribución de software de la UPC. Por otra parte no existe ninguna otra herramienta libre (Brutalix,…) que permita la flexibilidad que necesitamos.

 

Desde la adquisición de Rembo por parte de IBM en 2006, parte de las funcionalidades que nos interesan (scripts en Rembo-C) han dejado de estar disponibles. Para poder trabajar con Tivoli en modo Rembo es necesario instalar un parche. Descargamos Tivoli de la distribución de software y el parche de la web de IBM.

 

Descomprimimos en /usr/local los paquetes con Tivoli y el parche:

 

master-cluster1> cd /usr/local

master-cluster1> tar xfz  TPMfOSd-Full-5.1.1.0-build-051.39-linux.tar.gz

master-cluster1> tar xfz  TPMfOSd-TKIT-Fix-5.1.1.0-build-053.11-

linux.tar.gz

master-cluster1> cd /usr/local

master-cluster1> tar xfz TPMfOSd-Full-5.1.1.0-build-051.39-linux.tar.gz

master-cluster1> apt-get install mysql-server

 

Ejecutamos el programa de instalación:

 

master-cluster1> cd /usr/local/tpmfos

master-cluster1> ./setup

 

      1. Enter the installation directory [/usr/local/tpmfos]:

              This software requires a large amount of disk space to store client images.

              Please enter the directory where to store these data.

              Data directory [/usr/local/tpmfos/files]:

 

       2. This software can be managed from a web-based console.

              You can choose to use a secure link (HTTPS) to the server console.

              You can also change the default ports. You must also choose the administrator name

              Do you want to use SSL to access the Web interface? [y/n (default y)]:

              Enter the HTTP console port [8080]:

              Enter the HTTPS console port [443]:

              Enter the administrator name [admin]:

 

Configuramos el entorno web de gestión de Tivoli.

 

       3. ln: creando el enlace simbólico «mysql.jar» a «mysql-connector-java-*/mysql-connector-java-*-bin.jar»

      

El enlace lo hemos creado con anterioridad y apunta a nuestro conector mysql ubicado en /usr/java/j2sdk1.4.2_18/jre/lib/ext/mysql-connector-java-3.1.14-bin.jar.

 

       4. This software requires a third party database to store deployment objects.

              Can you provide a MySQL database? [y/n (default y)]:

              Enter the IP address of your MySQL server [127.0.0.1]:

              Enter the port used by your MySQL server on 127.0.0.1 [3306]:

              Enter the name of an existing (empty) database [AutoDeploy]:

              If the database AutoDeploy on server 127.0.0.1 does not exist, please create it now!

              Press return to continue...

              Enter the user name to access the database [root]:

              Enter the password to access the database:

 

Debemos crear una bbdd con el nombre AutoDeploy, aunque en otra versión se llama tpmfosddb.

 

       5. The installation program will now create the configuration file and initialize the server.

              Please wait...

              IBM Tivoli Provisioning Manager for OS Deployment server v.5.1 (000.32)

              Licensed Materials - Property of IBM. L-DDAC-6RLW3E

              (C) Copyright IBM Corporation 1998, 2006.

              All Rights Reserved. IBM, the IBM logo, and Tivoli are trademarks

              of IBM Corporation in the United States, other countries or both.

              ** Rembo server has successfully stopped

              OS deployment server initialized successfully.

              File /opt/tpmfos-5.1/files/global/rad/radb.ini created successfully.

              URL to access database: mysql://127.0.0.1:3306/AutoDeploy?useUnicode=true&characterEncoding=UTF-8

              Username to access the database: root

              Password to access the database: hidden

              Do you want to create startup scripts? [y/n (default y)]:

 

Se crean los scripts de inicio.

     

       6.     File /home/tpmfos/files/global/rad/radb.ini created successfully.

              URL to access database: mysql://127.0.0.1:3306/AutoDeploy?useUnicode=true&characterEncoding=UTF-8

              Username to access the database: root

              Password to access the database: hidden

              Do you want to create startup scripts? [y/n (default y)]:

              ln: creando el enlace simbólico «/etc/rc2.d/S91rembo» a «/etc/init.d/rembo»: El fichero existe

              ln: creando el enlace simbólico «/etc/rc2.d/S92rbagent» a «/etc/init.d/rbagent»: El fichero existe

              ln: el destí «/etc/rc2.d/S90dbgw» no és un directori

              ln: creando el enlace simbólico «/etc/rc5.d/S91rembo» a «/etc/init.d/rembo»: El fichero existe

              ln: creando el enlace simbólico «/etc/rc5.d/S92rbagent» a «/etc/init.d/rbagent»: El fichero existe

              ln: creando el enlace simbólico «/etc/rc5.d/S90dbgw» a «/etc/init.d/dbgw»: El fichero existe

              Startup scripts (rembo, dbgw, rbagent) have been created in /etc/init.d.

              Do you want to start all the services ? [y/n (default y)]:

              Starting Rembo JDBC to ODBC gateway: dbgw.

              Starting IBM Tivoli Provisioning Manager for OS Deployment server: remboStarting IBM Tivoli Provisioning               Manager for OS Deployment Web interface extension: rbagentIBM Tivoli Provisioning Manager for OS Deployment                 Web interface extension v.5.1 (000.32)

              Licensed Materials - Property of IBM. L-DDAC-6RLW3E

              (C) Copyright IBM Corporation 1998, 2006.

              All Rights Reserved. IBM, the IBM logo, and Tivoli are trademarks

              of IBM Corporation in the United States, other countries or both.

              .

              Goodbye!

 

 

Tras responder estas preguntas Tivoli queda instalado con una configuración preliminar.

 

Copiamos el script de inicio en /etc/init.d/ y hacemos que el servicio Tivoli se inicie al arrancar el sistema:

 

master-cluster1> cp /usr/local/tmpfos/scripts/linux/redhat/rembo /etc/init.d/tivoli

master-cluster1> ln -s /etc/init.d/tivoli /etc/rc2.d/S91tivoli

 

Tivoli instala un servidor web que corre en el puerto 8080. En adelante toda interacción con el sistema de imágenes se realizará vía web:

 

http://master-cluster1.lsi.upc.edu:8080

 

Tivoli utiliza el protocolo PXE (Preboot eXecution Environment) para arrancar e instalar los sistemas de las máquinas que gestiona. Este sistema funciona conjuntamente con el protocolo de red DHCP. En las máquinas master contamos con sendos servidores DHCP (ver apartado [16.1]) que se encargan de asignar las direcciones IP a cada una de las máquinas del cluster.

 

Para que Tivoli funcione correctamente con nuestros servidores DHCP es necesario indicar lo siguiente en su fichero de configuración (/etc/dhcp3/dhcpd.conf):

 

option vendor-class-identifier "PXEClient";

 

 

 

 

 

13.2. Configuración

 

Agruparemos las máquinas por "clusters/colas", creando  3 grupos administrativos, eixam, nozomi y tenada, más un grupo con las máquinas servidoras de disco denominado storage. Cada una de las máquinas del cluster debe darse de alta en Tivoli en alguno de estos grupos. Posteriormente podremos personalizar el proceso de instalación de imágenes por grupos si es necesario.

 

El alta de una máquina se hace desde el menú Toolkit®Toolkit Hosts®Register new hosts.

 

Los datos solicitados son la dirección IP y la dirección MAC de la tarjeta de red. Es necesario dar de alta previamente cada máquina en el servidor DHCP con los mismos datos.

 

Una vez dada de alta, se debe configurar la máquina para arrancar por red vía PXE. Esta funcionalidad se configura en la BIOS y varía dependiendo del modelo de ordenador.

 

Tras estos pasos, la máquina está lista para arrancar vía PXE. Durante el arranque de Tivoli, en primer lugar el nodo obtiene una dirección IP por DHCP y posteriormente se establece comunicación entre el nodo y el servidor Tivoli. La figura [13.1] muestra este proceso.

 

 

PXE

 

Figura 13.1: Pantalla de nodo arrancando por PXE

 

 

Por defecto todas las máquinas dadas de alta en Tivoli ejecutan el interfaz de administración, que cuenta con una consola que nos permitirá crear imágenes del sistema en el servidor. En la figura [13.2] se muestra la pantalla con el interfaz de administración de Tivoli.

 

La idea es configurar una máquina tipo para  una vez que sea estable y cuente con todos los servicios necesarios, arrancar vía PXE el interfaz de administrador y crear una imagen de sistema. Posteriormente esta imagen de sistema se instalará por red en todas las máquinas del cluster en el momento de arrancar. Tras finalizar el proceso de copia del sistema, la máquina arrancará y personalizará el sistema en función de su rol dentro del cluster, como se detalla en el apartado [13.4].

 

 

Tivoli

 

Figura 13.2: Interfaz de administración de Tivoli

 

 

Este mecanismo nos permite actualizar el sistema de los nodos de computación simplemente reiniciándolos cuando no tengan trabajos asignados. Los nodos servidores de disco también se actualizan reiniciándolos, teniendo la precaución de no reiniciar al mismo tiempo los dos nodos de un mismo AFR, lo cual provocaría la pérdida de acceso a la parte de datos que sirviesen. Una estrategia válida podría ser rebotar en primer lugar los nodos servidores de disco pares (disc2, disc4  y disc6) y una vez éstos hubiesen arrancado con el nuevo sistema reiniciar los impares (disc1, disc3 y disc5).

 

13.3. Creación de una imagen

 

Desde la consola en el interfaz de administración de Tivoli en la máquina de referencia copiamos en el servidor una copia de la partición que incluye el sistema operativo y dos ficheros, el kernel y el initial ramdisk, que nos permitirán arrancar la máquina una vez finalice el volcado del sistema:

 

BuildDiskImage(0,1,"net://global/hdimages/node.img");

CopyFile("disk://0:1/boot/vmlinuz-2.6.18","net://global/hdimages/vmlinuz-2.6.18-gluster");

CopyFile("disk://0:1:/boot/initrd.img-2.6.18","net://global/hdimages/initrd.img-2.6.18-gluster");

 

Tivoli cuenta con un potente lenguaje de programación que permite realizar muchas más operaciones además de crear y volcar imágenes. Utilizaremos Rembo-C para particionar de forma inteligente las máquinas antes de volcar el sistema. Estos scripts se guardan en el servidor y son invocados en lugar del interfaz de administrador cuando se indica explícitamente. Pueden consultarse en los apéndices [19.1.12].

 

13.4. Personalización de imágenes

 

En los capítulos anteriores hemos explicado cómo instalar y configurar los servicios necesarios para el correcto funcionamiento del cluster. En este apartado veremos los mecanismos necesarios para automatizar el proceso de configuración de nodos.

 

El script de arranque de Tivoli detecta el número de discos, si bien utilizamos como máximo 2 de ellos (en RAID) y comprueba si se trata de discos inicializados. Una máquina con discos inicializados es una máquina que ya forma parte del cluster y en la que no hay que tocar el particionamiento pues se podrían perder datos.

 

Tivoli, al detectar una máquina nueva (ningún disco inicializado), particiona sus discos de la siguiente manera:

 

partición 1: EXT2       20 GB
partición 2: SWAP        4 GB
particion 3: RAID       TAMAÑO TOTAL - TAMAÑO particion1 - TAMAÑO

particion2 - 1MB

 

Se crean un total de 3 particiones. Al arrancar el sistema operativo, el script de personalización de imagen post_boot.sh creará una cuarta en cada uno de sus discos que los marcará como "inicializados". En posteriores arranques, la existencia de esta cuarta partición hará que Tivoli se limite a restaurar la imagen de sistema sin más.

 

La casuística que se contempla a la hora de restaurar la imagen en una máquina es la siguiente:

 

1. Nodo nuevo (ningún disco inicializado)

 1.1. Con 1 disco

      * InicializarDisco(0)

 1.2. Con > 1 disco

    1.2.1. Discos de mismo tamaño

           * InicializarDisco(0)

           * InicializarDisco(1)

           * RestaurarSistema

           * ArrancarLinux

    1.2.2. Discos de distinto tamaño

           * ObtenerDiscoDeMenorTamaño

           // inicializamos los discos con el particionamiento del disco

           // de menor tamaño

           * InicializarDisco(0)

           * InizializarDisco(1)

           * RestaurarSistema

           * ArrancarLinux

 

2. Nodo del cluster (algún disco inicializado)

 2.1. Con 1 disco

          * RestaurarSistema

           * ArrancarLinux

 2.2. Con > 1 disco

   2.2.1. Dos discos inicializados

           * RestaurarSistema

           * ArrancarLinux

   2.2.2. Un disco no inicizaliado

     2.2.2.1. Tamaño(disco no inicializado) < Tamaño(disco inicializado)

              * ERROR, el disco nuevo debe ser mayor o igual que el disco inicializado

     2.2.2.2. Tamaño(disco no inicializado) >= Tamaño(disco inicializado)

              * InicializarDisco(disco no inicializado)

 

InicializarDisco(IdDisco) {

 

  * ObtenerTamañodiscoMenor

  * ParticionarDisco(IdDisco)

 

}

 

DiscoInicializado?(IdDisco) retorna BOOL {

 

  si (NumParticiones(IdDisco)<4)

     retorna FALSO;

  sino

     si (TipoPartition(IdDisco,4) == "f0")

         retorna TRUE;

     sino

         retorna FALSE;

     fsi

 fsi

 

}

 

El script rembo que controla la instalación de imágenes en los nodos bootnode-gluster.shtml se encuentra en los apéndices [19.1.12].

 

Una vez el sistema operativo se restaura en un nodo y éste arranca, se lleva a cabo la personalización del sistema en función de la identidad del nodo y su rol dentro del cluster, que llevará a cabo el script /etc/init.d/post_boot.sh. Para ello se basará en la información almacenada en fichero /root/files/nodes/nodes de los nodos master, que es una pequeña base de datos con la información de todos los nodos dados de alta.

 

Este formato del fichero de nodos es el siguiente:

 

# Listado de nodos

#

# Indica, para cada nodo, si forma parte de un OST y, en tal caso, si se

# trata de un nodo (P)rimario o (S)ecundario y quién es su pareja.

#

# Atención: Dar de alta primero a nodo primario y, posteriormente, una vez

# exporten el OST, a su secundario

#

#

# HOSTNAME   OST?   (P)ri/(S)ec   PAIRNODE        CLUSTER     MCAST_CHANNEL

# --------   ----   -----------   --------        -------     -------------

disc1      SI          P         disc2          storage      239.2.11.75

disc2      SI          S         disc1          storage      239.2.11.75

disc3      SI          P         disc4          storage      239.2.11.75

disc4      SI          S         disc3          storage      239.2.11.75

disc5      SI          P         disc6          storage      239.2.11.75

disc6      SI          S         disc5          storage      239.2.11.75

node200    NO          -         -              tenada       239.2.11.74

node102    NO          -         -              eixam        239.2.11.72

node301    NO          -         -              nozomi       239.2.11.73

node303    NO          -         -              nozomi       239.2.11.73

node104    NO          -         -              eixam        239.2.11.72

node105    NO          -         -              eixam        239.2.11.72

 

 

Tras el hostname, el campo OST? indica si el nodo en cuestión es servidor de disco. De ser "SI" el siguiente campo indicará si es un nodo primario o secundario. El siguiente campo indica qué nodo es su pairnode, es decir, el nodo con el que mantiene sus datos replicados.

 

Los dos últimos campos sirven al sistema de monitorización Ganglia para incluir el nodo en uno de los grupos y para establecer el canal multicast de comunicación con el resto de sus compañeros.

 

El script post_boot.sh copia información actualizada de los nodos master (fichero nodos, configuración de GlusterFS, usuarios, ganglia, crons, etc) y personaliza el sistema en función de la información almacenada el el fichero nodes. La casuística es la siguiente:

 

1. Ningún disco inicializado.

    1.1. Dos discos no inicializados

           1.1.1. Nodo no es servidor de disco

                     // nodo es cliente glusterFS

                    * Montamos zona common de SunGrid

                    * Montamos HOME glusterFS

           1.1.2. Nodo es servidor de disco

                     // nodo es servidor glusterFS

                    * Creamos array HOME

                    * Marcamos los discos como inicializados

                    * Montamos zona common de SunGrid

                    * Montamos HOME glusterFS

                    * Lanzamos daemon glustrerFS

    1.2. Nodo con un disco

          // nodo es cliente glusterFS

          * Montamos zona common de SunGrid

          * Montamos HOME glusterFS

    1.3. Nodo sin discos

           * ERROR

2. Dos discos inicializados

     2.1. Nodo no es servidor de disco

            // nodo es cliente glusterFS

           * Montamos zona common de SunGrid

           * Montamos HOME glusterFS

     2.2. Nodo es servidor de disco

            // nodo es servidor glusterFS

            * Lanzamos daemon glusterFS

 

Por último, en caso de tratarse de un nodo nuevo, el script lo añade a la cola correspondiente en Sun Grid con tantos slots como cores tenga la máquina. El script post_boot.sh se encuentra en los apéndices [19.1.13].

 


14. Ganglia

 

 

Ganglia es un sistema de monitorización de clusters vía web. Utiliza tecnologías como XML para la representación de los datos, XDR para compactar y mover los datos y RRDTool para el almacenamiento y la visualización. Como está pensado para trabajar con clusters formados por una gran cantidad de nodos, utiliza algoritmos y estructuras de datos que generan overheads muy pequeños entre nodos y proporcionan una alta concurrencia. Ganglia es altamente escalable, siendo capaz de monitorizar sin problemas clusters con miles de nodos.

 

Está formado por 5 componentes:

 

ganglia-dataflow

 

Figura 14.1: Daemons y flujo de datos en un sistema Ganglia

 

 

·        gmond: Es el demonio de monitorización. Se trata de un servicio ligero que se instala en todas las máquinas que queremos monitorizar. Este demonio utiliza el protocolo XDR para recoger información del estado y enviarla vía XML sobre TCP.

 

·        gmetad: Este daemon es el encargado de recolectar información servida por otros gmetad y gmond y almacena su estado en bases de datos indexadas de tipo round-robin (rrd). Gmetad provee un mecanismo sencillo para disponer de información histórica de un conjunto de máquinas.

 

·        gmetric: La Ganglia metric tool es una aplicación tipo línea de comandos que permite inyectar métricas personalizadas sobre hosts que son monitorizados por ganglia.

 

·        gstat: Es una aplicación que permite interactuar con Ganglia directamente y obtener información sobre las métricas almacenadas.

 

·        web: El frontend web expresa la información almacenada por gmetad en un interfaz web gráfico usando PHP.

 

La figura [14.1] muestra los daemons anteriormente descritos así como otros subsistemas involucrados y el flujo de datos entre ellos.

 

14.1. Instalación

 

Ganglia está disponible como paquete de software del repositorio oficial de Debian. En la distribución el software Ganglia viene separado en dos partes: ganglia-monitor, que incluye el núcleo de monitorización y el daemon encargado de recolectar de forma local los datos en cada nodo,  y gmetad, el daemon que comunica los distintos nodos.

 

Los instalamos del repositorio oficial Debian:

 

master-cluster1> apt-get install ganglia-monitor gmetad

 

Ganglia utiliza la web como medio para mostrar la información del estatus del cluster, por lo que es necesario contar con un servidor web. Instalamos el servidor web Apache[12], por ser el servidor web de uso más común en entornos UNIX y la preferencia en el Laboratorio de Cálculo.

 

Instalamos apache y los paquetes adicionales necesarios:

 

master-cluster1> apt-get install apache2 libapache2-mod-php5

 

La instalación de apache deja un servidor web operativo corriendo en el puerto 80, con los ficheros de configuración en /etc/apache2 y el repositorio web en /var/www.

 

Hacemos visible ganglia para nuestro servidor web. Para ello creamos el fichero /etc/apache2/sites-available/ganglia:

 

DocumentRoot /var/www/

 

<Directory /var/www/ganglia>

Options FollowSymLinks MultiViews

       AllowOverride None

       Order allow,deny

allow from all

</Directory>

 

Y creamos el link simbólico desde /etc/apache2/sites-enabled/ganglia. Por último hacemos un reload del servidor para que lea la nueva configuración:

 

master-cluster1> /etc/init.d/apache2 reload

 

14.2. Configuración

 

Hay dos daemons que controlan la recogida y almacenamiento de datos generados por los nodos del cluster: gmond y gmetad. Como hemos explicado, gmond es el encargado de recolectar la información local del host y compartirla vía TCP, mientras que gmetad recoge la información exportada por otros hosts y la almacena en una base de datos rrd.

 

 

Figura 14.2: Pantalla principal de  la web Ganglia

 

Configuramos las distintas colas, los nodos de almacenamiento y los nodos master como grupos segregados que se monitorizan de forma independiente. Cada uno de estos grupos comparte la información generada por gmond con el resto de máquinas de su grupo y con los nodos master. La comunicación de cada grupo se realiza por canales multicast, lo que garantiza un menor overhead de tráfico de red.

 

En los nodos de entrada master-cluster1 y master-cluster2, hay sendos demonios gmetad que recogen información de cada grupo. Igualmente, cada grupo cuenta con dos daemons gmetad que recogen la información de los nodos de su grupo. Instalamos el gmetad en dos máquinas para poder disponer de la información del grupo si uno de los dos nodos con gmetad caen.

 

La siguiente tabla muestra los distintos grupos multicast con sus direcciones de red:

 

Master nodes            239.2.11.71

eixam                   239.2.11.72

nozomi                  239.2.11.73

tenada                  239.2.11.74

storage                 239.2.11.75

 

Los ficheros gmond.conf y gmetad.conf que controlan los daemons gmond y gmetad respectivamente se encuentran en los apéndices [19.1.4] y [19.1.15].

 

14.3. Personalización

 

La información que proporciona Ganglia por defecto es enorme, pero echamos en falta información específica del sistema de colas. Por ello crearemos algunas métricas que mediante shellscripts permitan conocer el estatus del cluster: trabajos en ejecución y trabajos encolados.

 

Una métrica de Ganglia no es más que un valor numérico con una etiqueta enviado por TCP a una canal multicast mediante el comando gmetric. Este valor es recogido por el daemon gmetad y almacenado en una base de datos rrd. Posteriormente el motor Ganglia transformará los valores numéricos almacenados en información gráfica, si así lo configuramos.

14.3.1. Trabajos en ejecución:

 

Obtenemos el número de trabajos en ejecución en cada nodo mediante el script jobs_run.sh, que puede consultarse en los apéndices [19.1.16].

 

Incorporaremos el comando gmetric a un cron de root que irá enviando la información a intervalos regulares de 1 minuto:

 

# JOBS en cola prioritaria

* * * * *       /usr/bin/gmetric --name sge_jobs_run --value `/root/scripts/jobs_run.sh 2> /dev/null` -tint16 --units=procs --mcast_channel=239.2.11.72 --mcast_port=8649 --mcast_if=eth0 2> /dev/null

 

En cada cluster habrá que cambiar el canal muticast por el que corresponda. Además de monitorizar los trabajos en ejecución, monitorizamos los trabajos que se ejecutan en colas "nice", que obtenemos con el script jobs_run-slave.sh, disponible en los apéndices [19.1.17].

 

Asimismo añadimos un cron que envíe el número de trabajos en el nodo cada minuto:

 

# JOBS en cola subordinada

* * * * *       /usr/bin/gmetric --name sge_jobs_run-slave --value `/root/scripts/jobs_run-slave.sh 2> /dev/null` -tint16 --units=procs --mcast_channel=239.2.11.72 --mcast_port=8649 --mcast_if=eth0 2> /dev/null

 

El resultado es el que se muestra en la figura [ 14.3].

 

 

jobs_running

 

Figura 14.3:Gráfica de la métrica jobs_running

 

14.3.2. Trabajos encolados

                                                                                                                                       

Otra métrica interesante asociada al sistema de colas es el número de trabajos encolados. Este valor lo calcularemos en los nodos master mediante el script jobs_queued.sh. Puede encontrarse en los apéndices [19.1.18].

 

De la misma forma que hacíamos con los trabajos en ejecución, creamos una entrada en el cron de root que envíe el número de trabajos en colados al gmetad cada minuto:

 

* * * * *       /usr/bin/gmetric --name jobs_queued --value `/root/scripts/jobs_queued.sh` -tint16 --units=procs

 

 

jobs_queued

 

Figura 14.4: Gráfica de la métrica jobs_queued

 

14.3.3. Sensor de temperatura

 

La temperatura de la CPU debe mantenerse dentro de unos valores nominales. Superar cierto límite provocará de manera irremediable el fallo del nodo.

 

Creamos una nueva métrica con el valor de la temperatura de la CPU de cada nodo. Esto nos permitirá adelantarnos a posibles fallos por sobrecalentamiento cuando por ejemplo, un ventilador falle.

 

A tal efecto creamos el script temp_max.sh que devuelve la temperatura del core con el valor más alto. Su contenido puede consultarse en los apéndices [19.1.19]. Previamente el script carga el módulo de monitorización de sensores adecuado en función del tipo de CPU y del chipset detectado.

 

temperature_max.jpg

 

Figura 14.5: Gáfica de la métrica temperature_max

 

El siguiente paso es añadir el valor obtenido por esta métrica a la base de datos rrd. Como con el resto de métricas personalizadas lo hacemos utilizando el comando gmetric a intervalos de 1 minuto mediante la programación de un cron:

 

 

# Sensors

* * * * *       /usr/bin/gmetric --name temperature_max --value `/root/scripts/temp_max.sh 2> /dev/null` -tint16 --units=degrees --mcast_channel=239.2.11.72 --mcast_port=8649 --mcast_if=eth0 2> /dev/null

 

Como resultado tendremos una nueva métrica llamada temperature_max dentro de la web ganglia disponible para cada nodo del cluster.

14.3.4. Personalización web

 

El siguiente paso es procesar y mostrar en la web de Ganglia la información de las métricas que hemos creado y que se encuentran almacenadas en las bases de datos rrd. El frontend de Ganglia está programado en PHP y es fácilmente modificable.

 

En el directorio /var/www/ganglia está el código PHP con las funciones de procesamiento y visualización de los datos y en /var/www/ganglia/template los perfiles que dan forma a la web.

 

En primer lugar creamos un nuevo perfil "LSI" basado en el perfil por defecto, añadiendo la información extra que queremos mostrar. El perfil está formado por ficheros HTML con la disposición de los distintos elementos que aparecen en cada una de las páginas web de Ganglia. Modificamos los siguientes ficheros:

 

·        cluster_extra.tpl: Añadimos código que invoca a la función php que muestra el número de trabajos en ejecución del grupo en el caso de colas y el número de trabajos encolados en el caso del grupo Master nodes.

 

·        meta_view.tpl: Añadimos información acerca del volumen GlusterFS en la página principal.

 

El contenido íntegro de ambos ficheros está en los apéndices [19.1.20] y [19.1.21].

 

La función php que dibuja en pantalla las gráficas se encuentra en el archivo graph.php. Añadimos el código necesario para dibujar en pantalla las gráficas que representan los datos generados por nuestras métricas. El fichero graph.php se encuentra en los apéndices [19.1.22].

 

La figura [14.6] muestra la vista general del cluster, con una fila para cada grupo de máquinas: nodos master, colas eixam, nozomi y tenada y servidores de disco. La fila superior es un sumatorio de los recursos de todos los grupos.

 

 

 

 

Figura 14.6: Vista general del cluster

 

 

Las cuatro columnas de gráficas  muestran diferentes recursos de las colas: la carga de CPU, la utilización de la memoria, el tráfico de red e información acerca de los trabajos del sistema de colas.

 

Para cada cola se muestra el número de trabajos en ejecución  (color azul) y en ejecución en modo nice (color verde). La línea roja marca el número máximo de slots disponibles y por tanto el número máximo de trabajos concurrentes en ejecución.

 

El grupo de nodos master en el campo dedicado al sistema de colas muestra el número de trabajos en la cola de espera.

 

Adicionalmente, se muestra, en la fila correspondiente a cada cola, el espacio total y el espacio libre de la zona de disco compartida.

 

La figura [14.7] muestra el estado de una cola, con un resumen de los principales recursos: carga del sistema, uso de CPU, utilización de memoria y de red en la parte superior y el estado de los diferentes nodos que componen el cluster a continuación.

 

 

 

 

 

Cada nodo aparece coloreado según su carga. De esta forma podemos advertir estados altos de carga (color rojo) rápidamente, sin entrar a comprobar el valor numérico concreto.

 

 

 

ganglia-cluster.tiff

 

Figura 14.7: Vista de una cola

 

 

La gráfica de cada nodo muestra una métrica seleccionable desde el menú Metric de la cabecera. Por defecto se muestra la carga del sistema, pero pueden seleccionarse multitud de otras métricas, entre ellas las que hemos creado ad-hoc, como sge_jobs_run, sge_jobs_run-slave o temperature_max.

 

En la parte izquierda aparece la gráfica de trabajos en ejecución, así como información porcentual de la carga del sistema.

 

 

 

 

 

 

La figura [14.8] muestra la información de tallada de un nodo, con un resumen textual y las consabidas gráficas de carga, uso de CPU, uso de memoria y tráfico de red en la parte derecha.

 

En la parte inferior se despliegan las gráficas de todas las métricas.

 

 

ganglia-nodo.tiff

 

Figura 14.8: Vista de un nodo

 

 


15. Nagios

 

Nagios es un sistema de monitorización de redes para entornos UNIX. Examina periódicamente hosts y servicios, avisándonos cuando se produce algún comportamiento inesperado y volviendo a avisarnos cuando el servicio vuelve a la normalidad. Está especialmente indicado en la monitorización de redes con gran cantidad de componentes.

 

Nagios es la herramienta que utiliza el Laboratorio de Cálculo de LSI para monitorizar todos sus servidores y servicios.

 

En los clientes Nagios el daemon nrpe recoge las peticiones enviadas desde el servidor e invoca el plugin apropiado para obtener el valor asociado al estatus del recurso monitorizado. Cuando se produce un fallo en alguno de los servicios monitorizados el sistema nagios envía un aviso al administrador.

15.1. Instalación

 

Es necesario instalar el cliente nagios en cada uno de los hosts que queremos monitorizar. En nuestro caso lo instalamos en las dos máquinas master-cluster. De esta manera si se produce el fallo de una de las dos máquinas seguiremos pudiendo monitorizar el cluster.

 

Master-cluster1> apt-get install nagios-nrpe-server

 

15.2. Configuración

 

Monitorizaremos por una parte el estatus del servicio Sun Grid en las máquinas master (sge_master) y en los nodos de cómputo (sge_execd) y por otra la conectividad de red de los nodos servidores de disco. Esto último se hace mediante el plugin nrpe_ping, que forma parte del paquete nagios.

 

15.2.1. Configuración en cliente

 

En primer lugar es necesario configurar el cliente nagios indicando la dirección IP del servidor. Además, dado que utilizaremos un plugin que acepta parámetros, debemos indicar que queremos aceptar este tipo de plugins.También configuramos un nuevo comando que nos permitirá conocer el estatus del servicio Sun Grid mediante el script check_sge.sh.

 

Monitorizamos el servicio Sun Grid mediante el plugin check_sge.sh. Puede consultarse en los apéndices [19.1.23].

 

 

 

Los plugins nagios son scripts que deben acabar con uno de los siguientes exit status:

 

·        0: El servicio funciona correctamente.

·        1: Warning. El servicio presenta algún tipo de anomalía.

·        2: Error. El servicio no funciona.

 

La salida estándar puede ser utilizada como un medio para obtener información extra sobre el estatus del servicio, por ejemplo el motivo del fallo.

 

El plugin check_sge.sh acepta como parámetro el hostname del nodo que queremos chequear.

 

En función del hostname comprobaremos si el servicio sge_master o el servicio sge_execd está corriendo.

15.2.2. Configuración en servidor

 

La configuración del servidor nagios está formada por una serie de ficheros donde se definen los recursos a monitorizar, los comandos que se utilizarán para ello y los administradores responsables de los servicios a los que se avisará en caso de fallo.

 

El servidor Nagios departamental es la máquina karpov.lsi.upc.edu. Se trata de una máquina con sistema Linux Debian en la que se ha instalado el software nagios de Debian. Así pues, encontramos los ficheros de configuración en /etc/nagios.

 

En primer lugar definimos el cluster como un servicio a monitorizar. Para ello añadimos la información de las dos máquinas master-cluster a los ficheros hostgroup.cfg y hosts.cfg:

 

hostgroup.cfg:

 

define hostgroup{

hostgroup_name  cluster

alias           Cluster Servers

members         master-cluster1,master-cluster2

contact_groups  admins,cluster-admins

        }

 

hosts.cfg:

 

define host{

use                     generic-host

host_name               master-cluster1

alias                   master-cluster1

address                 147.83.20.221

check_command           check-host-alive

max_check_attempts      10

notification_interval   120

notification_period     24x7

notification_options    d,r

        }

 

define host{

use                     generic-host

host_name               master-cluster2

alias                   master-cluster2

address                 147.83.20.222

check_command           check-host-alive

max_check_attempts      10

notification_interval   120

notification_period     24x7

notification_options    d,r

}

 

Monitorizamos el estado de cada uno de los nodos de computación del cluster y de los propios nodos master mediante el comando check_sge. Para ello creamos tantos servicios como nodos hay en el cluster. Lo hacemos en el fichero services.cfg:

 

define service{

use                             generic-service         ; Name of service template to use

host_name                       master-cluster1,master-cluster2

service_description             node100

is_volatile                     0

check_period                    24x7

max_check_attempts              4

normal_check_interval           5

retry_check_interval            1

contact_groups                  admins,cluster-admins

notification_interval           960

notification_period             24x7

check_command                   check_nrpe_param2!check_sge!node100

}

 

Repetimos esta configuración para todos los nodos de computación del cluster. A destacar que el comando de chequeo tiene dos parámetros: el nombre del plugin y el parámetro de éste que indica el nodo que se está examinando. Debemos definir un nuevo comando de chequeo que acepte dos parámetros, ya que por defecto nagios no lo incluye. Lo definimos en el fichero de configuración checkcommands.cfg:

 

define command{

command_name    check_nrpe_param2

command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a $ARG2$ $ARG3$ $ARG4$

}

 

Para los nodos de disco creamos un servicio de monitorización de conectividad mediante el plugin check_ping:

 

define service{

use                             generic-service         ; Name of service template to use

host_name                       master-cluster1,master-cluster2

service_description             Disc1

is_volatile                     0

check_period                    24x7

max_check_attempts              4

normal_check_interval           5

retry_check_interval            1

contact_groups                  admins,cluster-admins

notification_interval           960

notification_period             24x7

check_command                   check_nrpe_param2!check_ping!disc2!99,99%!100,100%

}

 

Repetimos esta configuración para todos los nodos servidores de disco del cluster.

 

El Laboratorio de Cálculo dispone del un frontend web, que permite una fácil gestión de la información generada por nagios. También permite gestionar los avisos, deshabilitar chequeos, etc. Todos los servicios configurados en nagios quedan reflejados automáticamente en la web, accesible desde http://karpov.lsi.upc.edu/nagios.

 

La figura [15.1] muestra el estatus de los servicios del cluster en la web Nagios.

 

 

 

Figura 15.1: Vista de la web Nagios


16. Servicios auxiliares

 

Una vez vistos los servicios propios del cluster, vamos a tratar una serie servicios auxiliares necesarios para su correcto funcionamiento.

 

Queda fuera del objetivo de este proyecto tratar en profundidad la configuración de estos servicios, con los que se asume cierta familiaridad como administrador de sistemas, por lo que nos limitaremos a concretar las particularidades de nuestra configuración.

 

16.1. DHCP

 

DHCP (Dynamic Host Configuration Protocol) es un protocolo de red que permite a las máquinas de una red obtener la configuración de red automáticamente.

 

En el cluster los nodos se identifican por su dirección IP, que determina el rol que juegan, servidor de disco o nodo de computación. La dirección IP de un nodo es siempre la misma desde el momento en que se fija al darlo de alta. Por ello utilizamos asignación de IPs manual (o estática), que asigna la siempre la misma dirección IP en función de la dirección MAC de la tarjeta de red.

16.1.1. Instalación

 

Instalamos el servidor DHCP en las máquinas master-cluster y el cliente  en el resto de nodos:

 

master-cluster1> apt-get install dhcp3-server

 

node100> apt-get installl dhcp-client

16.1.2. Configuración del servidor

 

La configuración del servidor DHCP[13] reside en /etc/dhcp3/dhcpd.conf. Añadimos la información acerca del rango de IPs que vamos a servir y creamos un nuevo grupo en el que fijamos la dirección IP de cada nodo a su dirección MAC.

 

Para que Tivoli funcione correctamente en conjunción con el servidor DHCP es necesario añadir la directiva PXEclient.

 

El fichero de configuración dhcpd.conf se encuentra en los apéndices [19.1.24].

 

La adición de nuevos nodos supone, en primer lugar, la asignación de una dirección IP. Esta tarea se lleva a cabo desde el script de alta de nodo, que se trata el apartado dedicado a tareas administrativas [17.1].

 

Utilizamos cuatro rangos de IPs, uno para las máquinas master-cluster y servidores de disco y otro para las máquinas de cada cola (eixam. nozomi y tenada):

 

Hostname          Función           @IP

master-cluster1   master            192.168.0.201

master-cluster2   master            192.168.0.202

disc1             disco             192.168.0.101

...

Disc199           disco             192.168.0.199

node100           eixam             192.168.1.100

...

node199           eixam             192.168.1.199

node200           tenada            192.168.2.100

...

node299           tenada            192.168.2.199

node300           nozomi            192.168.3.100

...

node399           nozomi            192.168.3.199

16.1.3. Configuración de los clientes

 

En el archivo de configuración de red /etc/network/interfaces indicamos que la configuración del interfaz eth0 se hace mediante dhcp:

 

# This file describes the network interfaces available on your system

# and how to activate them. For more information, see interfaces(5).

 

# The loopback network interface

auto lo

iface lo inet loopback

 

# The primary network interface

auto eth0

 

iface eth0 inet dhcp

 

De esta forma al arrancar el nodo, la red quedará configurada automáticamente:

 

node100> /sbin/ifconfig

eth0      Link encap:Ethernet  HWaddr 00:1C:23:E3:0C:58

          inet addr:192.168.1.100  Bcast:192.168.255.255  Mask:255.255.0.0

          inet6 addr: fe80::21c:23ff:fee3:c58/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:853664758 errors:0 dropped:82 overruns:0 frame:17

          TX packets:917038883 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:2029030137 (1.8 GiB)  TX bytes:2386219895 (2.2 GiB)

          Interrupt:169

 

16.2. Exim

 

Exim es un MTA (Mail Transfer Agent) desarrollado por la Universidad de Cambridge. Como la mayoría de los servidores de correo además de MTA es capaz de funcionar también como MSA (Mail Submision Agent).

 

Brevemente, el funcionamiento del sistema de correo electrónico es el siguiente: una aplicación de usuario (MUA) envía un mensaje de correo electrónico que recibe el MSA (Mail Submission Agent) y lo envía al MTA (Mail Transfer Agent). El MTA es la parte más importante del sistema de correo. Se encarga de hacer llegar el mensaje del dominio origen al servidor de correo (MTA) del dominio destino. Finalmente el MDS (Mail Delivery Agent) deja el mensaje de correo en el mailbox apropiado.

 

La misión de Exim dentro del cluster será gestionar el envio de correos y avisos administrativos generados en cada nodo.

16.2.1. Instalación

 

Instalamos Exim[14] en todas las máquinas del cluster:

 

master-cluster1> apt-get install exim4 exim4-config

 

El paquete exim4-config incluye un frontend que facilita la configuración de Exim como MTA y como MSA en casos sencillos como el que nos ocupa.

16.2.2. Configuración

 

Exim es capaz de funcionar como MTA y como MSA. Las máquinas master-cluster1 y master-cluster2 funcionarán como relay de correo para el resto de nodos, reenviando el correo el correo que generado en la intranet al servidor de correo departamental.

 

En los nodos de computación y los servidores de disco configuramos Exim como MSA, haciendo que se reenvíe su correo a cualquiera de los nodos master-cluster.

 

La configuración puede hacerse mediante el frontend ejecutando el comando dpkg-reconfigure exim4-config o editando el fichero /etc/exim4/update.exim4.conf.

 

La configuración del sistema de correo de los nodos master y del resto de nodos se encuentra en los apéndices [19.1.25] y [19.1.26].

 


16.3. NTP

 

La sincronización del tiempo es un tema de vital importancia cuando tenemos un conjunto de máquinas que queremos que se comporten como una sola. Además, el hecho de contar con un sistema de ficheros distribuido obliga a mantener el tiempo de los nodos perfectamente sincronizados.

 

La sincronización de los relojes de las máquinas del cluster se lleva a cabo mediante el protocolo NTP (Network Time Protocol). En nuestro cluster las máquinas master-cluster actuarán como servidoras de tiempo para los nodos. Las propias máquinas master-cluster sincronizarán su tiempo, a su vez con el servidor de tiempo departamental.

 

El hecho de contar con servidores de tiempo propios permite al cluster mantener la hora sincronizada permanentemente independientemente de cualquier fallo externo.

16.3.1. Instalación

 

El daemon NTP y las utilidades de gestión asociadas están incluidas en el paquete ntp. Lo instalamos en todas las máquinas del cluster:

 

master-cluster1> apt-get install ntp

 

El servicio NTP queda configurado para iniciarse al arrancar la máquina.

16.3.2. Configuración

 

La instalación deja la configuración en el fichero /etc/ntp.conf.

 

Las máquinas master-cluster sincronizan su hora con el servidor de tiempo de lsi ntp.lsi.upc.edu y con alguno más en caso de fallo de éste. Además como actúan de servidor de hora para los nodos del cluster, se debe activar broadcast a la red privada del cluster. El fichero de configuración /etc/ntp.conf que controla el servicio de tiempo en los nodos master-cluster se encuentra en el apéndice [19.1.27].

 

Los nodos obtienen el tiempo de los nodos master-cluster y su ntp actúa sólo como cliente. Nuevamente el fichero de configuración puede encontrarse en el apéndice [19.1.28].

 

16.4. Dsh

 

Dsh (distributed shell o dancer's shell) es una utilidad que permite ejecutar comandos en varias máquinas remotas a la vez, lo que en la práctica sería un bucle de ejecuciones remotas.

 

Lo utilizaremos desde las máquinas master-cluster para realizar tareas administrativas en grupos de máquinas o en la totalidad del cluster.

 

16.4.1. Instalación

 

Instalamos dsh desde el repositorio de software de Debian en las dos máquinas master-cluster:

 

master-cluster1> apt-get install dsh

 

La instalación deja la configuración en /etc/dsh.

16.4.2. Configuración

 

dsh por defecto ejecuta los comandos remotos mediante rsh, si bien es posible hacer que utilice ssh. Lo cambiamos en el fichero de configuración /etc/dsh/dsh.conf:

 

#default configuration file for dsh.

# suppled as part of dancer's shell

verbose = 0

remoteshell =ssh

showmachinenames = 1

waitshell=1  # whether to wait for execution

#remoteshellopt=...

# default config file end.

 

La configuración de dsh incluye un directorio groups en el que podemos crear ficheros de texto con hostnames de grupos de máquinas. En nuestro caso creamos un grupo para cada cola, uno más para las máquinas servidoras de disco, y un último grupo para las máquinas master-cluster:

 

master-cluster1:/etc/dsh/groups>  ls -la

total 32

drwxr-xr-x 2 root root 4096 2008-09-17 15:52 .

drwxr-xr-x 3 root root 4096 2009-01-02 12:15 ..

lrwxrwxrwx 1 root root   16 2008-08-26 15:29 all -> ../machines.list

-rw-r--r-- 1 root root  153 2008-09-18 17:11 eixam

-rw-r--r-- 1 root root   32 2008-04-02 16:58 masters

-rw-r--r-- 1 root root  104 2008-09-29 16:59 nozomi

-rw-r--r-- 1 root root   36 2008-09-17 15:08 storage

-rw-r--r-- 1 root root   64 2008-09-29 16:59 tenada

 

El fichero machines.list incluye las máquinas de todos los grupos y es útil cuando queremos ejecutar comandos en todas las máquinas.

 

El funcionamiento de dsh es sencillo:

 

master-cluster1> dsh -a comando

 

Ejecuta el comando indicado en todas las máquinas del cluster.

 

master-cluster1> dsh -g nombre_grupo comando

 

Ejecuta el comando indicado en las máquinas de un grupo concreto.

 

La ejecución de los comandos en cada una de las máquinas se realiza con conexiones ssh secuenciales. Es posible realizarlas todas de forma concurrente mediante la opción -c.

 

16.5. Backup

 

El Laboratorio de Cálculo de LSI cuenta con un sistema de backups departamental como respaldo de datos de usuario y sistemas de los  servidores. Los backups  permiten disponer de una copia más o menos reciente de la información en caso de fallo en los sistemas de almacenamiento o de borrado accidental.

 

Durante el mes de enero de 2009 incorporaremos el cluster al servicio de backups, realizando copia de los sistemas de las máquinas master-cluster y de la zona de disco distribuido. Para ello se ha comprado un robot SUN StorageTek SL24 Tape Autoloader que contendrá también copias de los servidores de proyecto.

16.5.1. Instalación

 

El software utilizado para la realización de los backups es Sun StorageTek Enterprise Backup Sogftware v7.3., disponible en un CD de instalación para múltiples plataformas. Para su instalación basta con descomprimir el fichero tar correspondiente a nuestra plataforma. Lo instalamos las dos máquinas master-cluster:

 

master-cluster1> cd /

master-cluster1> tar xfz /root/files/lgtoclnt-7.4-1.i686.tgz

16.5.2. Configuración

 

En este apartado abordaremos la parte cliente de la configuración, ya que la configuración de  la parte servidor queda fuera del ámbito de administración del cluster.

 

El cliente de backup se configura como un daemon que se ejecuta al arrancar la máquina y permanece en ejecución atendiendo las peticiones del servidor. Hacemos que el cliente se inicie al arrancar la máquina master-cluster2 incluyendo el inicio del servicio de backup en  el script /etc/init.d/rc.sistemes:

 

/usr/sbin/nsrexecd -s nsrhost -s nsrserverhost -s nemesis -s davinci

 

En las pruebas realizadas comprobamos que la tasa de transferencia al realizar el backup de la zona de disco compartida era muy baja, lo que suponía una demora de más de un día para realizar el backup de unos 500 GB. Esto se debe, sin lugar a dudas, a alguna incompatibilidad entre el software de backup y el sistema de ficheros GlusterFS.

 

Como solución decidimos realizar el backup de cada uno de los discos que conforman la zona GlusterFS de forma independiente. Recordemos que la zona GlusterFS está formada por grupos de dos servidores con datos replicados. Estos discos cuentan con un sistema de ficheros ext3 y son accesibles desde el propio servidor de discos, si bien la modificación directa supondría la corrupción de los datos.

 

Exportamos por NFS el disco de una de las máquinas de cada AFR de la zona GlusterFS a master-cluster2. En la actualidad la zona GlusterFS cuenta con 6 servidores (disc1, disc2, disc3, disc4, disc5 y disc6) organizados en 3 AFRs. Configuramos la exportación del disco de los nodos disc2, disc4 y disc6 mediante el fichero /etc/exports, que puede consultarse en los apéndices [19.1.29].

 

La exportación se hace como sólo lectura para que no exista posibilidad alguna de escritura en esta zona fuera del control del sistema GlusterFS.

 

En master-cluster2 montamos las tres zonas exportadas. Para que estas zonas se monten de forma automática, añadimos las siguientes líneas al fichero /etc/fstab:

 

disc2:/mnt/glusterfs/home     /mnt/backup/disc2 nfs   defaults    0     0

disc4:/mnt/glusterfs/home     /mnt/backup/disc4 nfs   defaults    0     0

disc6:/mnt/glusterfs/home     /mnt/backup/disc6 nfs   defaults    0     0

 

El backup de la zona GlusterFS se completa con la copia de la partición con  el namespace /mnt/glusterfs/home-ns.

 

También guardamos backup de la partición raíz de master-cluster2, con lo que tendremos copia del sistema operativo y de todo el software instalado, así como de Tivoli y las imágenes de disco de los nodos.

 

Por último guardamos backup de la partición common con la configuración de Sun Grid.

 

Resumiendo, hacemos backup de los directorios siguientes:

 

/

/mnt/backup/disc2

/mnt/backup/disc4

/mnt/backup/disc6

/mnt/glusterfs/home-ns

/mnt/glusterfs/sge-common

 

16.6. Estadísticas web

 

El cluster cuenta con un servidor web que permite acceder al servicio de monitorización ganglia y la descarga de manuales, documentación y presentaciones.

 

El software awstats se encarga de la generación de estadísticas en acceso a servidores web en base a la información almacenada en sus logs. Proporciona un informe pormenorizado de las páginas web más visitadas así como las direcciones que la consultan, browsers utilizados, etc.

16.6.1. Instalación

 

Instalamos el paquete de software awstats en las dos máquinas master-cluster:

 

master-cluster1> apt-get install awstats

16.6.2. Configuración

 

awstats utiliza un programa en perl para extraer del servidor web información con la que generar estadísticas accesibles vía web.

 

La configuración está en el fichero /etc/awstats/awstats.conf, donde indicamos el origen de los logs (servidor web), el tipo de servidor web (apache) y el dominio. El fichero awstats.conf puede consultarse en los apéndices [19.1.30].

 

Las estadísticas se generan con la invocación del script awstats.pl. Creamos un cron que llame a este script una vez al día:

 

# awstats

0 0 * * *       /var/www/awstats/cgi-bin/awstats.pl -update –config = master-cluster1.lsi.upc.edu

 

Por último sólo queda hacer que las información generada por awstats sea visible en nuestra web. Para ello creamos la configuración pertinente en el servidor apache de los nodos master-cluster, añadiendo las siguientes líneas al fichero /etc/apache2/apache2.conf o creando el fichero /etc/apache2/sites-available/awstats:

 

#

# Directives to allow use of AWStats as a CGI

#

Alias /awstatsclasses "/var/www/awstats/classes/"

Alias /awstatscss "/var/www/awstats/css/"

Alias /awstatsicons "/var/www/awstats/icon/"

ScriptAlias /awstats/ "/var/www/awstats/cgi-bin/"

 

#

# This is to permit URL access to scripts/files in AWStats directory.

#

<Directory "/var/www/awstats/">

    Options None

    AllowOverride All

    Order allow,deny

    Allow from all

</Directory>

 

<Directory "/var/www/awstats/cgi-bin/">

    Options None

    AllowOverride All

    Order allow,deny

    Allow from all

</Directory>

 

Las estadísticas serán visibles en la url:

 

http://master-cluster1.lsi.upc.edu/awstats/awstats.pl?config=master-cluster1.lsi.upc.edu.

 

Las figuras [16.1] y [16.2] muestran parte del contenido de las estadísticas generadas por awstats.

 

 

awstats-1

 

Figura 16.1: Web awstats (1)

 

 

 

Figura 16.2: Web awstats (2)

 

 

Restringiremos el acceso a las estadísticas a los administradores del cluster, ya que que esta información no es relevante para los usuarios, mediante un fichero .htaccess en el directorio /var/www/awstats/cgi-bin, en el que se encuentra el programa awstats.pl.

 

El fichero de control de acceso a la web de estadísticas .htaccess se encuentra en los apéndices [19.1.31].

 

16.7. Wake on LAN

 

Wake on LAN o WOL es un servicio que permite el arranque remoto de máquinas apagadas dentro de una red local. Mediante un paquete especial (MagicPacket) enviado a la dirección MAC de la tarjeta de red de la máquina que deseemos iniciar remotamente, que previamente se ha configurada para aceptar este tipo de paquetes.

 

Para que el proceso de WOL tenga éxito éste debe estar soportado por la BIOS, la tarjeta de red y el sistema operativo de la máquina.

 

La utilidad ethtool permite configurar diversos aspectos de las tarjetas de red. En nuestro caso queremos que las máquinas se enciendan al recibir un MagicPacket, por lo que deberemos ejecutamos el comando:

 

node100> ethtool –s eth0 wol g

 

Incorporamos este comando al script /etc/initr.d/rc.sistemes para que se ejecute cada vez que la máquina arranque. Así su tarjeta de red quedará preparada para WOL.

 

Estando apagada, el siguiente comando inducirá el arranque de la máquina con la dirección MAC especificada :

 

master-cluster1> /usr/bin/etherwake –i eth0 @MAC

 

Utilizaremos este el procedimiento de arranque remoto desde los nodos master-cluster. Disponemos de un par de scripts que permiten arrancar y apagar las máquinas, ya sea individualmente o por grupos. Los scripts wakeup-cluster.sh y halt-cluster.sh pueden encontrarse en los apéndices [ 19.1.32] y [19.1.33].

 

16.8. NAT

 

Las máquinas del cluster conforman una red privada que las aísla del exterior. Master-cluster1 y master-cluster2 están conectadas a la red del cluster y a la red de LSI y son el punto de entrada al cluster de los usuarios.

 

Los motivos que nos llevan a incluir las máquinas del cluster en una red privada son los siguientes:

 

·        No se utilizan direcciones IP públicas, un recurso limitado actualmente.

 

·        Las máquinas del cluster se aíslan del tráfico de la red de LSI. En un cluster de computación es de vital importancia disponer de una red con el mayor ancho de banda posible. La uso red privada evita que el tráfico broadcast generado por servicios ajenos al cluster entre en ella.

 

·        Seguridad. Las máquinas con direcciones IP públicas son universalmente accesibles y se necesitan servicios adicionales de securización como filtros y firewalls para protegerlas. Dado que el acceso directo no es necesario, el uso de IPs privadas proporciona un grado adicional de seguridad.

 

Con este esquema de red, el tráfico desde fuera del cluster está cerrado, pero también lo está el tráfico desde el cluster hacia el exterior. Esto puede representar un problema para cierto software que necesita acceder al exterior.

 

Es el caso de software como Matlab o Maple, que hacen uso de licencias alojadas en servidores de licencias flotantes. La UPC dispone de un número limitado de licencias para el uso concurrente de este software. Con el fin de controlar el número de usuarios que hacen uso del software la UPC dispone de un servidor de licencias, al que se debe conectar cualquier ordenador que quiera ejecutar este tipo de software.

 

En nuestro cluster los programas se ejecutan en máquinas que se encuentran dentro de una red privada, sin acceso al exterior. Para que el software con licencias flotantes pueda ejecutarse es necesario que se permita la conexión con el exterior.

 

NAT (Network Address Translator) es un mecanismo utilizado en routers IP que permite intercambiar paquetes entre dos redes enmascarando la dirección origen mediante la conversión en tiempo real de las direcciones utilizadas en los paquetes.

 

Básicamente lo que haremos será configurar el router de la red del cluster, las máquinas master-cluster, para que modifiquen el campo de dirección origen de los paquetes generados por las máquinas de computación. La dirección original, privada, se cambiará por una dirección del rango de LSI, en este caso la dirección de la máquina que actúe como router.

 

A efectos prácticos, todas las peticiones de licencia desde el cluster llegarán al servidor de licencias flotantes de la UPC con la dirección IP de master-cluster1 o master-cluster2, por lo que serán aceptadas.

 

La activación del NAT en las máquinas master-cluster requiere la activación de las opciones de routing correspondientes en el kernel:

 

·         Networking options

o        Network Packet Filtering

§         IP: Netfilter Configuration

·         Connection Tracking (required for masq/NAT) [M]

·         Full NAT                                    [M]

 

Las máquinas master-cluster, que actuarán como gateway, deben aceptar el reenvío de paquetes provenientes de la red del cluster. Para ello activamos la opción ip_forwarding:

 

master-cluster1> echo 1 > /proc/sys/net/ipv4/ip_forward

 

Asimismo es necesario que en todas las máquinas de computación se añada una ruta estática a la tabla de routing indicando que el Gateway por defecto es una máquina master-cluster:

 

node100> route add default gw 192.168.0.201

 

Añadimos este comando al script /etc/init.d/rc.sistemas para que estos cambios se realicen al arrancar el nodo.

 


17. Tareas administrativas

 

 

Los scripts de administración están en el directorio /root/scripts de las dos máquinas master-cluster y pueden ejecutarse indistintamente desde cualquiera de ellas.

 

17.1. Alta de nodo

 

El proceso de alta de nuevos nodos está casi totalmente automatizado. La utilización de Tivoli (capítulo [13]) como sistema de instalación de imágenes y la posterior personalización del sistema operativo mediante shellscripts, explicado en el apartado [13.3], permiten que el nuevo nodo esté operativo con una intervención mínima por parte del administrador.

 

El alta de usuario se hace mediante el script alta_nodo.sh. Se trata de un script interactivo que guarda la información del nodo y lo da de alta en los diferentes servicios del cluster. Concretamente, pregunta los siguientes datos:

 

1.      Grupo al que pertenece el nodo (eixam, nozomi, tenada, servidor de disco).

2.      Dirección MAC

3.      Dirección IP

4.      En caso de tratarse de un servidor de disco, el rol que juega, Primario o Secundario, y su pairnode.

 

Con estos datos, configura los siguientes servicios:

 

1.      Dar de alta al nuevo nodo en el DHCP, asociando la IP a la MAC facilitada

2.      Añade entrada en el fichero /etc/hosts.

3.      Añade nueva entrada a fichero /root/files/nodes/nodes con información del nodo, su rol y la cola a la que pertenece.

4.      Incorpora el nuevo nodo a las listas de dsh.

5.      Da de alta el nodo con permisos administrativos en Sun Grid.

6.      Copia la versión actualizada de los ficheros hosts y nodes a todos los nodos del cluster.

7.      Envía mail al administrador del cluster informando del alta del nuevo nodo.

 

El script alta_nodo.sh puede encontrarse en los apéndices [19.1.34].

 

Tras ejecutar el script tan sólo resta dar de alta el nodo en el servidor de imágenes. Para ello seguimos los pasos indicados en el apartado [13.2]. Una vez dado de alta en Tivoli y previa configuración en la BIOS de arranque por PXE, el nodo está listo para incorporarse al cluster.

 

Tan solo quedará dar de alta el nodo en el sistema de monitorización nagios como indicamos en el apartado [15.2.1].

 

 

Sustitución de un nodo

 

Cuando se sustituye un nodo por otro nuevo no se sigue el procedimiento de alta de nodo, sino que se modifica la configuración del servidor DHCP y del Tivoli, sustituyendo la dirección MAC de la máquina antigua por la de la nueva. Una vez hechos estos cambios basta con conectar el nuevo nodo a la red y encenderlo. Tras unos minutos la imagen de sistema quedará instalada y el nodo estará operativo.

 

17.2. Alta de usuario

 

Los usuarios del cluster son usuarios locales, independientes del resto de sistemas del Departamento, siguiendo la política de autonomía del cluster. Ahora bien, todo usuario del cluster debe ser usuario de LSI. De hecho, tanto el username como el password se obtienen del servicio de NIS departamental. Esto es necesario porque permite a los usuarios utilizar su username y password de LSI para acceder al cluster, evitando tener que recordar un nuevo username y password.

 

El alta de nuevos usuarios se realiza mediante el script alta_usuario.sh, que tiene como parámetros el username y el grupo o cola al que pertenece el nuevo usuario. El username pertenecer a LSI. Con el username y el password cifrado obtenido de las NIS, se realizan las siguientes acciones:

 

1.      Se añade información del usaurio a los ficheros passwd, shadow y group.

 

2.      Se crea el home del nuevo usuario en el filesystem distribuido.

 

3.      Se añade entrada con username y grupo a fichero /etc/allowed_users.

 

4.      Propaga la información (passwd, shadow, group y allowed_users) a todos los nodos del cluster.

 

5.      Por último añade el usuario a la lista de acceso de la cola correspondiente en Sun Grid.

 

El script alta_usuario.sh y los scripts auxiliares build_homes.sh y build_users.sh puede encontrarse en los apéndices [ 19.1.35], [19.1.36] y [19.1.37].

 

Una vez el alta ha sido realizada sólo queda enviar mail informando al usuario y a su profesor responsable.

 

 

 


18. Conclusiones

 

18.1. Objetivos y requisitos cumplidos

 

Al iniciar este proyecto planteamos dos objetivos:

 

·        La implantación de un nuevo sistema de clustering para el Departamento de LSI.

 

·        La creación de una documentación que sirviese como referencia para el Laboratorio de Cálculo de LSI

 

El nuevo cluster ha sido implementado en el plazo previsto y está en producción desde el 1 de Octubre de 2008. La documentación del sistema la constituye básicamente este documento, la ponencia realizada en las VII Jornades de Programari Lliure, las presentaciones técnicas realizadas a otros administradores de sistemas de la UPC, las presentaciones realizadas a los miembros del Departamento de LSI durante las jornadas de presentación del cluster y distintos FAQs para usuarios.

 

Para estos dos objetivos nos habíamos fijado una serie de requisitos. Veamos cómo los hemos cumplido.

18.1.1. El nuevo cluster

 

El nuevo cluster debía tener una serie de componentes que proporcionasen el servicio de calidad esperado:

 

·        Un software de clustering: el sistema de gestión de colas Sun Grid.

 

·        Un espacio de disco compartido de usuario: el filesystem distribuido paralelo GlusterFS.

 

·        Alta disponibilidad: Heartbeat.

 

·        Un sistema de gestión de imágenes: el software Tivoli.

 

·        Un sistema de monitorización: Ganglia juntamente con el servicio de monitorización departamental Nagios.

 

·        Amén de otros servicios básicos como correo, sincronización de tiempo, etc.

 

Todos estos servicios han sido integrados en lo que es el nuevo cluster del Departamento de LSI.

 

Las dos piedras angulares a la hora de plantear la arquitectura del nuevo cluster eran, por una parte un software de clustering robusto y eficiente y por otra un sistema de ficheros paralelo, estable y escalable. Tras el largo período de pruebas y la experiencia acumulada durante el tiempo que lleva en producción el nuevo cluster podemos asegurar que estos objetivos se han cubierto con creces.

 

La capacidad de proceso de Sun Grid, utilizado actualmente en los mayores clusters del mundo, queda patente en nuestras pruebas con centenares de usuarios y miles de procesos concurrentes.

 

Por otra parte con GlusterFS hemos encontrado el sistema de ficheros que es capaz de sacar el mayor partido al hardware del que disponemos sin renunciar a nuestros requerimientos de estabilidad, rendimiento y flexibilidad. Su rendimiento es muy bueno si lo comparamos con sistemas NFS convencionales y, lo que es más importante, se ha mostrado como un producto muy estable.

 

La cuidada elección de cada uno de los componentes del cluster junto con la aplicación allá donde fuere necesario de productos específicos como heartbeat, proporcionan alta disponibilidad en todas las partes del cluster.

 

Durante la fase de pruebas la estabilidad de nuestra solución quedó demostrada ante fallos hardware simulados de distintos componentes, desconexiones de red y shutdowns de los distintos tipos de nodos. El tiempo máximo de recuperación ante el fallo más grave posible, el fallo de un nodo master, no supera los dos minutos, lo que es poco para un sistema de la complejidad del nuestro.

18.1.2. La documentación

 

La documentación también debía cumplir una serie de requisitos. Debía ser una documentación clara, concisa y no debía omitir información básica para el entendimiento de los conceptos más técnicos. Al fin y al cabo se trata de un documentación que debería servir como referencia al Laboratorio de Cálculo de LSI, formado por administradores de sistemas con experiencia pero que podrían no estar familiarizados con los clusters de computación.

 

Si bien se ha intentado escribir este documento con estos requisitos en mente, será el uso que se haga del mismo el que nos dirá si los objetivos se han cumplido. Fuere como fuere, se trata de un documento vivo, abierto a críticas y sugerencias, que pretende servir como base a la documentación de futuras mejoras que se implementen en el Cluster.

 

18.2. Planificación y estudios de costes

 

La realización de este proyecto ha tenido un coste temporal y económico. A continuación haremos el desglose de estos costes.

 

 

18.2.1. Planificación temporal                

 

La planificación temporal contempla el tiempo de desarrollo de los dos objetivos que nos marcamos al comenzar este proyecto:

 

·        Implementación del nuevo cluster: del 2 de Enero al 15 de Septiembre de 2008 (8 meses y medio).

 

·        Documentación del sistema y del proyecto: a partir del 15 de Octubre (2 meses).

 

Evidentemente una parte importante de la documentación se realizó durante la fase de implementación, de la misma forma que durante el tiempo que se escribía la documentación se realizaron ajustes en el sistema.

 

A continuación vamos a detallar en el tiempo el trabajo realizado en cada una de las dos fases:

 

Fase de implementación

 

Como hemos comentado durante la fase de implementación también se llevó a cabo parte de la documentación. Concretamente se documentó:

 

·        La parte correspondiente al análisis preliminar, con la descripción de los objetivos y requerimientos del proyecto.

 

·        Todas las instrucciones de instalación y configuración así como los ficheros de configuración y scripts asociados a los distintos componentes del cluster.

 

Durante gran parte del tiempo que duró la implementación del nuevo cluster, los tres clusters antiguos siguieron prestando servicio. Todas las pruebas se llevaron a cabo en nodos nuevos que se habían comprado pero que no se habían añadido a sus respectivos clusters. Sólo durante las dos semanas (1 al 15 de Septiembre) que duró la fase de integración del nuevo sistema y previo acuerdo con los usuarios, paramos los clusters antiguos.

 

Dado que mi trabajo en el Laboratorio de Cálculo no se reduce a la administración de clusters, mi dedicación no pudo ser total. Fui descargado de parte de mis obligaciones con el fin de avanzar el desarrollo lo máximo posible, quedando mi dedicación al proyecto finalmente en unas 5 horas diarias de lunes a viernes.

 

La siguiente tabla muestra la planificación durante la fase de implementación:

 

FASE DEL PROYECTO

ESTIMACION INICIAL

PLANIFICACIÓN REAL

DESVIACIÓN

(ACUMULADA)

Estudio del cluster antiguo

Fecha inicio

Fecha fin

Tiempo

02/01

04/01

15 horas

02/01

04/01

15 horas

 

 

0

Estudio de sistemas de clustering

Fecha inicio

Fecha fin

Tiempo

07/01

14/01

30 horas

07/01

11/01

25 horas

 

 

-5 (-5)

Estudio de sistemas de ficheros paralelos

Fecha inicio

Fecha fin

Tiempo

15/01

22/01

30 horas

14/01

22/01

35 horas

 

 

+5 (0)

Creación de infraestructura de pruebas

Fecha inicio

Fecha fin

Tiempo

23/01

25/01

15 horas

23/01

25/01

15 horas

 

 

0 (0)

Diseño del nuevo cluster (v1.0)

Fecha inicio

Fecha fin

Tiempo

28/01

31/01

20 horas

28/01

31/01

20 horas

 

 

0 (0)

Sun Grid: estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

01/02

15/02

55 horas

04/02

13/02

40 horas

 

 

-15 (-15)

Lustre (v1.0): estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

18/02

03/03

55 horas

14/02

10/03

95 horas

 

 

+40 (+25)

Revisión del diseño (v1.1)

Fecha inicio

Fecha fin

Tiempo

04/03

06/03

15 horas

11/03

13/03

15 horas

 

 

+0 (+25)

Lustre (v1.1): configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

07/03

27/03

55 horas

11/03

07/04

80 horas

 

 

+25 (+50)

Revisión del diseño (v2.0)

Fecha inicio

Fecha fin

Tiempo

28/03

02/04

20 horas

08/04

10/04

15 horas

 

 

-5 (+45)

GlusterFS (v2.0): estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

03/04

17/04

55 horas

11/04

02/05

75 horas

 

 

+20 (+65)

Heartbeat: estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

18/04

02/05

55 horas

05/05

23/05

75 horas

 

 

+20 (+85)

Ganglia: estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

05/05

16/05

50 horas

26/05

11/06

65 horas

 

 

+15 (+100)

Tivoli: estudio, configuración y pruebas

Fecha inicio

Fecha fin

Tiempo

19/05

30/05

50 horas

12/06

25/06

50 horas

 

 

+0 (+100)

Automatización de procedimientos

Fecha inicio

Fecha fin

Tiempo

02/06

13/06

50 horas

26/06

21/07

90

 

 

+40 (+140)

Pruebas del sistema completo (de pruebas) y planificación de la implantación

Fecha inicio

Fecha fin

Tiempo

16/06

27/06

35 horas

22/07

31/07

30 horas

 

 

-5 (+135)

Implantación del nuevo sistema

Fecha inicio

Fecha fin

Tiempo

30/07

11/07

20 horas

01/09

12/09

20 horas

 

 

+30 (+135)

Traspaso de datos

Fecha inicio

Fecha fin

Tiempo

14/07

17/07

20 horas

15/09

17/09

20 horas

 

 

+0 (+135)

Pruebas de estabilidad y benchmarking del sistema final

Fecha inicio

Fecha fin

Tiempo

18/07

25/07

30 horas

12/09

14/09

15 horas*

 

 

-15 (+120)

 

 

La siguiente tabla muestra, a modo de resumen, las fechas y horas que se planificaron inicialmente y las que se dedicaron en realidad:

 

 

FASE DEL PROYECTO

ESTIMACIÓN INICIAL

PLANIFICACIÓN FINAL

DESVIACIÓN (ACUMULADA)

Implementación

Fecha inicio

Fecha fin

Tiempo

02/01

17/07

675 horas

02/01

17/09

795 horas

 

 

+120 horas

 

 

Los datos muestran una desviación de casi dos meses de trabajo respecto a la estimación inicial.  Los problemas encontrados en la puesta a punto del filesystem paralelo tienen gran parte de la culpa.

 

A mediados del mes de mayo, viendo que acumulábamos un retraso considerable, decidimos retrasar la fecha de puesta en marcha del nuevo cluster hasta el día 15 de Septiembre. Finalmente el cluster fue puesto en marcha el día previsto y los usuarios pudieron comenzar a utilizarlo mientras realizábamos la migración de datos de los clusters antiguos.

 

Documentación

 

La documentación debía realizarse una vez finalizado el proyecto, siendo el único límite la fecha de presentación de este proyecto de final de carrera en Enero de 2009.

 

Dado que durante la fase de implementación se habían documentado todos los procedimientos de forma exhaustiva, sabíamos que una buena parte de la documentación estaba ya hecha. Con esto en mente, pensamos que el plazo de dos meses sería más que suficiente para llevarla a cabo.

 

La siguiente tabla muestra de forma aproximada el tiempo estimado y el tiempo dedicado realmente a realizar la documentación:

 

 

FASE DEL PROYECTO

ESTIMACIÓN INICIAL

PLANIFICACIÓN FINAL

DESVIACIÓN (ACUMULADA)

Documentación

Fecha inicio

Fecha fin

Tiempo

03/11/08

08/01/09

220 horas

03/11/08

12/01/09

230 horas

 

 

+10 horas

 

 

La desviación total sobre el tiempo estimado inicialmente ha sido de 130 horas.

18.2.2. Coste económico     

 

El coste económico de este proyecto se divide en tres partes:

 

·        Hardware: el coste de los nodos y resto de componentes físicos del cluster.

·        Software: el coste de los programas necesarios para el funcionamiento del cluster.

·        Personal: el coste de la mano de obra utilizada durante la implementación.

 

Hardware

 

La siguiente tabla enumera cada uno de los componentes físicos del cluster junto con su precio:

 

Cantidad

Componente

Precio (€)

12

Nodos del antiguo cluster

24.840

32

Nodos nuevos (Dell)

111.360

6

Nodos servidores de disco

10.440

1

Switch 3Com gigabit de 48 puertos

1.850

1

Switch 3Com gigabit de 16 puertos

1.044

2

Switch Cisco gigabit estacable a 36 Gb/s

17.400

3

Rack (cableado+alimentación eléctrica)

24.012

50

Cable UTP categoría 6

5.220

2

Multiplexador de consolas Dell

3.944

50

Cable para multiplexador de consolas Dell

5.220

 

Total

205.330

 

 

El coste de todo el hardware que compone el cluster es de 205.330 €.

 

Software

 

Todo el software utilizado para la realización de este proyecto, a excepción del software de gestión de imágenes Tivoli, es software open source, cuyo código es abierto y gratuito.

 

En cuanto a Tivoli si bien es de pago, la UPC cuenta con licencia, así que tampoco nos supone ningún desembolso.

 

El coste de la licencia del software de backup queda imputado al Departamento, por lo que tampoco lo hemos tenido en cuenta.

 

Personal

 

La complejidad del proyecto hacía necesaria la participación de más de una persona. Concretamente el equipo de trabajo que ha diseñado e implementado este proyecto está formado por:

 

·        Un jefe de proyecto: encargado de realizar la planificación y dirigir el desarrollo del proyecto para obtener los objetivos planteados minimizando las posibles desviaciones. Su dedicación al proyecto es de 7 horas semanales.

 

·        Un administrador senior de sistemas: que se encarga de recolectar, presentar y evaluar las distintas alternativas así como de implementar la solución consensuada con el jefe de proyecto. Su dedicación es de 25 horas semanales.

 

·        Un administrador junior de sistemas:  realiza tareas rutinarias de apoyo, con una dedicación es de 20 horas semanales.

 

 

La siguiente tabla muestra el coste humano del proyecto:

 

Componente

Horas trabajadas

Coste/hora (€)

Coste total (€)

Jefe de proyecto

185

70

12.950

Administrador senior

795

45

35.775

Administrador junior

278

20

5.560

 

Total

54.825

 

 

Coste total del proyecto

 

El coste total del proyecto, después de sumar el coste del hardware, software y mano de obra es de aproximadamente 259.615 €.

 

18.3. Mejoras y ampliaciones del sistema

 

Este proyecto nos ha permitido construir un cluster completo que cumple todos los objetivos que nos planteamos. Ahora bien, siempre es posible mejorar la calidad del servicio mediante combinaciones de software y hardware que, por diversos motivos (tiempo, dinero,…)  no se han podido utilizar en el momento de la implementación.

 

El nuevo cluster es un sistema complejo, formado por la combinación de distintos componentes cuya configuración puede afinarse para cambiar su comportamiento o mejorar su rendimiento bajo determinadas circunstancias.

 

A continuación comentaremos algunas mejoras que se han dejado en el tintero y que esperamos incluir en futuras actualizaciones del sistema.

 

18.3.1. Infraestructura de red

 

El hardware que sustenta la red del cluster es el hardware heredado de los tres clusters antiguos. Se trata de:

 

·        1 switch 3Com gigabit de 48 puertos

·        2 switch 3Com gigabit de 16 puertos

 

En el momento de la puesta en marcha del cluster, contamos con 50 máquinas, lo que sobrepasa la capacidad del switch de 48 puertos. Esto nos obliga a conectar uno de los switches de 16 bocas a uno de sus puertos.

 

La merma de rendimiento de red en las dos máquinas conectadas actualmente al switch pequeño y, lo que es más importante, de futuros nodos que se incorporen al cluster, es un tema a tener muy en cuenta.

 

Recientemente el Laboratorio de Cálculo de LSI ha adquirido un par de switches Cisco C37506-48TS-S apliables de 48 bocas. El stacking entre ambos switches se realiza mediante una conexión dedicada de 36 Gigabits.

 

Gracias a los nuevos switches el cluster puede crecer en efectivos sin que el rendimiento de red se vea afectado. La sustitución de los switches viejos por los nuevos está prevista para el primer trimestre de 2009.

18.3.2. IP bonding

 

Durante la fase de pruebas de los filesystems paralelos nos percatamos de que el ancho de banda de red acaba siendo un factor limitante a poco que crezca el número de nodos de almacenamiento. En estos filesystems las lecturas y escrituras se hacen en paralelo en varios volúmenes al mismo tiempo, aportando una mejora sustancial de rendimiento si lo comparamos con el acceso a un sistema de almacenamiento único.

 

La tecnología gigabit ethernet proporciona un ancho de banda teórico de  125 MBytes/s. En nuestra configuración actual los datos se obtienen de tres grupos de servidores de disco, cada uno de los cuales cuenta con dos discos SATA en configuración RAID0. Cada uno de estos nodos puede ofrecer datos a una velocidad de más de 100 MBytes/s, con lo que la suma de tres subsistemas sirviendo datos supera con creces el ancho de banda de la red.

 

Link aggregation o IEEE 802.3ad es una tecnología de red que permite incrementar la velocidad de una conexión ethernet agregando el ancho de banda de varias conexiones físicas.

 

En la práctica podríamos utilizar esta tecnología para que las máquinas servidoras de disco sirviesen disco a una mayor velocidad. Todas las máquinas del cluster cuentan con varias tarjetas de red, 2 en el caso de los servidores de disco, que utilizadas conjuntamente podrían ofrecer un ancho de banda teórico de 250 MBytes/s.

 

Durante la fase final de las pruebas del filesystem paralelo probamos esta configuración, pero no obtuvimos los resultados esperados, limitados por la CPU de las máquinas utilizadas como servidoras de disco.

 

Cuando tuvimos que replantear la arquitectura del cluster en el apartado [9.5], viendo que era imposible aprovechar el espacio de disco de todas las máquinas, nos vimos obligados a utilizar nodos dedicados a servir disco. Dado que no disponíamos de máquinas nuevas, utilizamos a tal efecto máquinas viejas que iban a retirarse. Se trata de máquinas con unos 5 años de antigüedad, con CPUs muy poco potentes para los cánones actuales pero que cumplen correctamente el cometido como servidoras de disco.

 

La configuración de las dos tarjetas de red de estas máquinas en modo link aggregation, produjo un overhead de cálculo que llegó a saturar la CPU, provocando la pérdida de paquetes en la conexión de red, lo que obligaba a continuas retransmisiones. En la práctica todo esto se traducía en una ligera merma de rendimiento respecto a la utilización de una única tarjeta de red.

 

Por ello aparcamos la idea de utilizar link aggregation hasta que dispongamos de máquinas servidoras de disco con CPUs más potentes.

18.3.3. Sistema de almacenamiento

 

El éxito de nuestra implementación del filesystem está fuera de toda duda. La zona compartida nos ha permitido:

 

·        Aumentar el espacio disponible en caliente.

·        Eliminar el problema con la fragmentación de zonas.

·        Un mayor rendimiento.

·        Alta disponiblidad de datos.

·        Sistema altamente escalable.

 

Recordemos que los elementos que componen la zona de disco compartida son máquinas corrientes con discos convencionales. La configuración actual funciona correctamente, y los beneficios respecto al modelo original son más que evidentes, pero es posible dar un salto de calidad hacia una configuración más profesional.

 

En este sentido, la utilización de hardware específico como un SAN nos permitiría alcanzar cotas mayores de rendimiento, fiabilidad (tolerancia a fallos) y escalabilidad, eso sí, a cambio de un precio que de momento, no podemos asumir.

 

El esquema mostrado en la figura [18.1] muestra una posible futura implementación de nuestro cluster utilizando un SAN. Esta configuración necesita del siguiente hardware extra:

 

·        Un SAN, como el Dell PowerVault MD3000.

·        Dos servidores de disco dedicados con controladoras SAS duales

 

El array de discos Dell PowerVault MD3000 dispone de espacio para hasta 45 discos SAS o SATA de hasta 1 TByte. Asimismo dispone de dos controladoras SAS duales que permiten configuración en modo tolerancia de fallos.

 

 

Figura 18.1: Esquema del cluster con SAN y Lustre

 

 

Los servidores de disco disponen de una controladora SAS dual, lo que les permite conectarse a cada una de las dos controladoras del array de discos.

 

Una posible organización interna del array de discos, que optimiza el uso de Lustre como filesystem podría ser la siguiente:

 

·        4 OSTS formados por 4 discos en configuración RAID5, lo que da un espacio de almacenamiento efectivo de 3 TBytes por OST.

·        1 MDT formado por dos discos de 1 TByte en RAID1 (mirror).

·        El espacio total del filesystem es de 4 OST x 3 TBytes = 12 TBytes

 

Cada servidor de discos es primary de dos OSTs y failover de otros dos. Esta configuración conocida como primary/primary permite, gracias a las conexiones  SAS redundantes, soportar la caída de uno de los dos servidores sin pérdida del servicio.

 

El rendimiento del sistema está asegurado gracias a:

 

·        La velocidad de cada uno de los discos del array: hasta SAS 15K rpm.

·        La agrupación de discos en RAID5.

·        Con 4 OSTs se puede considerar hacer strip de 3 OSTs, por lo que cada lectura/escritura se haría en 3 grupos de discos simultáneamente.

·        La velocidad de conexión entre el array y los servidores de disco: conexión SAS de 3 Gb/s en cada servidor de disco, lo que da un throughput máximo de 6 Gb/s.

·        La conexión de los servidores a la red interna del cluster utilizando link aggregattion de 2 conexiones gigabit ethernet, lo que permite a cada servidor de disco servir datos a una velocidad máxima de 2 Gb/s. Dados que los datos se obtienen de los dos servidores a la vez, la tasa máxima de datos servida podría llegar a los 4 Gb/s (500 MBytes/s). 

18.3.4. Tunning de Sun Grid

 

Sun Grid Engine es un sistema de colas que permite unos niveles de personalización altísimos. Nuestra configuración actual debe verse como una adaptación del modelo original con tres clusters independientes.

 

El nuevo cluster cuenta con tres colas, cuyo hardware y los usuarios que trabajan sobre ellas se corresponden con los tres clusters originales. La unidad de asignación de recursos o slots en los nodos de computación es la CPU o core físico. En un nodo con 8 cores hay 8 slots de ejecución o lo que es lo mismo pueden ejecutarse 8 trabajos de forma concurrente. Este es el umbral a partir del cual un nodo deja de aceptar trabajos.

 

La asignación 1 trabajo - 1 CPU puede no ser la más óptima (de hecho, en muchos casos no lo será), ya que un nodo con tantos procesos en ejecución como slots disponibles no aceptará más trabajos independientemente del uso que se esté haciendo de sus recursos (CPU y memoria).

 

Una política más acertada podría ser establecer el umbral de carga de las colas por el uso real de la CPU. El modelo actual es una primera aproximación que esperamos ajustar tras acumular datos durante los primeros meses en producción.

 

Como sistema vivo que es, el cluster cambiará o no en función de las necesidades de los usuarios. Gracias a la flexibilidad que nos brinda Sun Grid estos cambios son posibles con un mínimo impacto.

18.3.5. Checkpointing (transparente) de procesos

 

Sun Grid prevé la posibilidad de utilizar distintos tipos de librerías de checkpointing. Estas librerías permiten guardar en disco el estado de un proceso en ejecución para por ejemplo, mover un proceso de un nodo a otro o para continuar la ejecución de un proceso que  acabó su ejecución de forma inesperada por un fallo hardware.

 

Hay que destacar que Sun Grid no proporciona ningún mecanismo de checkpointing, sino un interfaz para la utilización de sistemas de terceros.

 

Durante el desarrollo de este proyecto tuvimos la ocasión de probar algunas soluciones de checkpointing "transparente" como BLCR (Berkeley LabCheckpoint/Restart). Encontramos que las limitaciones eran demasiado importantes como para incluirlos en un sistema en producción como el nuestro, donde el tipo de procesos es de lo más variado, desde scripts en perl hasta programas comerciales como Matlab.

 

Concretamente encontramos problemas al hacer checkpoint de procesos que hacen uso de file descriptors o pipes, algo básico para los procesos que se suelen ejecutar en el cluster.

 

Por otra parte, los usuarios del cluster que ejecutan procesos de larga duración (meses) ya implementan mecanismos de checkpoint que les permiten perder el mínimo tiempo de proceso en caso de fallo. Por otra parte, el scheduling actual del sistema de colas independientes no prevé la posibilidad de reubicar procesos, lo cual sería de utilidad en caso de disponer de un sistema jerárquico de colas.

18.3.6. Nuevos nodos

 

La potencia de cálculo del cluster es el sumatorio de la potencia de cálculo de los elementos que lo componen, por lo que la compra de nuevos nodos contribuye de forma inmediata a incrementar el throughput del cluster.

 

El Laboratorio de Cálculo de LSI cuenta con 4 racks[15] para máquinas del cluster. Cada uno de estos racks dispone de 24 conexiones eléctricas y de red, lo que nos permitiría llegar a tener hasta 96 nodos.

 

Dado que el espacio es finito intentaremos, en la medida de lo posible, sustituir nodos con más de 4 años de antigüedad, por los nodos nuevos.

 


19. Apéndices

 

19.1. Ficheros de configuración y scripts

19.1.1. Fichero menu.lst

 

default         0

timeout         5

title           Lustre-kernel, kernel 2.6.18 (gluster)

root            (hd0,0)

kernel          /boot/vmlinuz-2.6.18-1.6.5.1 root=/dev/md0 ro

initrd          /boot/initrd.img-2.6.18-1.6.5.1

 

19.1.2. Fichero drbd.conf

 

global {

    usage-count yes;

}

 

 

common {

  syncer {

    rate 125M;

    al-extents 1024;

  }

  protocol C;

}

 

 

resource r0 {

  startup {

    wfc-timeout 30;

  }

 

  disk {

     on-io-error detach;

  }

 

  net {

 

  }

 

  on node1 {

    device     /dev/drbd0;

    disk       /dev/md2;

    address    10.1.1.1:7790;

    meta-disk internal;

  }

  on node2 {

    device    /dev/drbd0;

    disk      /dev/md2;

    address   10.1.1.2:7790;

    meta-disk internal;

  }

}

 

19.1.3. Fichero glusterfs-server.vol

 

volume brick

      type storage/posix

      option directory /mnt/glusterfs/home

end-volume

 

volume posix-locks

     type features/posix-locks

      option mandatory on

      subvolumes brick

end-volume

 

volume iothreads

      type performance/io-threads

      option thread-count 2

      option cache-size 64MB

     subvolumes posix-locks

end-volume

 

volume wb

      type performance/write-behind

subvolumes iothreads

end-volume

 

volume ra

      type performance/read-ahead

      subvolumes wb

end-volume

 

volume server

      type protocol/server

     subvolumes ra

     option transport-type tcp/server

     option auth.ip.ra.allow *

end-volume

 

19.1.4. Fichero glusterfs-client.vol

 

volume client0-ns

 type protocol/client

 option transport-type tcp/client

 option remote-host 192.168.0.201

 option remote-subvolume brick-ns

 option transport-timeout 180

end-volume

 

volume client1-ns

type protocol/client

option transport-type tcp/client

      option remote-host 192.168.0.202

      option remote-subvolume brick-ns

      option transport-timeout 180

end-volume

 

#### CLIENTES ####

 

volume client1

type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.101

      option remote-subvolume ra

      option transport-timeout 180

end-volume

 

volume client2

      type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.102

      option remote-subvolume ra

      option transport-timeout 180

end-volume

 

volume client3

type protocol/client

option transport-type tcp/client

option remote-host 192.168.0.103

      option remote-subvolume ra

      option transport-timeout 180

end-volume

volume client4

      type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.104

      option remote-subvolume ra

      option transport-timeout 180

end-volume

 

volume client5

      type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.105

      option remote-subvolume ra

      option transport-timeout 180

end-volume

 

volume client6

      type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.106

      option remote-subvolume ra

      option transport-timeout 180

end-volume

 

volume afr-ns

      type cluster/afr

      subvolumes client0-ns client1-ns

end-volume

 

volume afr1

      type cluster/afr

      subvolumes client1 client2

end-volume

 

volume afr2

      type cluster/afr

      subvolumes client3 client4

end-volume

 

volume afr3

      type cluster/afr

      subvolumes client5 client6

end-volume

volume unify

      type cluster/unify

      subvolumes afr1 afr2 afr3

      option scheduler rr

      option rr.limits.min-free-disk 1%

      option readdir-force-success on

      option namespace afr-ns

end-volume

 

volume wb

      type performance/write-behind

      option aggregate-size 128KB

      option flush-behind on

      subvolumes unify

end-volume

 

19.1.5. Fichero ha.cf de master-cluster1

 

debugfile /var/log/ha-debug

logfile /var/log/ha-log

logfacility local0

auto_failback on

ucast eth0 192.168.0.202

warntime 30

deadtime 120

initdead 180

keepalive 5

node master-cluster1

node master-cluster2

 

19.1.6. Fichero ha.cf de master-cluster2

 

debugfile /var/log/ha-debug

logfile /var/log/ha-log

logfacility local0

auto_failback on

ucast eth0 192.168.0.201

warntime 30

deadtime 120

initdead 180

keepalive 5

node master-cluster1

node master-cluster2

 

 

19.1.7. Fichero haresources

 

master-cluster1 Filesystem.drbd::/dev/drbd1::/mnt/sge/default/spool::ext3 sungrid MailTo::cluster@lsi.upc.edu

 

19.1.8. Script sungrid de heartbeat

 

#!/bin/bash

#

 

ACT_QMASTER="/usr/local/sge/default/common/act_qmaster"

SGESCRIPT="/etc/init.d/sgemaster"

HOSTNAME=`uname -n`

 

 

case "$1" in

    start)

      SHARED_ZONES=`mount | grep -e drbd1 -e drbd0 | wc -l`

      #while [ $SHARED_ZONES != 2  && ! -f $ACT_QMASTER ]; do

      while [ ! -f $ACT_QMASTER ]; do

         echo "[LCLSI] Zonas lustre aun no montadas, esperamos 30\" m?s..."

         sleep 30

         SHARED_ZONES=`mount | grep -e drbd1 -e drbd0 | wc -l`

      done

      ACT_QMASTER="/usr/local/sge/default/common/act_qmaster"

      echo $HOSTNAME > $ACT_QMASTER

      # try several times, in case heartbeat deadtime

      # was smaller than drbd ping time

      try=6

      while true; do

            sleep 10

            $SGESCRIPT start && break

            let "--try" || exit 1 # LSB generic error

            sleep 1

      done

      ;;

    stop)

      $SGESCRIPT stop

      #ex=$?

      ;;

    status)

      #Status: Si hostname = act_qmaster => master

      #     Si hostname <> act_qmaster => shadow

        HOSTNAME=`uname -n`

      if [ -f $ACT_QMASTER ]; then

         QMASTER_ACTUAL=`cat /usr/local/sge/default/common/act_qmaster`

           if [ $HOSTNAME == $QMASTER_ACTUAL ]; then

              STATE=Master

           else

              STATE=Shadow

           fi

      else

           STATE=Unconfigured

        fi

      case $STATE in

            Master)

                  MASTER_RUNNING=`ps waux|grep sge_qmaster|grep -v grep|wc -l`

                  if [ $MASTER_RUNNING == 1 ]; then

                     echo "running (Primary)"

                     exit 0 # LSB status "service is OK"

                    else

                     echo "stopped (Primary)"

                  fi   

                  ;;

            Shadow|Unconfigured)

                  echo "stopped ($STATE)" ;;

            "")

                  echo "stopped" ;;

            *)

                  # unexpected. whatever...

                  echo "stopped ($ST)" ;;

      esac

      exit 3 # LSB status "service is not running"

      ;;

    *)

      echo "Usage: sungrid {start|stop|status}"

      exit 1

      ;;

esac

 

exit 0

 

19.1.9. Fichero drbd.conf de zona spool

 

global {

    usage-count yes;

}

 

 

common {

  syncer {

    rate 125M;

    al-extents 1024;

  }

  protocol C;

}

 

 

 

resource r1 {

  startup {

    wfc-timeout 30;

  }

 

  disk {

     on-io-error detach;

  }

 

  net {

 

  }

 

  on master-cluster1 {

    device     /dev/drbd1;

    disk       /dev/md3;

    address    10.1.1.1:7790;

    meta-disk internal;

  }

  on master-cluster2 {

    device    /dev/drbd1;

    disk      /dev/md3;

    address   10.1.1.2:7790;

    meta-disk internal;

  }

}

 

19.1.10. Fichero glusterfs-server_sge-common.vol

 

volume brick-sge

      type storage/posix

     option directory /mnt/glusterfs/sge-common

end-volume

 

volume server

      type protocol/server

      subvolumes brick-sge

     option transport-type tcp/server

     option auth.ip.brick-sge.allow *

end-volume

 

19.1.11. Fichero glusterfs-client-sge.vol

 

volume client1-sge

      type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.201

      option remote-subvolume brick-sge

      option transport-timeout 180

end-volume

 

volume client2-sge

type protocol/client

      option transport-type tcp/client

      option remote-host 192.168.0.202

      option remote-subvolume brick-sge

      option transport-timeout 180

end-volume

 

volume afr

      type cluster/afr

      subvolumes client1-sge client2-sge

end-volume

 

19.1.2. Fichero bootnode-gluster.shtml

 

<script type="text/rembo-c">

 

ShowConsole();

 

int NumDisks = sizeof(SystemInfo.Disks);

 

// Devuelve el id del disco de menor tamaño

int GetSmallerDisk (void) {

  int SmallerDiskSize = SystemInfo.Disks[0];

  int SmallerDisk = 0;

  for (int i=1;i<NumDisks;i++) {

     if (SystemInfo.Disks[i] < SmallerDiskSize) {

       SmallerDisk = i;

     }

  }

  Log(Strf("DISCO DE MENOR TAMAÑO: %u<br><br>",SmallerDisk));

  return SmallerDisk;

}

 

// Trabajamos con el disco de menor tamaño

int MaxDisks = 2;

int IdDisk = GetSmallerDisk();

int DiskSize = SystemInfo.Disks[IdDisk];

int RootSize = 20000000;

int SwapSize = 4000000;

int HomeSize = (DiskSize - RootSize - SwapSize-50000);

int NumPartitions = 0;

str Partitions = Strf("EXT2:%u LINUX-SWAP:%u 253:%u", RootSize, SwapSize, HomeSize);

 

str p = GetPrimaryPartitions(IdDisk);

var pa = ParsePartitions(p);

 

int min (int num1, int num2) {

  if (num1 < num2)

     return num1;

  else return num2;

}

 

// Devuelve TRUE si Disco Inicializado

bool DiscoInicializado (int IdDisk) {

  str p = GetPrimaryPartitions(IdDisk);

  var pa = ParsePartitions(p);

  int NumPartitions = sizeof(pa);

 

  if (NumPartitions < 4)

     return false;

  else

     if (StrCompare(pa[3].type,"240") == 0)

        return true;

     else

        return false;

}

 

// Comrprobar que tamaÆo(disco_no_inicializado)>= tamaÆo(disco_inicializado)

if (NumDisks >1) {

  // 2 o mas discos

  if (DiscoInicializado(0) && !DiscoInicializado(1)) {

      if (SystemInfo.Disks[1] < SystemInfo.Disks[0]) {

         Log(Strf("ERROR: Disco sin inicializar (1) es de menor tamaño que el ya inicializado. <br>"));

         exit (1);

      }

  else {

     if (!DiscoInicializado(0) && DiscoInicializado(1)) {

      if (SystemInfo.Disks[0] < SystemInfo.Disks[1]) {

         Log(Strf("ERROR: Disco sin inicializar (0) es de menor tamaño que el ya inicializado. <br>"));

         exit (1);

       }

     }

  }

}

}

 

//Particionamos los discos no particionados (sin MARCA)

for (int i=0;i<min(NumDisks,MaxDisks);i++) {

  if (!DiscoInicializado(i)){

     Log(Strf("Inicializando disco %u. Tabla de particiones:<br>",i));

     SetPrimaryPartitions(i,Partitions);

     Log(GetPrimaryPartitions(i) + "<br>");

  }

}

 

  SetBootablePartition(0,1);

 

Log(Strf("Restauramos imagen...<br>"));

RestoreDiskImage(0,1,"net://global/hdimages/node_gluster_v3.img");

 

HDClean(0,2);

 

LXBoot("net://global/hdimages/vmlinuz-2.6.18-gluster","net://global/hdimages/initrd.img-2.6.18-gluster","root=/dev/sda1");

 

</script>

 

19.1.13. Script post_boot.sh

 

#!/bin/bash

 

 

# Decidimos qué host es master

 

masters="master-cluster1 master-cluster2"

for node in `echo $masters`; do

   if [ "`ping -c 3 -W 1 -i 1 $node | grep "bytes from" | wc -l`" -ne 0 ]; then

      NodoMaster=$node

      break

   fi

done

echo "[LCLSI] Nodo Master: $NodoMaster"

echo ""

 

SrcFiles=/root/files/nodes

GlusterPath=/

GlusterDaemon=$GlusterPath/sbin/glusterfs

GlusterClientCfg=$GlusterPath/etc/glusterfs/glusterfs-client.vol

GlusterClientSgeCfg=$GlusterPath/etc/glusterfs/glusterfs-client-sge.vol

GlusterServerCfg=$GlusterPath/etc/glusterfs/glusterfs-server.vol

 

# Sincronizamos hora

/usr/sbin/rdate -s $NodoMaster

 

 

# Damos nombre al nodo

scp $NodoMaster:/etc/hosts /etc/hosts

Ip=`ifconfig eth0|grep inet|awk '{print $2}'|cut -f2 -d:`

Nombre=`grep -w $Ip /etc/hosts |awk '{print $2}'`

# Damos nombre segun @IP asignada

echo $Nombre > /etc/hostname

hostname $Nombre

 

 

# Restauramos usuarios

 

/usr/bin/scp $NodoMaster:/etc/passwd.nodes /etc/passwd

/usr/bin/scp $NodoMaster:/etc/shadow /etc/shadow

chmod 640 /etc/shadow

/usr/bin/scp $NodoMaster:/etc/group /etc/group

 

# Copiamos Configuracion GlusterFS

/usr/bin/scp $NodoMaster:$SrcFiles/glusterfs-client.vol /etc/glusterfs/

/usr/bin/scp $NodoMaster:$SrcFiles/glusterfs-server.vol /etc/glusterfs/

/usr/bin/scp $NodoMaster:$SrcFiles/glusterfs-client-sge.vol /etc/glusterfs/

 

# Copiamos fstab

/usr/bin/scp $NodoMaster:$SrcFiles/fstab /etc/

 

# Copiamos listado de nodos

/usr/bin/scp $NodoMaster:$SrcFiles/nodes /etc/

 

# Copiamos ficheros de configuracion de heartbeat

/usr/bin/scp $NodoMaster:$SrcFiles/ha.cf /etc/ha.d/

/usr/bin/scp $NodoMaster:$SrcFiles/haresources /etc/ha.d/

 

# Copiamos ficheros de configuracion de GANGLIA

/usr/bin/scp $NodoMaster:$SrcFiles/gmetad.conf /etc/

/usr/bin/scp $NodoMaster:$SrcFiles/gmond.conf /etc/

 

# Detectar número de discos (1 o 2)

ExisteSda=`cat /proc/partitions | grep sda3|wc -l`

ExisteSdb=`cat /proc/partitions | grep sdb3|wc -l`

 

# NumDiscosIni: numero de discos inicializados

NumDiscosIni=`fdisk -l /dev/sda /dev/sdb | grep PA-RISC | wc -l`

 

# Obtenemos datos del nodo

if [ `grep $Nombre /etc/nodes|wc -l` -eq 0 ]; then

   echo "[LCLSI] ERROR. Nodo no encontrado en lista de nodos (/etc/nodes)"

   echo "        Comprobar alta en master-cluster"

   exit 1

fi

HaNode=`grep -w ^$Nombre /etc/nodes|awk '{print $2}'`

RolNode=`grep -w ^$Nombre /etc/nodes|awk '{print $3}'`

PairNode=`grep -w ^$Nombre /etc/nodes|awk '{print $4}'`

 

 

echo "HaNode: $HaNode, RolNode: $RolNode, PairNode: $PairNode"

echo "NumDiscosIni: $NumDiscosIni"

case $NumDiscosIni in

   0)

        # Ningún disco inicializado

        echo "[LCLSI] Nodo nuevo"

 

        if [ $ExisteSda -eq 1 ] && [ $ExisteSdb -eq 1 ]; then

           # Hay dos discos no inicializados

           echo "[LCLSI] Nodo con discos sda y sdb no inicializados"

 

           if [ $HaNode == "NO" ]; then

              echo "[LCLSI] Nodo $Nombre es CLIENTE glusterfs"

              echo ""

              echo "[LCLSI] Montamos /home (zona glusterfs)"

              echo "$GlusterDaemon -f $GlusterClientCfg /home"

              $GlusterDaemon -f $GlusterClientCfg /home

              # Formateamos y montamos zona TMP

              echo "[LCLSI] Formateamos y montamos zona TMP"

              TmpRaid=`cat /proc/mdstat|grep md2|wc -l`

              if [ $TmpRaid -eq 0 ]; then

                 TmpDevice="/dev/sda3"

              else

                 TmpDevice="/dev/md2"

              fi

              /sbin/mke2fs -j $TmpDevice

              /bin/mount $TmpDevice /tmp

              /bin/chmod 777 /tmp

              /bin/chmod a+t /tmp

           else

              # El Nodo tiene una pareja OST/DRBD

              echo "[LCLSI] Nodo $Nombre es SERVIDOR glusterfs"

              echo "[LCLSI] Creamos array HOME"

              mdadm --create /dev/md2 -R --level=0 --raid-devices=2 /dev/sda3 /dev/sdb3

              echo "[LCLSI] INFO: Nodo $Nombre forma un AFR con $PairNode"

             # Marcamos discos como inicializados

              echo "[LCLSI] Marcamos discos como inicializados"

              PrimerByteLibre=`/sbin/parted /dev/sdb unit b print free|grep "Free Space"|awk '{print $1}'|cut -f1 -dB`

              SegundoByteLibre=`expr $PrimerByteLibre + 1`

              /sbin/parted /dev/sda unit b mkpart primary ext2 $PrimerByteLibre $SegundoByteLibre set 4 palo on

              /sbin/parted /dev/sdb unit b mkpart primary ext2 $PrimerByteLibre $SegundoByteLibre set 4 palo on

              sleep 5

              # Formateamos zona gluster

              /sbin/mke2fs -j /dev/md2

              # Montamos zona gluster (server)

              echo "[LCLSI] Montamos zona gluster"

              mount -t ext3 /dev/md2 /mnt/glusterfs/home

              # Lanzamos Daemon gluster

              echo "[LCLSI] Lanzamos Daemon gluster"

              $GlusterDaemon -f $GlusterServerCfg

         fi

        elif [ $ExisteSda -eq 1 ] && [ $ExisteSdb -eq 0 ]; then

           # Nodo con un disco (sda)

           echo "[LCLSI] Nodo con un solo disco (sda). NO lo incializamos"

           echo ""

           # Formateamos y montamos zona TMP

           echo "[LCLSI] Formateamos y montamos zona TMP"

           TmpRaid=`cat /proc/mdstat|grep md2|wc -l`

           if [ $TmpRaid -eq 0 ]; then

              TmpDevice="/dev/sda3"

           else

              TmpDevice="/dev/md2"

           fi

           /sbin/mke2fs -j $TmpDevice

           /bin/mount $TmpDevice /tmp

           /bin/chmod 777 /tmp

        /bin/chmod a+t /tmp

           echo "[LCLSI] Montamos zona common (sge)"

           $GlusterDaemon -f $GlusterClientSgeCfg /mnt/sge/default/common

           echo "[LCLSI] Montamos /home (zona glusterfs)"

           echo "$GlusterDaemon -f $GlusterClientCfg /home"

           $GlusterDaemon -f $GlusterClientCfg /home

        elif [ $ExisteSda -eq 0 ] && [ $ExisteSdb -eq 1 ]; then

        # Nodo con un disco (sdb) ---> RARO...

           echo "[LCLSI] Nodo con un solo disco (sdb). NO lo incializamos"

           echo ""

           echo "[LCLSI] Montamos zona common (sge)"

           $GlusterDaemon -f $GlusterClientSgeCfg /mnt/sge/default/common

           echo "[LCLSI] Montamos /home (zona glusterfs)"

           $GlusterDaemon -f $GlusterClientCfg /home

        elif [ $ExisteSda -eq 0 ] && [ $ExisteSdb -eq 0 ]; then

           # No existe ningun disco. ERROR: discos mal particionados por REMBO

           echo "[LCLSI] ERROR: No se han detectado discos con particionamiento correcto"

           echo "[LCLSI] Verificar REMBO"

           exit 1

        fi

        # Enviamos mail

        echo ""|mail -s "[CLUSTER] Alta de nodo $Nombre" cluster@lsi.upc.edu

        ;;

 

   2)

        # Dos discos inicializados

        echo "[LCLSI] Detectado sistema con dos discos ya inicializados"

        if [ "$HaNode" == "NO" ]; then

           echo ""

           echo "[LCLSI] Nodo $Nombre es CLIENTE glusterfs"

           echo "[LCLSI] Montamos zona common (sge)"

           $GlusterDaemon -f $GlusterClientSgeCfg /mnt/sge/default/common

           echo "[LCLSI] Montamos /home (zona glusterfs)"

           $GlusterDaemon -f $GlusterClientCfg /home

           # Formateamos y montamos zona TMP

           echo "[LCLSI] Formateamos y montamos zona TMP"

           /sbin/mke2fs -j /dev/sda3

           /bin/mount /dev/sda3 /tmp

           /bin/chmod 777 /tmp

           /bin/chmod a+t /tmp

        else

           echo "[LCLSI] Nodo $Nombre es SERVIDOR glusterfs"

           # Montamos zona gluster (server)

           echo "[LCLSI] Montamos zona gluster"

           mount -t ext3 /dev/md2 /mnt/glusterfs/home

           # Lanzamos Daemon gluster

           echo "[LCLSI] Lanzamos Daemon gluster"

           $GlusterDaemon -f $GlusterServerCfg

        fi

        ;;

 

   *)  echo "ERROR: Numero de discos marcados > 2 ¿¿??"

       echo "NumDiscosRemboIni: $NumDiscosRemboIni"

;;

esac

 

# copiamos crontab (root)

if [ $HaNode == "SI" ]; then

   /usr/bin/scp $NodoMaster:$SrcFiles/crontab_root_storage /tmp/.crontab_root

else

   /usr/bin/scp $NodoMaster:$SrcFiles/crontab_root /tmp/.crontab_root

fi

 

# Personalización ficheros GANGLIA

HOSTNAME=`hostname`

MY_CLUSTER=`grep -w ^$HOSTNAME /etc/nodes | awk '{print $5}'`

MY_MCAST_CHANNEL=`grep -w ^$HOSTNAME /etc/nodes | awk '{print $6}'`

 

sed s/"CLUSTER_NAME"/$MY_CLUSTER/ /etc/gmetad.conf > /tmp/.gmetad.conf

cp /tmp/.gmetad.conf /etc/gmetad.conf

rm /tmp/.gmetad.conf

 

sed s/"CLUSTER_NAME"/$MY_CLUSTER/ /etc/gmond.conf > /tmp/.gmond.conf

sed s/"MCAST_CHANNEL"/$MY_MCAST_CHANNEL/ /tmp/.gmond.conf > /etc/gmond.conf

rm /tmp/.gmond.conf

 

sed s/"MCAST_CHANNEL"/$MY_MCAST_CHANNEL/ /tmp/.crontab_root > /var/spool/cron/crontabs/root

rm /tmp/.crontab_root

 

# Todos los discos inicializados

 

if [ "$RolNode" == "-" ]; then

 

# SunGrid

 

NUM_CORES=`grep processor /proc/cpuinfo|wc -l`

export SGE_ROOT=/usr/local/sge

 

SGE_MOUNT=`mount|grep "/mnt/sge/default/common"|wc -l`

if ! [ $SGE_MOUNT -ne 1 ]; then

   echo "[LCLSI] ERROR: Zona SGE no accesible"

   exit 1

fi

 

if ! [ -L /usr/local/sge/default/common ]; then

     ln -s /mnt/sge/default/common /usr/local/sge/default/common

fi

if ! [ -d /mnt/sge/default/spool/$HOSTNAME ]; then

     mkdir /mnt/sge/default/spool/$HOSTNAME

fi

 

if ! [ -L /usr/local/sge/default/spool/$HOSTNAME ]; then

   ln -s /mnt/sge/default/spool/$HOSTNAME /usr/local/sge/default/spool/$HOSTNAME

fi

 

if [ `$SGE_ROOT/bin/lx24-x86/qstat -f|grep $HOSTNAME|wc -l` -ne 0 ]; then

  echo "[LCLSI] $HOSTNAME pertenece a cluster SunGrid"

else

  echo "[LCLSI] $HOSTNAME no pertenece a cluster SunGrid"

  echo "[LCLSI] Lo añadimos...."

  $SGE_ROOT/bin/lx24-x86/qconf -aattr hostgroup hostlist $HOSTNAME @allhosts

  $SGE_ROOT/bin/lx24-x86/qconf -aattr hostgroup hostlist $HOSTNAME @$MY_CLUSTER

  $SGE_ROOT/bin/lx24-x86/qconf -aattr queue slots "[$HOSTNAME=$NUM_CORES]" all.q

  $SGE_ROOT/bin/lx24-x86/qconf -aattr queue slots "[$HOSTNAME=$NUM_CORES]" $MY_CLUSTER

  $SGE_ROOT/bin/lx24-x86/qconf -aattr queue slots "[$HOSTNAME=$NUM_CORES]" $MY_CLUSTER-nice

 

fi

sleep 5

/etc/init.d/sgeexecd start

 

# Purgamos cola

DEAD_JOBS=`/usr/local/sge/bin/lx24-x86/qstat -s r -f -u "*" -q '*'@$HOSTNAME | egrep -v -e all.q -e ^queue -e ^$MY_CLUSTER

-e ^- |awk '{print $1}'`

 

if [ "$DEAD_JOBS" != "" ]; then

   for job in $DEAD_JOBS; do

       OWNER=`/usr/local/sge/bin/lx24-x86/qstat -j $job|grep ^owner|awk '{print $2}'`

       echo "JOB $job con owner: $OWNER"

       echo "[LCLSI] Purgamos trabajo $job encolado en nodo"

       # No queremos que se envie mail a usuarios reales.... de momento

       OWNER=cluster@lsi.upc.edu

       ssh $NodoMaster "/usr/local/sge/bin/lx24-x86/qdel $job;echo \"El trabajo con id $job ha terminado de forma inesperada por fallo en nodo $HOSTNAME\"|mail -s \"[LCLSI] Job $job ha muerto\" $OWNER@lsi.upc.edu"

   done

else

   echo "[LCLSI] No hay trabajos que purgar en nodo"

fi

fi

 

19.1.14. Fichero gmond.conf

 

# $Id: gmond.conf,v 1.3 2004/01/20 19:15:23 sacerdoti Exp $

# This is the configuration file for the Ganglia Monitor Daemon (gmond)

# Documentation can be found at http://ganglia.sourceforge.net/docs/

#

# To change a value from it's default simply uncomment the line

# and alter the value

#####################

#

# The name of the cluster this node is a part of

# default: "unspecified"

# name  "Testing Cluster"

name "Master nodes"

#

# The owner of this cluster. Represents an administrative

# domain. The pair name/owner should be unique for all clusters

# in the world.

# default: "unspecified"

owner "LCLSI"

#

# The latitude and longitude GPS coordinates of this cluster on earth.

# Specified to 1 mile accuracy with two decimal places per axis in Decimal

# DMS format: "N61.18 W130.50".

# default: "unspecified"

# latlong "N32.87 W117.22"

#

# The URL for more information on the Cluster. Intended to give purpose,

# owner, administration, and account details for this cluster.

# default: "unspecified"

# url "http://www.mycluster.edu/"

#

# The location of this host in the cluster. Given as a 3D coordinate:

# "Rack,Rank,Plane" that corresponds to a Euclidean coordinate "x,y,z".

# default: "unspecified"

# location "0,0,0"

#

# The multicast channel for gmond to send/receive data on

# default: 239.2.11.71

 mcast_channel 239.2.11.71

#

# The multicast port for gmond to send/receive data on

# default: 8649

 mcast_port    8649

#

# The multicast interface for gmond to send/receive data on

# default: the kernel decides based on routing configuration

 mcast_if  eth0

#

# The multicast Time-To-Live (TTL) for outgoing messages

# default: 1

# mcast_ttl  1

#

#

# The number of threads listening to multicast traffic

# default: 2

# mcast_threads 2

#

# Which port should gmond listen for XML requests on

# default: 8649

# xml_port     8649

#

# The number of threads answering XML requests

# default: 2

# xml_threads   2

#

# Hosts ASIDE from "127.0.0.1"/localhost and those multicasting

# on the same multicast channel which you will share your XML

# data with.  Multiple hosts are allowed on multiple lines.

# Can be specified with either hostnames or IP addresses.

# default: none

# trusted_hosts 1.1.1.1 1.1.1.2 1.1.1.3 \

# 2.3.2.3 3.4.3.4 5.6.5.6

#

# The number of nodes in your cluster.  This value is used in the

# creation of the cluster hash.

# default: 1024

# num_nodes  1024

#

# The number of custom metrics this gmond will be storing.  This

# value is used in the creation of the host custom_metrics hash.

# default: 16

# num_custom_metrics 16

#

# Run gmond in "mute" mode.  Gmond will only listen to the multicast

# channel but will not send any data on the channel.

# default: off

# mute on

#

# Run gmond in "deaf" mode.  Gmond will only send data on the multicast

# channel but will not listen/store any data from the channel.

# default: off

# deaf on

#

# Run gmond in "debug" mode.  Gmond will not background.  Debug messages

# are sent to stdout.  Value from 0-100.  The higher the number the more

# detailed debugging information will be sent.

# default: 0

# debug_level 10

#

# If you don't want gmond to setuid, set this to "on"

# default: off

# no_setuid  on

#

# Which user should gmond run as?

# default: nobody

setuid     ganglia

#

# If you do not want this host to appear in the gexec host list, set

# this value to "on"

# default: off

# no_gexec   on

#

# If you want any host which connects to the gmond XML to receive

# data, then set this value to "on"

# default: off

 all_trusted on

#

# If you want dead nodes to "time out", enter a nonzero value here. If specified,

# a host will be removed from our state if we have not heard from it in this

# number of seconds.

# default: 0 (immortal)

# host_dmax 108000

 

19.1.15. Fichero gmetad.conf

 

# This is an example of a Ganglia Meta Daemon configuration file

#                http://ganglia.sourceforge.net/

#

# $Id: gmetad.conf,v 1.10 2003/08/06 23:11:33 sacerdoti Exp $

#

#--------------------------------------------------------------------

# Setting the debug_level to 1 will keep daemon in the forground and

# show only error messages. Setting this value higher than 1 will

# make

# gmetad output debugging information and stay in the foreground.

# default: 0

# debug_level 10

#

#--------------------------------------------------------------------

# What to monitor. The most important section of this file.

#

# The data_source tag specifies either a cluster or a grid to

# monitor. If we detect the source is a cluster, we will maintain a

# complete

# set of RRD databases for it, which can be used to create historical

# graphs of the metrics. If the source is a grid (it comes from

# another gmetad),

# we will only maintain summary RRDs for it.

#

# Format:

# data_source "my cluster" [polling interval] address1:port

# addreses2:port ...

#

# The keyword 'data_source' must immediately be followed by a unique

# string which identifies the source, then an optional polling

# interval in

# seconds. The source will be polled at this interval on average.

# If the polling interval is omitted, 15sec is asssumed.

#

# A list of machines which service the data source follows, in the

# format ip:port, or name:port. If a port is not specified then 8649

# (the default gmond port) is assumed.

# default: There is no default value

#

# data_source "my cluster" 10 localhost  my.machine.edu:8649 

# 1.2.3.5:8655

# data_source "my grid" 50 1.3.4.7:8655 grid.org:8651 grid-

# backup.org:8651

# data_source "another source" 1.3.4.7:8655  1.3.4.8

 

data_source "Master nodes" localhost master-cluster2

 

data_source "eixam" node100 node101

 

data_source "tenada" node200 node201

 

data_source "nozomi" node300 node301

 

data_source "storage" disc1 disc3

#

#--------------------------------------------------------------------

# Scalability mode. If on, we summarize over downstream grids, and

# respect

# authority tags. If off, we take on 2.5.0-era behavior: we do not

# wrap our output

# in <GRID></GRID> tags, we ignore all <GRID> tags we see, and always

# assume

# we are the "authority" on data source feeds. This approach does not

# scale to

# large groups of clusters, but is provided for backwards

# compatibility.

# default: on

# scalable off

#

#--------------------------------------------------------------------

# The name of this Grid. All the data sources above will be wrapped

# in a GRID

# tag with this name.

# default: Unspecified

gridname "LCLSI"

#

#--------------------------------------------------------------------

# The authority URL for this grid. Used by other gmetads to locate

# graphs

# for our data sources. Generally points to a ganglia/

# website on this machine.

# default: "http://hostname/ganglia/",

#   where hostname is the name of this machine, as defined by

# gethostname().

# authority "http://mycluster.org/newprefix/"

#

#--------------------------------------------------------------------

# List of machines this gmetad will share XML with. Localhost

# is always trusted.

# default: There is no default value

#trusted_hosts 127.0.0.1 169.229.50.165 my.gmetad.org

trusted_hosts 127.0.0.1 master-cluster2

#

#--------------------------------------------------------------------

# If you want any host which connects to the gmetad XML to receive

# data, then set this value to "on"

# default: off

all_trusted on

#

#--------------------------------------------------------------------

# If you don't want gmetad to setuid then set this to off

# default: on

# setuid off

#

#--------------------------------------------------------------------

# User gmetad will setuid to (defaults to "nobody")

# default: "nobody"

setuid_username "ganglia"

#

#--------------------------------------------------------------------

# The port gmetad will answer requests for XML

# default: 8651

# xml_port 8651

#

#--------------------------------------------------------------------

# The port gmetad will answer queries for XML. This facility allows

# simple subtree and summation views of the XML tree.

# default: 8652

# interactive_port 8652

#

#--------------------------------------------------------------------

# The number of threads answering XML requests

# default: 4

# server_threads 10

#

#--------------------------------------------------------------------

# Where gmetad stores its round-robin databases

# default: "/var/lib/ganglia/rrds"

# rrd_rootdir "/some/other/place"

 

19.1.16. Script jobs_run.sh

 

#!/bin/bash

 

# Número de jobs (SunGrid) en ejecución en este nodo

 

HOSTNAME=`uname -n`

CLUSTER=`grep -w ^$HOSTNAME /etc/nodes | awk '{print $5}'`

 

/usr/local/sge/bin/lx24-x86/qstat -f | grep $CLUSTER@$HOSTNAME | awk '{print $3}' | cut -f 1 -d/

 

19.1.17. Script jobs_run-slave.sh

 

#!/bin/bash

 

# Número de jobs (SunGrid) en ejecución en este nodo

 

HOSTNAME=`uname -n`

CLUSTER=`grep -w ^$HOSTNAME /etc/nodes | awk '{print $5}'`

 

INFO_NODE=`/usr/local/sge/bin/lx24-x86/qstat -f | grep $CLUSTER-nice@$HOSTNAME`

 

# Buscamos flags de instancia suspendida ("A" por superar umbral de carga, "C" por calendario)

SUSPENDED=`echo $INFO_NODE|awk '{print $6}'|egrep -e A -e C|wc -l`

 

if [ $SUSPENDED -eq 0 ]; then

   echo $INFO_NODE|awk '{print $3}'|cut -f 1 -d/

else

   echo 0

fi

 

19.1.18. Script jobs_queued.sh

 

#!/bin/sh

 

# Retorna jobs encolados

# Queremos que sólo el master que corre sgemaster lo ejecute.

 

DRDB_STATUS=`/sbin/drbdadm state r1 |cut -f1 -d/`

 

if [ "$DRDB_STATUS" == "Primary" ]; then

   echo `/usr/local/sge/bin/lx24-x86/qstat -s p -u "*" | wc -l`

else

   echo "0"

fi

 

19.1.19. Script temp_max.sh

 

#!/bin/bash

 

# Devuelve la temperatura del core más caliente

 

# Identificamos tipo de procesador

#

# Dell (Core2/CoreQuad == Xeon)

# Pentium4 (Pentium4 Hyperthreading == Pentium 4)

# AMD (AMD64/X2 == Athlon 64)

 

PROC_TYPE=`/usr/sbin/dmidecode -s processor-family|head -1`

 

# Cargamos modulos de temperatura

if [ "$PROC_TYPE" == "Xeon" ]; then

   if [ `lsmod |grep coretemp|wc -l` == 0 ]; then

      /sbin/modprobe -q coretemp

   fi

   if [ `lsmod |grep coretemp|wc -l` == 0 ]; then

      echo "-1"

      exit 1

   fi

   TEMP=`/usr/local/bin/sensors | grep Core | awk '{print $3}' | cut -f2 -d+ | cut -f1 -d?|head -1`

 

elif [ "$PROC_TYPE" == "Pentium 4" ]; then

   if [ `lsmod |grep lm85|wc -l` == 0 ]; then

      /sbin/modprobe -q lm85

   fi

   TEMP=`/usr/local/bin/sensors | grep "CPU Temp" | awk '{print $3}' | cut -f2 -d+ | cut -f1 -d?|head -1`

elif [ "$PROC_TYPE" == "Athlon 64" ]; then

   if [ `lsmod |grep i2c-nforce2|wc -l` == 0 ]; then

      /sbin/modprobe -q i2-nforce2

   fi

   TEMP=`/usr/local/bin/sensors | grep Core | awk '{print $3}' | cut -f2 -d+ | cut -f1 -d?|head -1`

else

   # Tipo de procesador desconocido

   echo "-1"

fi

 

echo $TEMP

 

19.1.20. Fichero cluster_extra.tpl

 

<!-- A place to put custom HTML for the cluster view. -->

<BR>

<A HREF="./graph2.php?g=sge_jobs_run&amp;z=large&amp;{graph_args}">

<IMG BORDER=0 ALT="{cluster} JOBS RUNNING"

    SRC="./graph2.php?g=sge_jobs_run&amp;z=small&amp;{graph_args}">

</A>

 

19.1.17. Fichero meta_view.tpl

 

<TABLE BORDER="0" WIDTH="100%">

 

<!-- START BLOCK : source_info -->

<TR>

  <TD CLASS={class} COLSPAN=5>

   <A HREF="{url}"><STRONG>{name}</STRONG></A> {alt_view}

  </TD>

</TR>

 

<TR>

 <!-- START BLOCK : public -->

 <TD ALIGN="LEFT" VALIGN="TOP">

<table cellspacing=1 cellpadding=1 width="100%" border=0>

 <tr><td>CPUs Total:</td><td align=left><B>{cpu_num}</B></td></tr>

 <tr><td width="80%">Hosts up:</td><td align=left><B>{num_nodes}</B></td></tr>

 <tr><td>Hosts down:</td><td align=left><B>{num_dead_nodes}</B></td></tr>

 <tr><td></td></tr>

 <tr><td>Total Disk:</td><td align=left><B>{lustre_total}</B></td></tr>

 <tr><td>Free Disk:</td><td align=left><B>{lustre_total_free}</B>

 <tr><td>&nbsp;</td></tr>

 <tr><td>&nbsp;</td></tr>

</table>

  </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=load_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=load_report&z=small&r={range}"

       ALT="{name} Load" BORDER="0">

  </A>

  </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=mem_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=mem_report&z=small&r={range}"

       ALT="{name} MEM" BORDER="0">

  </A>

   </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=network_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=network_report&z=small&r={range}"

       ALT="{name} MEM" BORDER="0">

  </A>

   </TD>

 

 

  <TD VALIGN=top align=right>

   <A HREF="./graph2.php?{graph_url}&g=sge_jobs_run&z=large&r={range}" VALIGN=medium>

   <IMG SRC="./graph2.php?{graph_url}&g=sge_jobs_run&z=small&r={range}"

       ALT="{name} JOBS" BORDER="0" ALIGN="CENTER">

  </A>

   </TD>

 

<!-- END BLOCK : public -->

 

<!-- START BLOCK : private -->

  <TD ALIGN="LEFT" VALIGN="TOP">

<table cellspacing=1 cellpadding=1 width=100% border=0>

 <tr><td>CPUs Total:</td><td align=left><B>{cpu_num}</B></td></tr>

 <tr><td width=80%>Nodes:</td><td align=left><B>{num_nodes}</B></td></tr>

 <tr><td>&nbsp;</td></tr>

 <tr><td class=footer colspan=2>{localtime}</td></tr>

</table>

   </TD>

   <TD COLSPAN=2 align=center>This is a private cluster.</TD>

<!-- END BLOCK : private -->

 

</TR>

<!-- END BLOCK : source_info -->

</TABLE>

 

<!-- START BLOCK : show_snapshot -->

<TABLE BORDER="0" WIDTH="100%">

<TR>

  <TD COLSPAN="2" CLASS=title>Snapshot of the {self} |

   <FONT SIZE="-1"><A HREF="./cluster_legend.html" ALT="Node Image Legend">Legend</A></FONT>

  </TD>

</TR>

</TABLE>

 

<CENTER>

<TABLE CELLSPACING=12 CELLPADDING=2>

<!-- START BLOCK : snap_row -->

<tr>{names}</tr>

<tr>{images}</tr>

<!-- END BLOCK : snap_row -->

</TABLE>

</CENTER>

<!-- END BLOCK : show_snapshot -->

 

19.1.21. Fichero meta_view.tpl

 

<TABLE BORDER="0" WIDTH="100%">

 

<!-- START BLOCK : source_info -->

<TR>

  <TD CLASS={class} COLSPAN=5>

   <A HREF="{url}"><STRONG>{name}</STRONG></A> {alt_view}

  </TD>

</TR>

 

<TR>

 <!-- START BLOCK : public -->

 <TD ALIGN="LEFT" VALIGN="TOP">

<table cellspacing=1 cellpadding=1 width="100%" border=0>

 <tr><td>CPUs Total:</td><td align=left><B>{cpu_num}</B></td></tr>

 <tr><td width="80%">Hosts up:</td><td align=left><B>{num_nodes}</B></td></tr>

 <tr><td>Hosts down:</td><td align=left><B>{num_dead_nodes}</B></td></tr>

 <tr><td></td></tr>

 <tr><td>Total Disk:</td><td align=left><B>{lustre_total}</B></td></tr>

 <tr><td>Free Disk:</td><td align=left><B>{lustre_total_free}</B>

 <tr><td>&nbsp;</td></tr>

 <tr><td>&nbsp;</td></tr>

</table>

  </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=load_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=load_report&z=small&r={range}"

       ALT="{name} Load" BORDER="0">

  </A>

  </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=mem_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=mem_report&z=small&r={range}"

       ALT="{name} MEM" BORDER="0">

  </A>

   </TD>

 

  <TD VALIGN=top align=right>

  <A HREF="./graph2.php?{graph_url}&g=network_report&z=large&r={range}">

   <IMG SRC="./graph2.php?{graph_url}&g=network_report&z=small&r={range}"

       ALT="{name} MEM" BORDER="0">

  </A>

   </TD>

 

  <TD VALIGN=top align=right>

   <A HREF="./graph2.php?{graph_url}&g=sge_jobs_run&z=large&r={range}" VALIGN=medium>

   <IMG SRC="./graph2.php?{graph_url}&g=sge_jobs_run&z=small&r={range}"

       ALT="{name} JOBS" BORDER="0" ALIGN="CENTER">

  </A>

   </TD>

 

<!-- END BLOCK : public -->

 

<!-- START BLOCK : private -->

  <TD ALIGN="LEFT" VALIGN="TOP">

<table cellspacing=1 cellpadding=1 width=100% border=0>

 <tr><td>CPUs Total:</td><td align=left><B>{cpu_num}</B></td></tr>

 <tr><td width=80%>Nodes:</td><td align=left><B>{num_nodes}</B></td></tr>

 <tr><td>&nbsp;</td></tr>

 <tr><td class=footer colspan=2>{localtime}</td></tr>

</table>

   </TD>

   <TD COLSPAN=2 align=center>This is a private cluster.</TD>

<!-- END BLOCK : private -->

 

</TR>

<!-- END BLOCK : source_info -->

</TABLE>

 

<!-- START BLOCK : show_snapshot -->

<TABLE BORDER="0" WIDTH="100%">

<TR>

  <TD COLSPAN="2" CLASS=title>Snapshot of the {self} |

   <FONT SIZE="-1"><A HREF="./cluster_legend.html" ALT="Node Image Legend">Legend</A></FONT>

  </TD>

</TR>

</TABLE>

 

<CENTER>

<TABLE CELLSPACING=12 CELLPADDING=2>

<!-- START BLOCK : snap_row -->

<tr>{names}</tr>

<tr>{images}</tr>

<!-- END BLOCK : snap_row -->

</TABLE>

</CENTER>

<!-- END BLOCK : show_snapshot -->

 

19.1.22. Fichero graph.php

 

<?php

/* $Id: graph.php 970 2008-02-14 19:16:19Z carenas $ */

include_once "./conf.php";

include_once "./functions.php";

include_once "./get_context.php";

 

# RFM - Added all the isset() tests to eliminate "undefined index"

# messages in ssl_error_log.

# Graph specific variables

# ATD - No need for escapeshellcmd or rawurldecode on $size or $graph.  Not used directly in rrdto

ol calls.

$size = isset($_GET["z"]) && in_array( $_GET[ 'z' ], $graph_sizes_keys ) ?

        $_GET["z"] : NULL;

# ATD - TODO, should encapsulate these custom graphs in some type of container, then this code cou

ld check list of defined containers for valid graph labels.

$graph = isset($_GET["g"]) && in_array( $_GET['g'], array( 'cpu_report', 'mem_report', 'load_repor

t', 'network_report', 'packet_report', 'sge_jobs_run', 'lustre_report' ) ) ?

        $_GET["g"] : NULL;

$grid = isset($_GET["G"]) ?

        escapeshellcmd( clean_string( rawurldecode( $_GET["G"] ) ) ) : NULL;

$self = isset($_GET["me"]) ?

        escapeshellcmd( clean_string( rawurldecode($_GET["me"] ) ) ) : NULL;

$max = isset($_GET["x"]) ?

        clean_number( rawurldecode($_GET["x"] ) ) : NULL;

$min = isset($_GET["n"]) ?

        clean_number( rawurldecode($_GET["n"] ) ) : NULL;

$value = isset($_GET["v"]) ?

        clean_number( rawurldecode( $_GET["v"] ) ) : NULL;

$load_color = isset($_GET["l"]) && is_valid_hex_color( rawurldecode( $_GET[ 'l' ] ) ) ?

        escapeshellcmd( rawurldecode( $_GET["l"] ) ) : NULL;

$vlabel = isset($_GET["vl"]) ?

        escapeshellcmd( clean_string( rawurldecode( $_GET["vl"] ) ) ) : NULL;

$sourcetime = isset($_GET["st"]) ?

        clean_number( $_GET["st"] ) : NULL;

 

# RFM - Define these variables to avoid "Undefined variable" errors being

# reported in ssl_error_log.

$command = "";

$extras = "";

$upper_limit = "";

$lower_limit = "";

$background = "";

$vertical_label = "";

 

# Assumes we have a $start variable (set in get_context.php).

# $graph_sizes and $graph_sizes_keys defined in conf.php.  Add custom sizes there.

if( in_array( $size, $graph_sizes_keys ) ) {

  $height = $graph_sizes[ $size ][ 'height' ];

  $width = $graph_sizes[ $size ][ 'width' ];

  $fudge_0 = $graph_sizes[ $size ][ 'fudge_0' ];

  $fudge_1 = $graph_sizes[ $size ][ 'fudge_1' ];

  $fudge_2 = $graph_sizes[ $size ][ 'fudge_2' ];

} else {

  $height = $graph_sizes[ 'default' ][ 'height' ];

  $width = $graph_sizes[ 'default' ][ 'width' ];

  $fudge_0 = $graph_sizes[ 'default' ][ 'fudge_0' ];

  $fudge_1 = $graph_sizes[ 'default' ][ 'fudge_1' ];

  $fudge_2 = $graph_sizes[ 'default' ][ 'fudge_2' ];

}

 

 

# This security fix was brought to my attention by Peter Vreugdenhil <petervre@sci.kun.nl>

# Dont want users specifying their own malicious command via GET variables e.g.

# http://ganglia.mrcluster.org/graph.php?graph=blob&command=whoami;cat%20/etc/passwd

#

if($command)

    {

      exit();

    }

 

switch ($context)

{

    case "meta":

      $rrd_dir = "$rrds/__SummaryInfo__";

      break;

    case "grid":

      $rrd_dir = "$rrds/$grid/__SummaryInfo__";

      break;

    case "cluster":

      $rrd_dir = "$rrds/$clustername/__SummaryInfo__";

      break;

    case "host":

      $rrd_dir = "$rrds/$clustername/$hostname";

      break;

    default:

      exit;

}

 

$fudge = 0;

if ($graph)   /* Canned graph request */

    {

      if($graph == "jobs_run")

         {

            $fudge = $fudge_1;

            $style = "CPU";

 

            $upper_limit = "--upper-limit 100 --rigid";

            $lower_limit = "--lower-limit 0";

 

            $vertical_label = "--vertical-label Percent ";

if($context != "host" )

               {

                  /* If we are not in a host context, then we need to calculate the average */

                  $series =

                  "DEF:'num_nodes'='${rrd_dir}/cpu_user.rrd':'num':AVERAGE "

                  ."DEF:'cpu_user'='${rrd_dir}/cpu_user.rrd':'sum':AVERAGE "

                  ."CDEF:'ccpu_user'=cpu_user,num_nodes,/ "

                  ."DEF:'cpu_nice'='${rrd_dir}/cpu_nice.rrd':'sum':AVERAGE "

                  ."CDEF:'ccpu_nice'=cpu_nice,num_nodes,/ "

                  ."DEF:'cpu_system'='${rrd_dir}/cpu_system.rrd':'sum':AVERAGE "

                  ."CDEF:'ccpu_system'=cpu_system,num_nodes,/ "

                  ."DEF:'cpu_idle'='${rrd_dir}/cpu_idle.rrd':'sum':AVERAGE "

                  ."CDEF:'ccpu_idle'=cpu_idle,num_nodes,/ "

                  ."AREA:'ccpu_user'#$cpu_user_color:'User CPU' "

                  ."STACK:'ccpu_nice'#$cpu_nice_color:'Nice CPU' "

                  ."STACK:'ccpu_system'#$cpu_system_color:'System CPU' ";

                  if (file_exists("$rrd_dir/cpu_wio.rrd")) {

                     $series .= "DEF:'cpu_wio'='${rrd_dir}/cpu_wio.rrd':'sum':AVERAGE "

                     ."CDEF:'ccpu_wio'=cpu_wio,num_nodes,/ "

                     ."STACK:'ccpu_wio'#$cpu_wio_color:'WAIT CPU' ";

                  }

                  $series .= "STACK:'ccpu_idle'#$cpu_idle_color:'Idle CPU' ";

               }

            else

               {

                  $series ="DEF:'cpu_user'='${rrd_dir}/cpu_user.rrd':'sum':AVERAGE "

                  ."DEF:'cpu_nice'='${rrd_dir}/cpu_nice.rrd':'sum':AVERAGE "

                  ."DEF:'cpu_system'='${rrd_dir}/cpu_system.rrd':'sum':AVERAGE "

                  ."DEF:'cpu_idle'='${rrd_dir}/cpu_idle.rrd':'sum':AVERAGE "

                  ."AREA:'cpu_user'#$cpu_user_color:'User CPU' "

                  ."STACK:'cpu_nice'#$cpu_nice_color:'Nice CPU' "

                  ."STACK:'cpu_system'#$cpu_system_color:'System CPU' ";

                  if (file_exists("$rrd_dir/cpu_wio.rrd")) {

                     $series .= "DEF:'cpu_wio'='${rrd_dir}/cpu_wio.rrd':'sum':AVERAGE "

                     ."STACK:'cpu_wio'#$cpu_wio_color:'WAIT CPU' ";

                  }

                  $series .= "STACK:'cpu_idle'#$cpu_idle_color:'Idle CPU' ";

               }

         }

      else if ($graph == "mem_report")

         {

            $fudge = $fudge_0;

            $style = "Memory";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label Bytes";

 

            $series = "DEF:'mem_total'='${rrd_dir}/mem_total.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_total'=mem_total,1024,* "

               ."DEF:'mem_shared'='${rrd_dir}/mem_shared.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_shared'=mem_shared,1024,* "

               ."DEF:'mem_free'='${rrd_dir}/mem_free.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_free'=mem_free,1024,* "

               ."DEF:'mem_cached'='${rrd_dir}/mem_cached.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_cached'=mem_cached,1024,* "

               ."DEF:'mem_buffers'='${rrd_dir}/mem_buffers.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_buffers'=mem_buffers,1024,* "

               ."CDEF:'bmem_used'='bmem_total','bmem_shared',-,'bmem_free',-,'bmem_cached',-,'bmem

_buffers',- "

               ."AREA:'bmem_used'#$mem_used_color:'Used RAM     ' ";

            if (file_exists("$rrd_dir/swap_total.rrd")) {

               $series .= "DEF:'swap_total'='${rrd_dir}/swap_total.rrd':'sum':AVERAGE "

               ."DEF:'swap_free'='${rrd_dir}/swap_free.rrd':'sum':AVERAGE "

               ."CDEF:'bmem_swapped'='swap_total','swap_free',-,1024,* ";

            }

            $series .= "LINE2:'bmem_total'#$cpu_num_color:'Total RAM' ";

         }

      else if ($graph == "load_report")

         {

            $fudge = $fudge_2;

            $style = "Load";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $vertical_label = "--vertical-label 'Load/Procs'";

 

            $series = "DEF:'load_one'='${rrd_dir}/load_one.rrd':'sum':AVERAGE "

               ."DEF:'proc_run'='${rrd_dir}/proc_run.rrd':'sum':AVERAGE "

               ."DEF:'cpu_num'='${rrd_dir}/cpu_num.rrd':'sum':AVERAGE ";

            if( $context != "host" )

               {

                  $series .="DEF:'num_nodes'='${rrd_dir}/cpu_num.rrd':'num':AVERAGE ";

               }

            $series .="AREA:'load_one'#$load_one_color:'1-min Load' ";

            if( $context != "host" )

               {

                  $series .= "LINE2:'num_nodes'#$num_nodes_color:'Nodes' ";

               }

            $series .="LINE2:'cpu_num'#$cpu_num_color:'CPUs' ";

            $series .="LINE2:'proc_run'#$proc_run_color:'Running Processes' ";

         }

      else if ($graph == "network_report")

         {

            $fudge = $fudge_2;

            $style = "Network";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label 'Bytes/sec'";

 

            $series = "DEF:'bytes_in'='${rrd_dir}/bytes_in.rrd':'sum':AVERAGE "

               ."DEF:'bytes_out'='${rrd_dir}/bytes_out.rrd':'sum':AVERAGE "

."LINE2:'bytes_in'#$mem_cached_color:'In                 '                   "

               ."LINE2:'bytes_out'#$mem_used_color:'Out' ";

         }

      else if ($graph == "packet_report")

         {

            $fudge = $fudge_2;

            $style = "Packets";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label 'Packets/sec'";

 

            $series = "DEF:'bytes_in'='${rrd_dir}/pkts_in.rrd':'sum':AVERAGE "

               ."DEF:'bytes_out'='${rrd_dir}/pkts_out.rrd':'sum':AVERAGE "

               ."LINE2:'bytes_in'#$mem_cached_color:'In' "

               ."LINE2:'bytes_out'#$mem_used_color:'Out' ";

         }

      else if ($graph == "sge_jobs_run")

         {

            $fudge = $fudge_2;

            $style = "";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $extras = "--base 1024";

            $vertical_label = "--vertical-label '# Jobs'";

            if ($context == "cluster")

               {

                if ($clustername == "Master nodes")

                   {

                    #Dividir jobs encolados /2

                    $series = "DEF:'temp'='${rrd_dir}/jobs_queued.rrd':'sum':AVERAGE "

                    #."CDEF:'jobs_1'='temp',2,/ "

                    ."CDEF:'jobs_2'='temp',2,- "

                    ."CDEF:'jobs_3'='jobs_2',0,GT,'jobs_2',0,IF "

                    ."LINE2:'jobs_3'#$proc_run_color:'Queued' "

                    ."GPRINT:'jobs_3':LAST:'    %6.0lf ' ";

                   }

                else

                   {

                    $series = "DEF:'jobs_run'='${rrd_dir}/sge_jobs_run.rrd':'sum':AVERAGE "

                    ."DEF:'jobs_run-slave'='${rrd_dir}/sge_jobs_run-slave.rrd':'sum':AVERAGE "

                    ."DEF:'cpu_num'='${rrd_dir}/cpu_num.rrd':'sum':AVERAGE "

                    ."LINE1:'cpu_num'#$cpu_num_color:'Max' "

                    ."GPRINT:'cpu_num':LAST:' %2.0lf         ' "

                    ."AREA:'jobs_run'#$proc_run_color:'Running prio' "

                    ."GPRINT:'jobs_run':LAST:'%2.0lf         ' "       

                    ."STACK:'jobs_run-slave'#$mem_buffered_color:'Running nice' "

                    ."GPRINT:'jobs_run-slave':LAST:' %2.0lf ' ";       

                   }

               }

            else

               {

                $series = "DEF:'jobs_run'='${rrd_dir}/sge_jobs_run.rrd':'sum':AVERAGE "

                ."DEF:'cpu_num'='${rrd_dir}/cpu_num.rrd':'sum':AVERAGE "

                # Restamos cpus de masters y servidores de disco (4+12)

                ."CDEF:'cpu_num_real'='cpu_num',10,- "

                ."DEF:'jobs_run-slave'='${rrd_dir}/sge_jobs_run-slave.rrd':'sum':AVERAGE "

                ."LINE1:'cpu_num_real'#$cpu_num_color:'Max' "

                ."GPRINT:'cpu_num_real':LAST:' %2.0lf      ' "

                ."AREA:'jobs_run'#$proc_run_color:'Running prio' "

                ."GPRINT:'jobs_run':LAST:'%3.0lf      ' "

                ."STACK:'jobs_run-slave'#$mem_buffered_color:'Running nice' "

                ."GPRINT:'jobs_run-slave':LAST:'    %2.0lf ' ";

                }

         }

     

      else if ($graph == "lustre_report")

         {

            $fudge = $fudge_2;

            $style = "Free Disk";

 

            $lower_limit = "--lower-limit 0 --rigid";

            $vertical_label = "--vertical-label 'Bytes'";

           

            exec("echo 'AFR_1\nAFR_2\nAFR_3'",$OSTS);

            $series = "DEF:'total_tmp'='${rrd_dir}/lustre_total.rrd':'sum':AVERAGE "

            ."CDEF:'total'='total_tmp',1024,* "

            ."CDEF:'total_gb'='total',1073741824,/ "

            ."DEF:'total_free'='${rrd_dir}/lustre_total_free.rrd':'sum':AVERAGE "

            ."CDEF:'total_free_gb'='total_free',1048576,/ ";

            foreach ( $OSTS as $ost_i )

              {

               $series = "$series"

               ."DEF:'lustre_${ost_i}_tmp'='${rrd_dir}/${ost_i}_total.rrd':'sum':AVERAGE "

              ."DEF:'lustre_${ost_i}_free_tmp'='${rrd_dir}/${ost_i}_free.rrd':'sum':AVERAGE "

               ."CDEF:'lustre_${ost_i}_free_gb'='lustre_${ost_i}_free_tmp',1048576,/ "

               ."CDEF:'lustre_${ost_i}'='lustre_${ost_i}_tmp',1024,* "

               ."CDEF:'lustre_${ost_i}_gb'='lustre_${ost_i}',1073741824,/ "

               ."CDEF:'lustre_${ost_i}_pc_tmp'='lustre_${ost_i}_gb','lustre_${ost_i}_free_gb',/ "

               

               ."CDEF:'lustre_${ost_i}_pc'='lustre_${ost_i}_pc_tmp',100,* ";

               if ( $ost_i == "AFR_1" ) {

                  $series = "$series"

                  ."AREA:'lustre_${ost_i}'#".$$ost_i.":'$ost_i' ";

                  }

               else {

                   $series = "$series"

                  ."STACK:'lustre_${ost_i}'#".$$ost_i.":'$ost_i' ";

               }

               $series = "$series"

               ."GPRINT:'lustre_${ost_i}_gb':LAST:'%4.1lf GB' "

               ."GPRINT:'lustre_${ost_i}_pc':LAST:'(%3.1lf %%)\ ' ";

              }

$series = "$series"

               ."LINE2:'total'#$LUSTRE_TOTAL:'Total Disk' "

               ."LINE2:'total'#$LUSTRE_TOTAL: "

               ."COMMENT:'Total Free' "

               ."GPRINT:'total_free_gb':LAST:'%4.1lf GB      ' ";

         

       }

      else

         {

            /* Got a strange value for $graph */

            exit();

         }

    }

else

    {

      /* Custom graph */

      $style = "";

 

      $subtitle = $metricname;

      if ($context == "host")

      {

          if ($size == "small")

              $prefix = $metricname;

          else

              $prefix = $hostname;

 

          $value = $value>1000 ? number_format($value) : number_format($value, 2);

 

          if ($range=="job") {

               $hrs = intval( -$jobrange / 3600 );

               $subtitle = "$prefix last ${hrs}h (now $value)";

          }

          else

              $subtitle = "$prefix last $range (now $value)";

      }

 

      if (is_numeric($max))

         $upper_limit = "--upper-limit '$max' ";

      if (is_numeric($min))

         $lower_limit ="--lower-limit '$min' ";

 

      if ($vlabel)

         $vertical_label = "--vertical-label '$vlabel'";

      else if ($upper_limit or $lower_limit)

         {

            $max = $max>1000 ? number_format($max) : number_format($max, 2);

            $min = $min>0 ? number_format($min,2) : $min;

 

            $vertical_label ="--vertical-label '$min - $max' ";

         }

 

      $rrd_file = "$rrd_dir/$metricname.rrd";

      $series = "DEF:'sum'='$rrd_file':'sum':AVERAGE ";

        # LCLSI: quitamos subt?tulo:

         #."AREA:'sum'#$default_metric_color:'$subtitle' ";

      if ($jobstart)

         $series .= "VRULE:$jobstart#$jobstart_color ";

    }

 

# Set the graph title.

if($context == "meta")

   {

     $title = "$self $meta_designator $style";

   }

else if ($context == "grid")

  {

     $title = "$grid $meta_designator $style";

  }

else if ($context == "cluster")

   {

      $title = "$clustername $style";

   }

else

   {

    if ($size == "small")

      {

        # Value for this graph define a background color.

        if (!$load_color) $load_color = "ffffff";

        $background = "--color BACK#'$load_color'";

 

        $title = $hostname;

      }

    else if ($style)

       $title = "$hostname $style";

    else

       $title = $metricname;

   }

 

# Calculate time range.

if ($sourcetime)

   {

      $end = $sourcetime;

      # Get_context makes start negative.

      $start = $sourcetime + $start;

   }

# Fix from Phil Radden, but step is not always 15 anymore.

if ($range=="month")

   $end = floor($end / 672) * 672;

 

#

# Generate the rrdtool graph command.

#

$fudge += $height;

$command = RRDTOOL . " graph - --start $start --end $end ".

   "--width $width --height $fudge $upper_limit $lower_limit ".

   "--title '$title' $vertical_label $extras $background ".

   $series;

 

$debug=0;

 

# Did we generate a command?   Run it.

if($command)

 {

   /*Make sure the image is not cached*/

   header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");   // Date in the past

   header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified

   header ("Cache-Control: no-cache, must-revalidate");   // HTTP/1.1

   header ("Pragma: no-cache");                     // HTTP/1.0

   if ($debug) {

     header ("Content-type: text/html");

     print htmlentities( $command ) . "\n\n\n\n\n";

    }

   else {

     header ("Content-type: image/gif");

     passthru($command);

    }

 }

 

?>

 

19.1.23. Script check_sge.sh

 

#!/bin/bash

 

STATUS_OK=0

STATUS_WARNING=1

STATUS_ERROR=2

HOSTNAME=`uname -n`

ERROR=0

 

if ! [ -f /usr/local/sge/default/common/act_qmaster ]; then

   echo "SGE ERROR: common zone not mounted on $HOSTNAME"

   exit ${STATUS_ERROR}

fi

 

SGE_MASTER=`cat /usr/local/sge/default/common/act_qmaster`

 

if [ "$1" == "master" ]; then {

   if [ $HOSTNAME != $SGE_MASTER ]; then {

      echo "SGE Master not running, check $SGE_MASTER"

      exit ${STATUS_OK}

      }

   else {

      SGE_RUNNING=`ps waux | grep sge_qmaster | grep -v grep|wc -l`

      if [ $SGE_RUNNING -eq 0 ]; then

         echo "SGE ERROR: SGE missing on $HOSTNAME"

         exit ${STATUS_ERROR}

      else

         echo "SGE master running on $HOSTNAME"

         exit ${STATUS_OK}

      fi

      }

   fi

  }

else

   # Nodo de ejecución. Comprobamos si $1 existe en lista de nodos

   NODE_EXIST=`grep -w ^$1 /root/files/nodes/nodes|wc -l`

   if [ "$NODE_EXIST" -eq 0 ]; then

      echo "Node doesn't exist in cluster"

      exit ${STATUS_ERROR}

   fi

 

   if [ "`/usr/local/sge/bin/lx24-x86/qhost -h $1|grep -w ^$1|awk '{print $4}'`" == "-" ]; then

      echo "SGE ERROR: sge_execd down on $1"

      exit ${STATUS_ERROR}

   else

      echo "sge_execd running on $1"

      exit ${STATUS_OK}

   fi

fi

 

19.1.24. Fichero dhcp.conf

 

use-host-decl-names on;

 

default-lease-time 9999999999;

max-lease-time     9999999999;

ddns-update-style interim;

ddns-domainname "cluster.lsi";

ddns-updates on;

 

include "/etc/dhcp3/dhcpd3.key";

 

zone cluster.lsi. {

   primary 127.0.0.1;

}

 

zone 168.192.in-addr.arpa. {

   primary 127.0.0.1;

}

 

 

failover peer "cluster-dhcp" {

   primary;                             # we are a primary

   address      master-cluster1;        # address to listen on

   peer address master-cluster2;        # who we connect to

 

   port 519;                            # port to use for msgs

   peer port 521;                       # where we send msgs

   max-response-delay 60;               # how many seconds to

                                        # wait before we

                                        # determine a

                                        # failure

 

   max-unacked-updates 10;              # number of unacked

                                        # packets to send

 

   mclt 3600;                           # only defined on primary

   split 128;

   load balance max seconds 5;

}

 

 

 

subnet 192.168.0.0 netmask 255.255.0.0 {

  option routers 192.168.0.202;

  option domain-name "lsi.upc.edu";

  option domain-name-servers 147.83.20.5, 147.83.20.6, 147.83.2.3;

 pool {

      failover peer "cluster-dhcp";

      deny dynamic bootp clients;

      range 192.168.0.100 192.168.0.111;

}

 

  group {

    default-lease-time -1;

    option vendor-class-identifier "PXEClient";

 

    #### Cluster Nodes ####

 

    host node208 {

  hardware ethernet 00:22:19:50:5C:E9;

      fixed-address 192.168.2.108;

    }

 

    host node313 {

  hardware ethernet 00:22:19:50:5C:D0;

      fixed-address 192.168.3.113;

    }

 

    host node310 {

  hardware ethernet 00:E0:81:71:44:B1;

      fixed-address 192.168.3.110;

    }

 

    host node207 {

  hardware ethernet 00:E0:81:5D:47:B2;

      fixed-address 192.168.2.107;

    }

 

    host node311 {

  hardware ethernet 00:E0:81:5E:C0:D6;

      fixed-address 192.168.3.111;

    }

 

    host node309 {

  hardware ethernet 00:E0:81:55:27:31;

      fixed-address 192.168.3.109;

    }

 

    host node308 {

  hardware ethernet 00:E0:81:55:27:2F;

      fixed-address 192.168.3.108;

    }

 

    host node307 {

  hardware ethernet 04:4B:80:80:80:03;

      fixed-address 192.168.3.107;

    }

 

    host node312 {

  hardware ethernet 00:E0:81:5E:C1:65;

      fixed-address 192.168.3.112;

    }

 

    host node111 {

  hardware ethernet 00:E0:81:71:41:F8;

fixed-address 192.168.1.111;

    }

 

    host node110 {

  hardware ethernet 00:E0:81:71:44:BA;

      fixed-address 192.168.1.110;

    }

 

    host node109 {

  hardware ethernet 00:E0:81:71:41:BC;

      fixed-address 192.168.1.109;

    }

 

    host node108 {

  hardware ethernet 00:E0:81:5E:E7:A5;

      fixed-address 192.168.1.108;

    }

 

    host node306 {

  hardware ethernet 00:E0:81:5E:F7:A1;

      fixed-address 192.168.3.106;

    }

 

    host node107 {

  hardware ethernet 00:22:19:92:A9:BA;

      fixed-address 192.168.1.107;

    }

 

    host node118 {

  hardware ethernet 00:13:20:22:EC:06;

      fixed-address 192.168.1.118;

    }

 

    host node117 {

  hardware ethernet 00:11:11:C9:7B:2B;

      fixed-address 192.168.1.117;

    }

 

    host node116 {

  hardware ethernet 00:0C:F1:90:A1:DE;

      fixed-address 192.168.1.116;

    }

 

    host node115 {

  hardware ethernet 00:0C:F1:8F:47:D4;

      fixed-address 192.168.1.115;

    }

 

    host node114 {

  hardware ethernet 00:22:19:50:5C:6C;

      fixed-address 192.168.1.114;

    }

 

    host node113 {

  hardware ethernet 00:22:19:50:5C:D5;

      fixed-address 192.168.1.113;

    }

 

    host node112 {

  hardware ethernet 00:22:19:50:5A:41;

      fixed-address 192.168.1.112;

    }

 

    host node106 {

  hardware ethernet 00:E0:81:71:41:F2;

      fixed-address 192.168.1.106;

    }

 

    host node304 {

  hardware ethernet 00:1E:C9:FE:3E:48;

      fixed-address 192.168.3.104;

    }

 

    host node305 {

  hardware ethernet 00:1E:C9:FE:45:98;

      fixed-address 192.168.3.105;

    }

 

    host node100 {

  hardware ethernet 00:1C:23:E3:0C:58;

      fixed-address 192.168.1.100;

    }

 

    host node303 {

  hardware ethernet 00:1E:C9:FE:3A:49;

      fixed-address 192.168.3.103;

    }

 

    host node302 {

  hardware ethernet 00:1E:C9:FE:32:4B;

      fixed-address 192.168.3.102;

    }

 

    host node301 {

  hardware ethernet 00:1D:09:F0:2C:BE;

      fixed-address 192.168.3.101;

}

 

    host node300 {

  hardware ethernet 00:1D:09:F0:2E:83;

      fixed-address 192.168.3.100;

    }

 

    host node206 {

  hardware ethernet 00:18:8B:F8:2F:29;

      fixed-address 192.168.2.106;

    }

 

    host node205 {

  hardware ethernet 00:18:8B:F8:44:C5;

      fixed-address 192.168.2.105;

    }

 

    host node204 {

  hardware ethernet 00:18:8B:F8:45:76;

      fixed-address 192.168.2.104;

    }

 

    host node203 {

  hardware ethernet 00:1C:23:E3:08:5C;

      fixed-address 192.168.2.103;

    }

 

    host node202 {

  hardware ethernet 00:1D:09:F0:D0:BB;

      fixed-address 192.168.2.102;

    }

 

    host node201 {

  hardware ethernet 00:1D:09:F0:2C:D3;

      fixed-address 192.168.2.101;

    }

 

    host node105 {

  hardware ethernet 00:1D:09:F0:2E:9B;

      fixed-address 192.168.1.105;

    }

 

    host node104 {

  hardware ethernet 00:1D:09:F0:2E:FB;

      fixed-address 192.168.1.104;

    }

 

    host node103 {

  hardware ethernet 00:1D:09:F0:2F:AC;

      fixed-address 192.168.1.103;

    }

 

    host node101 {

  hardware ethernet 00:1C:23:E3:0B:8C;

      fixed-address 192.168.1.101;

    }

 

    host node102 {

  hardware ethernet 00:1D:09:F0:30:27;

      fixed-address 192.168.1.102;

    }

 

    host node200 {

  hardware ethernet 00:1D:09:F0:2E:1A;

      fixed-address 192.168.2.100;

    }

 

    host disc6 {

  hardware ethernet 00:11:11:CD:AF:E1;

      fixed-address 192.168.0.106;

    }

 

    host disc5 {

  hardware ethernet 00:13:20:44:C5:7C;

      fixed-address 192.168.0.105;

    }

 

    host disc4 {

  hardware ethernet 00:13:20:44:D6:57;

      fixed-address 192.168.0.104;

    }

 

    host disc3 {

  hardware ethernet 00:13:20:44:C6:1A;

      fixed-address 192.168.0.103;

    }

 

    host disc2 {

  hardware ethernet 00:13:20:44:D3:76;

      fixed-address 192.168.0.102;

    }

 

    host disc1 {

  hardware ethernet 00:13:20:44:C7:B9;

      fixed-address 192.168.0.101;

    }

}

}

 

19.1.25. Fichero update.exim4.conf en master-cluster1

 

dc_eximconfig_configtype='satellite'

dc_other_hostnames=''

dc_local_interfaces='127.0.0.1;192.168.0.201'

dc_readhost='lsi.upc.edu'

dc_relay_domains=''

dc_minimaldns='false'

dc_relay_nets='192.168.0.0/24'

dc_smarthost='mail.lsi.upc.edu'

CFILEMODE='644'

dc_use_split_config='false'

dc_hide_mailname='true'

dc_mailname_in_oh='true'

dc_localdelivery='mail_spool'

 

19.1.26. Fichero update.exim4.conf en nodos de computación y servidores de disco

 

dc_eximconfig_configtype='satellite'

dc_other_hostnames=''

dc_local_interfaces='127.0.0.1;192.168.0.202'

dc_readhost='lsi.upc.edu'

dc_relay_domains=''

dc_minimaldns='false'

dc_relay_nets='192.168.0.0/24'

dc_smarthost='mail.lsi.upc.edu'

CFILEMODE='644'

dc_use_split_config='false'

dc_hide_mailname='true'

dc_mailname_in_oh='true'

dc_localdelivery='mail_spool'

 

19.1.27. Fichero ntp.conf en nodos master-cluster

 

# /etc/ntp.conf, configuration for ntpd

 

driftfile /var/lib/ntp/ntp.drift

statsdir /var/log/ntpstats/

 

statistics loopstats peerstats clockstats

filegen loopstats file loopstats type day enable

filegen peerstats file peerstats type day enable

filegen clockstats file clockstats type day enable

 

 

# You do need to talk to an NTP server or two (or three).

#server ntp.your-provider.example

 

# pool.ntp.org maps to more than 300 low-stratum NTP servers.

# Your server will pick a different set every time it starts up.

#  *** Please consider joining the pool! ***

#  *** <http://www.pool.ntp.org/join.html> ***

server ntp.lsi.upc.edu iburst

server hora.rediris.es iburst

server 0.debian.pool.ntp.org iburst

server 1.debian.pool.ntp.org iburst

server 2.debian.pool.ntp.org iburst

server 3.debian.pool.ntp.org iburst

 

# By default, exchange time with everybody, but don't allow configuration.

# See /usr/share/doc/ntp-doc/html/accopt.html for details.

restrict -4 default kod notrap nomodify nopeer noquery

restrict -6 default kod notrap nomodify nopeer noquery

 

# Local users may interrogate the ntp server more closely.

restrict 127.0.0.1

restrict ::1

 

# Clients from this (example!) subnet have unlimited access,

# but only if cryptographically authenticated

#restrict 192.168.123.0  mask  255.255.255.0 notrust

 

# If you want to provide time to your local subnet, change the next line.

# (Again, the address is an example only.)

broadcast 192.168.0.255

 

# If you want to listen to time broadcasts on your local subnet,

# de-comment the next lines. Please do this only if you trust everybody

# on the network!

disable auth

broadcastclient

 

19.1.28. Fichero ntp.conf en nodos de computación y servidores de disco

 

# /etc/ntp.conf, configuration for ntpd

 

driftfile /var/lib/ntp/ntp.drift

statsdir /var/log/ntpstats/

 

statistics loopstats peerstats clockstats

filegen loopstats file loopstats type day enable

filegen peerstats file peerstats type day enable

filegen clockstats file clockstats type day enable

 

 

# You do need to talk to an NTP server or two (or three).

#server ntp.your-provider.example

 

# pool.ntp.org maps to more than 300 low-stratum NTP servers.

# Your server will pick a different set every time it starts up.

#  *** Please consider joining the pool! ***

#  *** <http://www.pool.ntp.org/join.html> ***

server master-cluster1 iburst

server master-cluster2 iburst

 

# By default, exchange time with everybody, but don't allow configuration.

# See /usr/share/doc/ntp-doc/html/accopt.html for details.

restrict -4 default kod notrap nomodify nopeer noquery

restrict -6 default kod notrap nomodify nopeer noquery

 

# Local users may interrogate the ntp server more closely.

#restrict 127.0.0.1

#restrict ::1

 

# Clients from this (example!) subnet have unlimited access,

# but only if cryptographically authenticated

#restrict 192.168.123.0  mask  255.255.255.0 notrust

 

# If you want to provide time to your local subnet, change the next line.

# (Again, the address is an example only.)

#broadcast 192.168.123.255

 

# If you want to listen to time broadcasts on your local subnet,

# de-comment the next lines. Please do this only if you trust everybody

# on the network!

#disable auth

#broadcastclient

 

19.1.29. Fichero /etc/exports

 

/etc/exports

 

 # /etc/exports: the access control list for filesystems which may be exported

#               to NFS clients.  See exports(5).

/mnt/glusterfs/home      master-cluster2 (ro, fsid=0, no_root_squash, sync,subtree_check)

 

19.1.30. Fichero awstats.conf

 

LogFile="/var/log/apache/access.log"

LogType=W

LogFormat=4

LogSeparator=" "

SiteDomain="master-cluster1.lsi.upc.edu"

HostAliases="localhost 127.0.0.1"

DNSLookup=1

DirData="/var/lib/awstats"

DirCgi="/cgi-bin"

DirIcons="/awstats-icon"

AllowToUpdateStatsFromBrowser=0

AllowFullYearView=2

EnableLockForUpdate=0

DNSStaticCacheFile="dnscache.txt"

DNSLastUpdateCacheFile="dnscachelastupdate.txt"

SkipDNSLookupFor=""

AllowAccessFromWebToAuthenticatedUsersOnly=0

AllowAccessFromWebToFollowingAuthenticatedUsers=""

AllowAccessFromWebToFollowingIPAddresses=""

CreateDirDataIfNotExists=0

BuildHistoryFormat=text

BuildReportFormat=html

SaveDatabaseFilesWithPermissionsForEveryone=0

PurgeLogFile=0

ArchiveLogRecords=0

KeepBackupOfHistoricFiles=0

DefaultFile="index.html"

SkipHosts=""

SkipUserAgents=""

SkipFiles=""

SkipReferrersBlackList=""

OnlyHosts=""

OnlyUserAgents=""

OnlyFiles=""

NotPageList="css js class gif jpg jpeg png bmp ico swf"

ValidHTTPCodes="200 304"

ValidSMTPCodes="1 250"

AuthenticatedUsersNotCaseSensitive=0

URLNotCaseSensitive=0

URLWithAnchor=0

URLQuerySeparators="?;"

URLWithQuery=0

URLWithQueryWithOnlyFollowingParameters=""

URLWithQueryWithoutFollowingParameters=""

URLReferrerWithQuery=0

WarningMessages=1

ErrorMessages=""

DebugMessages=0

NbOfLinesForCorruptedLog=50

WrapperScript=""

DecodeUA=0

MiscTrackerUrl="/js/awstats_misc_tracker.js"

LevelForBrowsersDetection=2         # 0 disables Browsers detection.

                                    # 2 reduces AWStats speed by 2%

                                    # allphones reduces AWStats speed by 5%

LevelForOSDetection=2               # 0 disables OS detection.

                                    # 2 reduces AWStats speed by 3%

LevelForRefererAnalyze=2            # 0 disables Origin detection.

                                    # 2 reduces AWStats speed by 14%

LevelForRobotsDetection=2           # 0 disables Robots detection.

                                    # 2 reduces AWStats speed by 2.5%

LevelForSearchEnginesDetection=2    # 0 disables Search engines detection.

                                    # 2 reduces AWStats speed by 9%

LevelForKeywordsDetection=2         # 0 disables Keyphrases/Keywords detection.

                                    # 2 reduces AWStats speed by 1%

LevelForFileTypesDetection=2        # 0 disables File types detection.

                                    # 2 reduces AWStats speed by 1%

LevelForWormsDetection=0            # 0 disables Worms detection.

                                    # 2 reduces AWStats speed by 15%

UseFramesWhenCGI=1

DetailedReportsOnNewWindows=1

Expires=0

MaxRowsInHTMLOutput=1000

Lang="auto"

DirLang="/usr/share/awstats/lang"

ShowMenu=1                                      

ShowSummary=UVPHB

ShowMonthStats=UVPHB

ShowDaysOfMonthStats=VPHB

ShowDaysOfWeekStats=PHB

ShowHoursStats=PHB

ShowDomainsStats=PHB

ShowHostsStats=PHBL

ShowAuthenticatedUsers=0

ShowRobotsStats=HBL

ShowWormsStats=0

ShowEMailSenders=0

ShowEMailReceivers=0

ShowSessionsStats=1

ShowPagesStats=PBEX

ShowFileTypesStats=HB

ShowFileSizesStats=0         

ShowOSStats=1

ShowBrowsersStats=1

ShowScreenSizeStats=0

ShowOriginStats=PH

ShowKeyphrasesStats=1

ShowKeywordsStats=1

ShowMiscStats=a

ShowHTTPErrorsStats=1

ShowSMTPErrorsStats=0

ShowClusterStats=0

AddDataArrayMonthStats=1

AddDataArrayShowDaysOfMonthStats=1

AddDataArrayShowDaysOfWeekStats=1

AddDataArrayShowHoursStats=1

IncludeInternalLinksInOriginSection=0

MaxNbOfDomain = 10

MinHitDomain  = 1

MaxNbOfHostsShown = 10

MinHitHost    = 1

MaxNbOfLoginShown = 10

MinHitLogin   = 1

MaxNbOfRobotShown = 10

MinHitRobot   = 1

MaxNbOfPageShown = 10

MinHitFile    = 1

MaxNbOfOsShown = 10

MinHitOs      = 1

MaxNbOfBrowsersShown = 10

MinHitBrowser = 1

MaxNbOfScreenSizesShown = 5

MinHitScreenSize = 1

MaxNbOfWindowSizesShown = 5

MinHitWindowSize = 1

MaxNbOfRefererShown = 10

MinHitRefer   = 1

MaxNbOfKeyphrasesShown = 10

MinHitKeyphrase = 1

MaxNbOfKeywordsShown = 10

MinHitKeyword = 1

MaxNbOfEMailsShown = 20

MinHitEMail   = 1

FirstDayOfWeek=1

ShowFlagLinks=""

ShowLinksOnUrl=1

UseHTTPSLinkForUrl=""

MaxLengthOfShownURL=64

HTMLHeadSection=""

HTMLEndSection=""

Logo="awstats_logo6.png"

LogoLink="http://awstats.sourceforge.net"

BarWidth   = 260

BarHeight  = 90

StyleSheet=""

color_Background="FFFFFF"           # Background color for main page (Default = "FFFFFF")

color_TableBGTitle="CCCCDD"         # Background color for table title (Default = "CCCCDD")

color_TableTitle="000000"           # Table title font color (Default = "000000")

color_TableBG="CCCCDD"              # Background color for table (Default = "CCCCDD")

color_TableRowTitle="FFFFFF"  # Table row title font color (Default = "FFFFFF")

color_TableBGRowTitle="ECECEC"      # Background color for row title (Default = "ECECEC")

color_TableBorder="ECECEC"          # Table border color (Default = "ECECEC")

color_text="000000"                       # Color of text (Default = "000000")

color_textpercent="606060"          # Color of text for percent values (Default = "606060")

color_titletext="000000"            # Color of text title within colored Title Rows (Default = "000000")

color_weekend="EAEAEA"              # Color for week-end days (Default = "EAEAEA")

color_link="0011BB"                       # Color of HTML links (Default = "0011BB")

color_hover="605040"                # Color of HTML on-mouseover links (Default = "605040")

color_u="FFAA66"                    # Background color for number of unique visitors (Default = "FFAA66")

color_v="F4F090"                    # Background color for number of visites (Default = "F4F090")

color_p="4477DD"                    # Background color for number of pages (Default = "4477DD")

color_h="66DDEE"                    # Background color for number of hits (Default = "66DDEE")

color_k="2EA495"                    # Background color for number of bytes (Default = "2EA495")

color_s="8888DD"                    # Background color for number of search (Default = "8888DD")

color_e="CEC2E8"                    # Background color for number of entry pages (Default = "CEC2E8")

color_x="C1B2E2"                    # Background color for number of exit pages (Default = "C1B2E2")

LoadPlugin="hashfiles"

ExtraTrackedRowsLimit=500

Include "/etc/awstats/awstats.conf.local"

 

19.1.31. Fichero .htaccess

 

AuthUserFile /var/www/awstats/cgi-bin/.htpasswd

AuthGroupFile /dev/null

AuthName "master-cluster1 WWW statistics"

AuthType Basic

<Limit GET>

        require user ivanc gabriel

        order deny,allow

        allow from all

</limit>

 

19.1.32. Script wakeup-cluster.sh

 

#!/bin/tcsh

#

#  Script de encendido del cluster                                            #

#

#  Uso: wakeup-cluster [nombre_nodo/all]                                                   #                                                                       #  Primer parámetro:                                                        #

#    Se especifica el nombre del nodo a levantar o "all" para           #    hacerlo en todos los nodos del cluster.                               #

#                                                                           

#                                                                          

#    Iván C.     12/09/08                                                      #                       

#

 

if ( "$#" != "1" ) then

   echo "Uso correcto: wakeup-cluster [-g grupo] [num_nodo/all]"

   exit 1

endif

 

 

switch($1)

    case 'all':

       foreach node (`cat /etc/hosts|awk '{print $2}'`)

             echo Waking-up $node

             /usr/sbin/etherwake -i eth0 ` arp -a | grep node105 |awk '{print $4}'`

       end

          breaksw

default:

       if ( `grep $1 /etc/hosts` != "" ) then

          echo Waking-up $1

          /usr/sbin/etherwake -i eth0 ` arp -a | grep node105 |awk '{print $4}'`

       else

          echo "Error: nodo $1 no existe"

          exit 1

       endif

       breaksw

endsw

 

19.1.33. Script halt-cluster.sh

 

#

#  Script de parada/reboot de cluster                                                                                #

#                                                                   

#  Uso: halt-cluster [-r/-h] [nombre_nodo/all]                                  # 

#                                                                            

#  Primer parámetro:                                                          

#

#    La opcion -r hace un reboot de un nodo                               

#    La opcion -h hace halt (parada eléctrica) del nodo, dejándolo en  

#    condiciones de ralizar wake-on-lan                                      #                                                                  

#  Segundo parámetro:                                                         #

#    Se especifica el nombre del nodo a parar/rebotar o "all" para

#    hacerlo en todos los nodos del cluster.                               #

#                                                                            

#                                                                           #

#    Iván C.     12/09/08                                                      #

#

 

if ( "$#" != "2" ) then

   echo "Uso correcto: halt-cluster [-r/-h] [num_nodo/all]"

   exit 1

endif

 

if (( "$1" != "-r") && ( "$1" != "-h")) then

    echo "Parametro incorrecto $1. Uso correcto: halt-cluster [-r/-h] [nodo/all]"

    exit 1

endif

 

switch ($1)

  case "-r":

         set command_line="/sbin/reboot"

         set command="Rebooting"

         breaksw

  case "-h":

         set command_line="/sbin/halt"

         set command="Halting"

         breaksw

  default:

         echo "Error en argumento. Uso correcto: halt-cluster [-r/-h] [nodo/all]"

         exit 1

         breaksw

  endsw

 

switch ($2)

  case "all":  

         foreach p (`cat /etc/hosts|grep node|awk '{print $2}'`)

              echo $command $p

              if (`fping -u $p` == "") then

                  ssh $p $command_line

              else

                 echo "Warning: $p sin conectividad"

              endif

         end

         breaksw

  default:

         breaksw

  endsw

 

19.1.34. Script alta_nodo.sh

 

#!/bin/bash

 

# Script de alta de nodos  (Septiembre 2008)

 

ESTE_MASTER=`uname -n`

if [ $ESTE_MASTER == "master-cluster1" ]; then

   OTRO_MASTER="master-cluster2"

else

   OTRO_MASTER="master-cluster1"

fi

 

RANGO_IP=192.168

RANGO_STORAGE=0

RANGO_EIXAM=1

RANGO_TENADA=2

RANGO_NOZOMI=3

MCAST_CHANNEL_EIXAM=239.2.11.72

MCAST_CHANNEL_NOZOMI=239.2.11.73

MCAST_CHANNEL_TENADA=239.2.11.74

MCAST_CHANNEL_STORAGE=239.2.11.75

 

LINEA=""

 

echo "Script de ALTA de nodos en cluster LSI"

echo ""

read -p "1) A qu? grupo pertenece el nuevo nodo? (eixam/nozomi/tenada/storage) " grupo

 

if [ $grupo == "eixam" ]; then

   rango=$RANGO_EIXAM

elif [ $grupo == "nozomi" ]; then

   rango=$RANGO_NOZOMI

elif [ $grupo == "tenada" ]; then

   rango=$RANGO_TENADA

elif [ $grupo == "storage" ]; then

   rango=$RANGO_STORAGE

else

   echo "Error, grupo incorrecto"

   exit 1

fi

 

echo ""

read -p "2) @MAC " MAC_NODO

 

# Comprobar MAC

 

echo ""

read -p "3) Numero de nodo (Sin contar el \"$rango\" por ser nodo de $grupo) " num_nodo

 

if [ $num_nodo -gt 99 ]; then

   echo "   N?mero de nodo debe ser < 100"

   exit 1

fi

 

IP_AUX=`expr $num_nodo \+ 100`

IP_NODO=$RANGO_IP.$rango.$IP_AUX

 

 

# Damos nombre al nodo:

if [ $grupo == "storage" ]; then

   NOMBRE_NODO=disc$num_nodo

else

   NOMBRE_NODO=node$rango$num_nodo

fi

 

echo ""

echo "   Nuevo nodo: $NOMBRE_NODO con IP $IP_NODO"

 

# Comprobamos que nodo no esta en /etc/hosts

if [ `grep $NOMBRE_NODO /etc/hosts | wc -l` -ne 0 ]; then

   echo "   Error. $NOMBRE_NODO ya est? dado de alta en /etc/hosts"

   exit 1

fi

 

if [ `grep ^$NOMBRE_NODO /root/files/nodes/nodes|wc -l` -ne 0 ]; then

   echo "   Error. $NOMBRE_NODO ya est? dado de alta en fichero nodes"

   exit 1

fi

 

LINEA="$NOMBRE_NODO"

 

if [ $grupo != "storage" ]; then

   LINEA="$LINEA        NO      -       -"

else

   echo ""

   read -p "5) Rol del nuevo nodo? (P)rimario o (S)ecundario " rol

   if [ $rol != "p" ] && [ $rol != "P" ] && [ $rol != "s" ] && [ $rol != "S" ]; then

      echo "Error, rol debe ser \"P\" ? \"S\""

   fi

   case $rol in

      p) rol="P"

         ;;

      s) rol="S"

         ;;

   esac

 

   LINEA="$LINEA        SI      $rol"

   echo ""

   read -p "6) Pairnode (nombre completo) ? " pairnode

   # Si rol de nodo es secundario => pairnode es primario => DEBE EXISTIR

   LINEA="$LINEA        $pairnode"

   EXISTE_PRIMARIO=`grep ^$pairnode /root/files/nodes/nodes`

   if [ "$rol" == "s" ] || [ "$rol" == "S" ]; then

if [ "$EXISTE_PRIMARIO" == "" ]; then

         echo "   Error, pairnode $pairnode no existe"

         exit 1

      else

         ROL_PAIRNODE=`echo $EXISTE_PRIMARIO|awk '{print $3}'`

         if [ $ROL_PAIRNODE != "P" ]; then

            echo "   Error. Pairnode ($pairnode) no es nodo PRIMARIO"

            exit 1

         else

            PAIRNODE_PAIRNODE=`echo $EXISTE_PRIMARIO|awk '{print $4}'`

            if [ $PAIRNODE_PAIRNODE != "$NOMBRE_NODO" ]; then

               echo "   Error. Pairnode ($pairnode) no tiene a $NOMBRE_NODO como secundario"

               exit 1

            else

               LINEA="$LINEA       $PAIRNODE"

            fi

         fi

       fi

   fi

   LINEA="$LINEA        $PAIRNODE"

  fi

 

# Añadimos información de la cola

 

## Comprobar cola

if [ $grupo == "eixam" ]; then

   LINEA="$LINEA            eixam           $MCAST_CHANNEL_EIXAM"

elif [ $grupo == "nozomi" ]; then

   LINEA="$LINEA        nozomi          $MCAST_CHANNEL_NOZOMI"

elif [ $grupo == "tenada" ]; then

   LINEA="$LINEA        tenada          $MCAST_CHANNEL_TENADA"

elif [ $grupo == "storage" ]; then

   LINEA="$LINEA        storage         $MCAST_CHANNEL_STORAGE"

else

   echo "ERROR: Cola $COLA no existe"

   exit 1

fi

 

echo "$LINEA"

 

## Metemos nodo en DHCP

 

echo ""

echo "* Damos de alta $nombre_nodo en DHCP"

echo ""

sed 's/    #### Cluster Nodes ####/    #### Cluster Nodes ####\n\n    host '$NOMBRE_NODO' {\n  har

dware ethernet '$MAC_NODO';\n      fixed-address '$IP_NODO';\n    }/' /etc/dhcp3/dhcpd.conf > /tmp

/.dhcpd.conf

cp /etc/dhcp3/dhcpd.conf /etc/dhcp3/dhcpd.conf.old

cp /tmp/.dhcpd.conf /etc/dhcp3/dhcpd.conf

rm /tmp/.dhcpd.conf

 

/etc/init.d/dhcp3-server restart

 

# Copiamos config. dhcp al otro nodo master y reiniciamos

echo "[LCLSI] Reiniciando dhcp en el otro nodo master"

sed s/"  option routers 192.168.0.201;"/"  option routers 192.168.0.202;"/ /etc/dhcp3/dhcpd.conf >

 /tmp/.dhcpd.conf

scp /tmp/.dhcpd.conf $OTRO_MASTER:/etc/dhcp3/dhcpd.conf

rm /tmp/.dhcpd.conf

ssh $OTRO_MASTER "/etc/init.d/dhcp3-server restart"

 

# Añadimos nodo a /etc/hosts

echo "$IP_NODO  $NOMBRE_NODO" >> /etc/hosts

 

# 6. SunGrid. Convertimos host en nodo de ejecución

 

if [ $grupo != "storage" ]; then

   echo "[LCLSI] Dando permisos administrativos a nodo $NOMBRE_NODO en SGE"

   /usr/local/sge/bin/lx24-x86/qconf -ah $NOMBRE_NODO

fi

 

   echo $LINEA >> /root/files/nodes/nodes

   scp /root/files/nodes/nodes $OTRO_MASTER:/root/files/nodes/nodes

 

   # A?adimos host a lista de dsh

   echo $NOMBRE_NODO >> /etc/dsh/machines.list

   echo $NOMBRE_NODO >> /etc/dsh/group/$grupo

   scp /etc/dsh/machines.list $OTRO_MASTER:/etc/dsh/

   scp /etc/dsh/group/$grupo $OTRO_MASTER:/etc/dsh/groups

   # Propagamos ficheros hosts y nodes a todo el cluster

   #/usr/bin/dsh -a "scp $ESTE_MASTER:/etc/hosts /etc/"

   scp /etc/hosts $OTRO_MASTER:/etc/

 

19.1.35. Script alta_usuario.sh

 

#!/bin/tcsh

#

# Script de alta de usuario en cluster

 

set ESTE_MASTER=`uname -n`

if ( "$ESTE_MASTER" == "master-cluster1" ) then

   set OTRO_MASTER="master-cluster2"

else

   set OTRO_MASTER="master-cluster1"

endif

 

set CLUSTERS="eixam nozomi tenada"

 

if ( "$#" != "2" ) then

   echo "ERROR. N?mero de parámetros incorrecto"

   echo "       Uso correcto: new_user.sh username cluster"

   exit 1

endif

 

if ( `grep -w $1 /etc/allowed_users | wc -l` != "0" ) then

   echo "ERROR: Usuario $1 ya incluido en lista de acceso"

   exit 1

endif

 

if ( `/usr/bin/ypcat passwd | cut -f1 -d: | grep -w $1 | wc -l` == "0" ) then

   echo "ERROR: Usuario $1 no es usuario NIS"

   exit 1

endif

 

set cluster_valido=0

foreach cluster ($CLUSTERS)

  if ( $2 == $cluster ) then

     set cluster_valido=1

     break;

  endif

end

 

if ( $cluster_valido == 0 ) then

    echo "[LCLSI] Error, cluster no existe."

    echo "        Clusters v?lidos: $CLUSTERS"

    exit 1

endif

 

echo "$1                $2" >> /etc/allowed_users

/root/scripts/build_users.sh

/root/scripts/build_homes.sh

 

echo "Propagando info usuario a nodos del cluster"

echo "ESTE MASTER: $ESTE_MASTER"

/usr/bin/dsh -a "scp ${ESTE_MASTER}:/etc/passwd.nodes /etc/passwd;scp ${ESTE_MASTER}:/etc/shadow /

etc/shadow;scp ${ESTE_MASTER}:/etc/group /etc/group"

scp /etc/allowed_users ${OTRO_MASTER}:/etc/allowed_users

scp /etc/passwd ${OTRO_MASTER}:/etc/passwd

scp /etc/shadow ${OTRO_MASTER}:/etc/shadow

scp /etc/group ${OTRO_MASTER}:/etc/group

 

 

# A?adimos usuario a lista de acceso

echo "A?adimos usuario $1 a lista de acceso $2"

/usr/local/sge/bin/lx24-x86/qconf -au $1 $2

 

19.1.36. Script build_users.sh

 

#!/bin/bash

#

# Script de creación de ficheros passwd, shadow y group

#

 

cp /etc/passwd.old /etc/passwd

cp /etc/passwd.old /etc/passwd.nodes

cp /etc/shadow.old /etc/shadow

cp /etc/group.old /etc/group

# Inclu?mos grupos it y sistemas en /etc/group

 

echo "it:x:100:" >> /etc/group

echo "beclsi:x:1900:" >> /etc/group

echo "becproy:x:1800:" >> /etc/group

echo "doctorat:x:1600:" >> /etc/group

echo "sistemas:x:50:" >>  /etc/group

echo "pfc:x:3100:" >> /etc/group

echo "p:x:500:" >> /etc/group

echo "ia:x:400:" >> /etc/group

echo "master:x:40000:" >> /etc/group

echo "altres:x:600:" >> /etc/group

 

# Añadimos usuarios de grupo

 

 set ALLOWED="tools:x:2000:"

foreach user (`cat /etc/allowed_users|awk '{print $1}'`)

  set line=`/usr/bin/ypcat passwd | grep -w ^$user`

  set USERNAME=`echo $line |cut -f1 -d:`

  set PASSWORD=`echo $line |cut -f2 -d:`

  set UID=`echo $line | cut -f3 -d:`

  set GID=`echo $line | cut -f4 -d:`

  if ( $USERNAME != "" ) then

     echo $USERNAME":x:"$UID":"$GID"::/home/usuaris/"$USERNAME":/bin/tcsh" >> /etc/passwd

     echo $USERNAME":x:"$UID":"$GID"::/home/usuaris/"$USERNAME":/bin/false" >> /etc/passwd.nodes

     echo $USERNAME":"$PASSWORD":12424:0:99999:7:::" >> /etc/shadow

  endif

 

  set ALLOWED=$ALLOWED$user","

end

 

# Creamos grupo tools

 

echo $ALLOWED >> /etc/group

 

19.1.37. Script build_homes.sh

 

#!/bin/tcsh

#

# Script de creación de zonas de usuario

 

if !( -d /home/usuaris ) then

   echo "[LCLSI] Creada zona de usuarios"

   mkdir /home/usuaris

endif

 

# Creamos zona tools

 

if !( -d /home/usuaris/tools ) then

   echo "[LCLSI] Creada zona tools"

   mkdir /home/usuaris/tools

   chown root:tools /home/usuaris/tools

   chmod 775 /home/usuaris/tools

endif

 

foreach line (`cat /etc/passwd | awk '/:400::|:500::|:3100::|:100::|:50::|:1900::|:1800::|:600::|:

40000::|:1600::/ {print $1}'`)

  set USERNAME=`echo $line | cut -f1 -d:`

  set GROUP=`echo $line | cut -f4 -d:`

  if ( $USERNAME != "" ) then

    if !( -d /home/usuaris/$USERNAME ) then

       echo "[LCLSI] Creada zona de usuario $USERNAME"

       mkdir /home/usuaris/$USERNAME

       cp /etc/skel/.tcshrc /home/usuaris/$USERNAME/

       # Fichero .sge_qstat

       set QUEUE=`grep -w ^$USERNAME /etc/allowed_users|awk '{print $2}'`

       if ( $QUEUE == "all" ) then

          echo "-u *" > /home/usuaris/$USERNAME/.sge_qstat

       else

          echo "-u * -q $QUEUE" > /home/usuaris/$USERNAME/.sge_qstat

       endif

       chown -R "$USERNAME":"$GROUP" /home/usuaris/$USERNAME

    endif

  endif

end

 

19.1.38. Script master_lectura.sh

 

#!/bin/sh

 

echo " "

echo "master <numero_jobs> <concurrencia>"

echo " "

 

if [ "$1" == "" ]

then

    echo "Falta el parametro 1"

    exit 0

else

if [ "$2" == "" ]

then

    echo "Falta el parametro 2"

    exit 0

fi

fi

 

touch /home/usuaris/ivanc/RESULTADOS/RESULTADO_lectura.TXT

 

echo " "  >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_lectura.TXT

echo " "  >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_lectura.TXT

echo "==============================================================================" >> /home/usuaris/ivanc/R

ESULTADOS/RESULTADO_lectura.TXT

echo "Ejecutando $1 Jobs con concurrencia $2" >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_lectura.TXT

echo " " >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_lectura.TXT

contador=0

 

while [ $contador -lt $1 ] ; do

 

    qsub /home/usuaris/ivanc/EXE/slave.sh $2

 

    contador=`expr $contador + 1`

 

done

 

19.1.39. Script slave.sh

 

#!/bin/csh

 

 

#$ -M ivanc@lsi.upc.edu

#$ -m beas

 

/home/usuaris/ivanc/EXE/test-disco_lectura.sh /home/usuaris/ivanc/5MB /home/usuaris/ivanc/RESULTADOS $1

 

19.1.40. Script test-disco_lectura.sh

 

#!/bin/sh

 

echo " "

echo "test_disco_lectura.sh <path_lectura> <path_escritura> <concurrencia>"

echo " "

echo " "

 

if [ "$1" == "" ]

then

    echo "Falta el parametro 1"

    exit 0

else

if [ "$2" == "" ]

then

    echo "Falta el parametro 2"

    exit 0

else

if [ "$3" == "" ]

then

    echo "Falta el parametro 3"

    exit 0

fi

fi

fi

 

 

echo "Leyendo $1 con concurrencia $3"

echo " "

 

contador=0

 

while [ $contador -lt $3 ] ; do

 

    if [ -d $2 ]

    then

         echo "Ya existe el directorio $2 .... se sobreescribiran los archivos."

         echo " "

    else

         mkdir -p $2

    fi

 

    echo "NO => Lanzado en background el proceso TAR (sin gzip!) en $2"

#    /usr/bin/time -f "Tiempo CPU : %E s.\nCPU        : %P\nRAM        : %M\n" tar -cjf $2/$contador $1 &

   

   

    echo "Realizo un cat * > /dev/null de $2 (Resultado a?adido en $2/RESULTADO_lectura.TXT)"

/usr/bin/time -o $2/RESULTADO_lectura.TXT -a -f "Tiempo CPU `uname -n`: %E s.\nCPU        : %P\nRAM        : %

M\n" find $1 -type f -exec cat {} > /dev/null \;

 

    contador=`expr $contador + 1`

 

done

 

 

wait

 

19.1.41. Script master_escritura.sh

 

#!/bin/sh

 

echo " "

echo "master <numero_jobs> <concurrencia>"

echo " "

 

if [ "$1" == "" ]

then

    echo "Falta el parametro 1"

    exit 0

else

if [ "$2" == "" ]

then

    echo "Falta el parametro 2"

    exit 0

fi

fi

 

 

echo " "  >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_escritura.TXT

echo " "  >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_escritura.TXT

echo "==============================================================================" >> /home/usuaris/ivanc/R

ESULTADOS/RESULTADO_escritura.TXT

echo "Ejecutando $1 Jobs con concurrencia $2" >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_escritura.TXT

echo " " >> /home/usuaris/ivanc/RESULTADOS/RESULTADO_escritura.TXT

contador=0

 

 

while [ $contador -lt $1 ] ; do

 

    qsub /home/usuaris/ivanc/EXE/slave2.sh $2

 

    contador=`expr $contador + 1`

 

done

 

19.1.42. Script slave2.sh

 

#!/bin/csh

 

 

#$ -M ivanc@lsi.upc.edu

#$ -m beas

 

/home/usuaris/ivanc/EXE/test-disco_escritura.sh /dev/shm/test-disco.5Mb.tar.bz2 /home/usuaris/ivanc/5MBytes/`d

ate +%H_%M_%S`/`uname -n` $1

 

19.1.43. Script test-disco_escritura.sh

 

#!/bin/sh

 

echo " "

echo "test_disco_escritura.sh <nombre_fichero> <path_escritura> <concurrencia>"

echo " "

echo " "

echo "============================ Ficheros Disponibles ============================================"

ls *.tar.bz2

echo "=============================================================================================="

echo " "

 

 

if [ "$1" == "" ]

then

    echo "Falta el parametro 1"

    exit 0

else

if [ "$2" == "" ]

then

    echo "Falta el parametro 2"

    exit 0

else

if [ "$3" == "" ]

then

    echo "Falta el parametro 3"

    exit 0

fi

fi

fi

 

 

echo "Deshaciendo $1 en $2 con concurrencia $3"

echo " "

 

contador=0

 

while [ $contador -lt $3 ] ; do

 

    if [ -d $2/$PPID.$contador ]

    then

         echo "Ya existe el directorio $2/$contador .... se sobreescribiran los archivos."

    else

         mkdir -p $2/$PPID.$contador

    fi

 

    echo "Lanzado en background el proceso en $2/$PPID.$contador"

    /usr/bin/time -o /home/usuaris/ivanc/RESULTADOS/RESULTADO_escritura.TXT -a -f "Tiempo CPU `uname -n`: %E s

.\nCPU        : %P\nRAM        : %M\n" tar -C $2/$PPID.$contador -xjf $1  &

 

    contador=`expr $contador + 1`

 

done

 

wait

 

19.1.44. Fichero resultado_lectura.sh

 

=====================================================================

Ejecutando 1 Jobs con concurrencia 1

 

Tiempo CPU : 0:47.39 s.

CPU        : 9%

RAM        : 0

 

^^^ node4 ^^^

 

 

=====================================================================

Ejecutando 6 Jobs con concurrencia 1

 

Tiempo CPU : 1:19.62 s.

CPU        : 5%

RAM        : 0

 

^^^ node4 ^^^

Tiempo CPU : 1:23.50 s.

CPU        : 5%

RAM        : 0

 

^^^ node5 ^^^

Tiempo CPU : 1:23.56 s.

CPU        : 6%

RAM        : 0

 

^^^ node1 ^^^

Tiempo CPU : 1:24.42 s.

CPU        : 5%

RAM        : 0

 

^^^ node2 ^^^

Tiempo CPU : 1:25.79 s.

CPU        : 5%

RAM        : 0

 

^^^ node6 ^^^

Tiempo CPU : 1:27.90 s.

CPU        : 4%

RAM        : 0

 

^^^ node3 ^^^

 

 

=====================================================================

Ejecutando 10 Jobs con concurrencia 1

 

Tiempo CPU : 1:34.73 s.

CPU        : 4%

RAM        : 0

 

^^^ node4 ^^^

Tiempo CPU : 1:46.49 s.

CPU        : 4%

RAM        : 0

 

^^^ node3 ^^^

Tiempo CPU : 2:16.71 s.

CPU        : 4%

RAM        : 0

 

^^^ node2 ^^^

Tiempo CPU : 2:16.88 s.

CPU        : 4%

RAM        : 0

 

^^^ node2 ^^^

Tiempo CPU : 2:25.36 s.

CPU        : 3%

RAM        : 0

 

^^^ node5 ^^^

Tiempo CPU : 2:25.51 s.

CPU        : 3%

RAM        : 0

 

^^^ node5 ^^^

Tiempo CPU : 2:32.89 s.

CPU        : 3%

RAM        : 0

 

^^^ node6 ^^^

Tiempo CPU : 2:32.99 s.

CPU        : 3%

RAM        : 0

 

^^^ node1 ^^^

Tiempo CPU : 2:33.13 s.

CPU        : 3%

RAM        : 0

 

Tiempo CPU : 2:33.09 s.

CPU        : 3%

RAM        : 0

 

 

 

 

 

 

19.1.45. Listado de paquetes de software instalado

 

A continuación se incluye la lista completa del software instalado como paquete Debian. Junto con el nombre del paquete se especifica la versión del mismo, que es la última disponible en el momento de realizar la instalación del cluster.

 

Nombre                  versión

 

Adduser                 3.102

Alien                   8.64

Antlr                   2.7.6-7

apache-common           1.3.34-4.1+etch1

apache2                 2.2.3-4+etch5

apache2-mpm-prefork     2.2.3-4+etch5

apache2-utils           2.2.3-4+etch5

apache2.2-common        2.2.3-4+etch5

apt                     0.6.46.4-0.1

apt-utils               0.6.46.4-0.1

aptitude                0.4.4-4

aspell                  0.60.4-4

aspell-es               1.9-8

at                      3.1.10

attr                    2.4.32-1

autoconf                2.61-4

autoconf2.13            2.13-58

autofs                  4.1.4-13

automake1.4             1.4-p6-12

autotools-dev           20060702.1

awstats                 6.5+dfsg-1

base-files              4

base-passwd             3.5.11

bash                    3.1dfsg-8

bc                      1.06-20

bibindex                2.10-5

bibtool                 2.48alpha.2-3

biff                    0.17.pre20000412-3

bin86                   0.16.14-1.4

bind-doc                8.4.7-1

bind9                   9.3.4-2etch3

bind9-doc               9.3.4-2etch3

bind9-host              9.3.4-2etch3

binutils                2.17-3

bison                   2.3.dfsg-4

blt                     2.4z-4

blt-dev                 2.4z-4

bonnie++                1.03a+b1

bsdmainutils            6.1.6

bsdutils                2.12r-19etch1

busybox                 1.1.3-4

bwm                     1.1.0-8.1

bzip2                   1.0.3-6

c2man                   2.41-17

ca-certificates         20070303

cflow                   1.1-1

console-common          0.7.69

console-data            1.01-7

console-tools           0.2.3dbs-65

coreutils               5.97-5.3

courier-authdaemon      0.58-4

courier-authlib         0.58-4

courier-authlib-userdb  0.58-4

courier-base            0.53.3-5

cpio                    2.6-18.1+etch1

cpp                     4.1.1-15

cpp-2.95                2.95.4-27

cpp-3.3                 3.3.6-15

cpp-3.4                 3.4.6-5

cpp-4.1                 4.1.1-21

cramfsprogs             1.1-6

cron                    3.0pl1-100

csh                     20060813-1

cutils                  1.6-3

cvs                     1.12.13-8

cxref                   1.6a-1.1

dash                    0.5.3-7

db4.4-util              4.4.20-8

dc                      1.06-20

ddd                     3.3.11-1

debconf                 1.5.11etch2

debconf-i18n            1.5.11etch2

debconf-utils           1.5.11etch2

debhelper               5.0.42

debian-archive-keyring  2007.07.31~etch1

debian-reference-common 1.11

debian-reference-es     1.11

debianutils             2.17

defoma                  0.11.10-0.1

devscripts              2.9.26

dhcp-client             2.0pl5-19.5etch2

dhcp3-common            3.0.4-13

dhcp3-server            3.0.4-13

dialog                  1.0-20060221-3

dictionaries-common     0.70.10

diff                    2.8.1-11

diffstat                1.43-2

discover1               1.7.19

discover1-data          2.2007.02.02

dmidecode               2.8-4

dnsutils                9.3.4-2etch3

doc-debian              3.1.5

doc-debian-es           2.5

doc-linux-es            2003.04-2

doc-linux-text          2007.02-1

dpkg                    1.13.25

dpkg-dev                1.13.25

dselect                 1.13.25

dsh                     0.25.7-1

dvidvi                  1.0-8etch2

e2fslibs                1.39+1.40-WIP-2006.11.14+dfsg-2etch1

e2fsprogs               1.39+1.40-WIP-2006.11.14+dfsg-2etch1

ecj-bootstrap           3.2.1-3

ecj-bootstrap-gcj       3.2.1-3

ed                      0.2-20

eject                   2.1.4-3

emacs21                 21.4a+1-3etch1

emacs21-bin-common      21.4a+1-3etch1

emacs21-common          21.4a+1-3etch1

emacsen-common          1.4.17

esound-common           0.2.36-3

etherwake               1.09-1

ethtool                 5-1

exim4                   4.63-17

exim4-base              4.63-17

exim4-config            4.63-17

exim4-daemon-light      4.63-17

fastjar                 4.1.1-21

fdutils                 5.5-20060227-1.1

fftw2                   2.1.3-20

file                    4.17-5etch3

fileutils               5.97-5.3

findutils               4.2.28-1etch1

finger                  0.17-10

flex                    2.5.33-11

fontconfig              2.4.2-1.2

fontconfig-config       2.4.2-1.2

fping                   2.4b2-to-ipv6-14

ftnchek                 3.3.1-1

ftp                     0.17-16

fvwm                    2.5.18-3

g++                     4.1.1-15

g++-2.95                2.95.4-27

g++-3.3                 3.3.6-15

g++-4.1                 4.1.1-21

g77                     3.4.6-19

g77-3.4                 3.4.6-5

gadfly                  1.0.0-11

ganglia-monitor         2.5.7-3.1

gappletviewer-4.1       4.1.1-20

gawk                    3.1.5.dfsg-4

gcc                     4.1.1-15

gcc-2.95                2.95.4-27

gcc-3.3                 3.3.6-15

gcc-3.3-base            3.3.6-15

gcc-3.4                 3.4.6-5

gcc-3.4-base            3.4.6-5

gcc-4.1                 4.1.1-21

gcc-4.1-base            4.1.1-21

gcj-4.1                 4.1.1-20

gcj-4.1-base            4.1.1-20

gconf2                  2.16.1-1

gconf2-common           2.16.1-1

gdb                     6.4.90.dfsg-1

gdk-imlib1              1.9.14-31

gdk-imlib11             1.9.14-31

gettext                 0.16.1-1

gettext-base            0.16.1-1

gij-4.1                 4.1.1-20

gjdoc                   0.7.7-7

glibc-doc               2.3.6.ds1-13etch7

gmetad                  2.5.7-3.1

gnome-bin               1.4.2-34

gnome-libs-data         1.4.2-34

gnu-efi                 3.0c-1

gnupg                   1.4.6-2

gnuplot                 4.0.0-5

gnuplot-nox             4.0.0-5

gnuplot-x11             4.0.0-5

gpgv                    1.4.6-2

grep                    2.5.1.ds2-6

groff-base              1.18.1.1-12

grub                    0.97-27etch1

gs                      8.54.dfsg.1-5etch1

gs-common               0.3.11

gs-gpl                  8.54.dfsg.1-5etch1

gsfonts                 8.11+urwcyr1.0.7~pre41-1

gsfonts-x11             0.20

gsl-bin                 1.8-2

gv                      3.6.2-3

gzip                    1.3.5-15

hdparm                  6.9-2

heartbeat               1.2.5-3

hostname                2.93

html2text               1.3.2a-3

htmlgen                 2.2.2-10

hyperlatex              2.8b-3

iamerican               3.1.20.0-4.3

ibritish                3.1.20.0-4.3

icatalan                0.5-3

iceweasel               2.0.0.16-0etch1

iconx                   9.4.2-2.7

ifstat                  1.1-5.0.1

iftop                   0.17-3

ifupdown                0.6.8

imlib-base              1.9.14-31

indent                  2.2.9-7

info                    4.8.dfsg.1-4

initramfs-tools         0.85i

initrd-tools            0.1.84.2

initscripts             2.86.ds1-38+etchnhalf.1

intltool-debian         0.35.0+20060710.1

ipchains                1.3.10-15

iperf                   2.0.2-2

iproute                 20061002-3

iptables                1.3.6.0debian1-5

iputils-ping            20020927-6

iso-codes               1.0a-1

ispanish                1.9-8

ispell                  3.1.20.0-4.3

itcl3.1                 3.1.0-7.1

itcl3.1-dev             3.1.0-7.1

java-common             0.25

java-gcj-compat         1.0.65-10

java-gcj-compat-dev     1.0.65-10

jfsutils                1.1.11-1

kernel-image-2.4.27-2   2.4.27-10sarge1

klibc-utils             1.4.34-2

klogd                   1.4.1-18

lacheck                 1.26-9

language-env            0.68

laptop-detect           0.12.1

less                    394-4

lesstif1                0.93.94-11.4

lesstif2                0.94.4-2

libacl1                 2.2.41-1

libamu2                 6.0.9-3.2

libapache2-mod-php5     5.2.0-8+etch11

libapr1                 1.2.7-8.2

libaprutil1             1.2.7+dfsg-2

libapt-pkg-perl         0.1.20

libart-2.0-2            2.3.17-1

libart-2.0-dev          2.3.17-1

libart2                 1.4.2-34

libasound2              1.0.13-2

libaspell15             0.60.4-4

libatk1.0-0             1.12.4-3

libatm1                 2.4.1-17

libattr1                2.4.32-1

libaudio-dev            1.8-4

libaudio2               1.8-4

libaudiofile0           0.2.6-6

libbeecrypt6            4.1.2-6

libbind9-0              9.3.4-2etch3

libblkid1               1.39+1.40-WIP-2006.11.14+dfsg-2etch1

libbonobo2              1.0.22-2.2

libbz2-1.0              1.0.3-6

libc6                   2.3.6.ds1-13etch7

libc6-dev               2.3.6.ds1-13etch7

libcairo2               1.2.4-4.1+etch1

libcap1                 1.10-14

libcomerr2              1.39+1.40-WIP-2006.11.14+dfsg-2etch1

libconfig-inifiles-perl 2.39-2

libconsole              0.2.3dbs-65

libcsiro0               5.6.1-10

libcupsys2              1.2.7-4etch4

libcupsys2-dev          1.2.7-4etch4

libcurl3                7.15.5-1etch1

libcurl3-gnutls         7.15.5-1etch1

libdb1-compat           2.1.3-9

libdb2                  2.7.7.0-9

libdb3                  3.2.9+dfsg-0.1

libdb3-util             3.2.9+dfsg-0.1

libdb4.2                4.2.52+dfsg-2

libdb4.3                4.3.29-8

libdb4.4                4.4.20-8

libdbi-perl             1.53-1etch1

libdbus-1-3             1.0.2-1+etch1

libdbus-glib-1-2        0.71-3

libdevmapper1.01        1.01.00-4

libdevmapper1.02        1.02.08-1

libdiscover1            1.7.19

libdns16                9.2.4-1

libdns22                9.3.4-2etch3

libdrm2                 2.0.2-0.1

libdshconfig1           0.20.12-2

libedit2                2.9.cvs.20050518-2.2

libefs1                 1.0.22-2.2

libelfg0                0.8.6-3

libesd0                 0.2.36-3

libevent1               1.1a-1

libexpat1               1.95.8-3.4

libexpat1-dev           1.95.8-3.4

libfam0                 2.7.0-12

libfam0c102             2.7.0-12

libflac6                1.1.1-5

libflac7                1.1.2-8

libfontconfig1          2.4.2-1.2

libfontconfig1-dev      2.4.2-1.2

libfontenc-dev          1.0.2-2

libfontenc1             1.0.2-2

libfreetype6            2.2.1-5+etch2

libfreetype6-dev        2.2.1-5+etch2

libfribidi0             0.10.7-4

libfs6                  1.0.0-4

libg2c0                 3.4.6-5

libg2c0-dev             3.4.6-5

libgc1c2                6.8-1

libgcc1                 4.1.1-21

libgcj-bc               4.1.1-21

libgcj-common           4.1.1-21

libgcj7-0               4.1.1-20

libgcj7-awt             4.1.1-20

libgcj7-dev             4.1.1-20

libgcj7-jar             4.1.1-20

libgconf2-4             2.16.1-1

libgcrypt11             1.2.3-2

libgcrypt11-dev         1.2.3-2

libgd2-xpm              2.0.33-5.2etch1

libgdbm3                1.8.3-3

libgdk-pixbuf2          0.22.0-11

libgimpprint1           4.2.7-10

libgl1-mesa-dev         6.5.1-0.6

libgl1-mesa-dri         6.5.1-0.6

libgl1-mesa-glx         6.5.1-0.6

libglade-gnome0         0.17-8

libglade0               0.17-8

libglib1.2              1.2.10-17

libglib2.0-0            2.12.4-2

libglu1-mesa            6.5.1-0.6

libgmp3                 4.1.4-6

libgnome32              1.4.2-34

libgnomeprint-bin       0.37-12

libgnomeprint-data      0.37-12

libgnomeprint15         0.37-12

libgnomesupport0        1.4.2-34

libgnomeui32            1.4.2-34

libgnorba27             1.4.2-34

libgnorbagtk0           1.4.2-34

libgnutls-dev           1.4.4-3+etch1

libgnutls11             1.0.16-13.1

libgnutls13             1.4.4-3+etch1

libgpg-error-dev        1.4-1

libgpg-error0           1.4-1

libgpmg1                1.19.6-25

libgsl0                 1.8-2

libgsl0-dev             1.8-2

libgssapi2              0.10-4

libgtk1.2               1.2.10-18

libgtk1.2-common        1.2.10-18

libgtk2.0-0             2.8.20-7

libgtk2.0-common        2.8.20-7

libgtkxmhtml1           1.4.2-34

libhdf4g                4.1r4-18.1

libhesiod0              3.0.2-18.1

libibverbs-dev          1.0.4-1

libibverbs1             1.0.4-1

libice-dev              1.0.1-2

libice6                 1.0.1-2

libid3tag0              0.15.1b-10

libident                0.22-3

libidl0                 0.8.6-1

libidn11                0.6.5-1

libisc11                9.3.4-2etch3

libisc7                 9.2.4-1

libisccc0               9.3.4-2etch3

libisccfg1              9.3.4-2etch3

libjack0.100.0-0        0.101.1-2

libjasper-1.701-1       1.701.0-2

libjpeg62               6b-13

libjpeg62-dev           6b-13

libklibc                1.4.34-2

libkpathsea3            2.0.2-30sarge4

libkpathsea4            3.0-30

libkrb53                1.4.4-7etch6

liblcms1                1.15-1

liblcms1-dev            1.15-1

libldap-2.2-7           2.2.23-8

libldap2                2.1.30-13.3

liblocale-gettext-perl  1.05-1

liblockfile1            1.06.1

libltdl3                1.5.22-4

liblwres1               9.2.4-1

liblwres9               9.3.4-2etch3

liblzo-dev              1.08-3

liblzo1                 1.08-3

libmad0                 0.15.1b-2.1

libmagic1               4.17-5etch3

libmagick9              6.2.4.5.dfsg1-0.14

libmng-dev              1.0.9-1

libmng1                 1.0.9-1

libmodplug0c2           0.7-5.2

libmpcdec3              1.2.2-1

libmpich1.0c2           1.2.7-2

libmyspell3c2           3.1-18

libmysql-java           5.0.4+dfsg-2

libncurses5             5.5-5

libncurses5-dev         5.5-5

libncursesw5            5.5-5

libneon25               0.25.5.dfsg-6

libnet-daemon-perl      0.38-1.1

libnet1                 1.1.2.1-2

libnetpbm10             10.0-11.1+etch1

libnewt0.52             0.52.2-10

libnfsidmap2            0.18-0

libnss-db               2.2.3pre1-2

liboaf0                 0.6.10-8

libogg0                 1.1.3-2

libopencdk8             0.5.9-2

libopencdk8-dev         0.5.9-2

liborbit0               0.5.17-11.1

liborbit2               2.14.3-0.2

libpam-modules          0.79-5

libpam-runtime          0.79-5

libpam0g                0.79-5

libpango1.0-0           1.14.8-5

libpango1.0-common      1.14.8-5

libpaper1               1.1.21

libparted1.7-1          1.7.1-5.1

libpcap0.7              0.7.2-7

libpcap0.8              0.9.5-1

libpci2                 2.1.11-3

libpcre3                6.7+7.4-4

libperl5.8              5.8.8-7etch3

libpils0                1.2.5-3

libplot2c2              2.4.1-15

libplplot9              5.6.1-10

libplrpc-perl           0.2017-1.1

libpng12-0              1.2.15~beta5-1

libpng12-dev            1.2.15~beta5-1

libpng3                 1.2.15~beta5-1

libpoppler0c2           0.4.5-5.1etch3

libpopt-dev             1.10-3

libpopt0                1.10-3

libpq4                  8.1.11-0etch1

libqhull5               2003.1-2

libqt3-headers          3.3.7-4etch2

libqt3-mt               3.3.7-4etch2

libqt3c102              3.3.4-3

libreadline4            4.3-11

libreadline5            5.2-2

librpcsecgss3           0.14-2etch3

librplay3               3.3.2-11

librpm4                 4.4.1-13

librrd2                 1.2.15-0.3

librrd2-dev             1.2.15-0.3

libsamplerate0          0.1.2-2

libsasl2                2.1.22.dfsg1-8

libsasl2-2              2.1.22.dfsg1-8

libselinux1             1.32-3

libsemanage1            1.8-1

libsensors3             2.10.1-3

libsepol1               1.14-2

libsigc++-1.2-5c102     1.2.5-4

libsigc++-2.0-0c2a      2.0.17-2

libslang2               2.0.6-4

libslp1                 1.2.1-6.2

libsm-dev               1.0.1-3

libsm6                  1.0.1-3

libsndfile1             1.0.16-2

libsnmp-base            5.2.3-7etch2

libsnmp9                5.2.3-7etch2

libspeex1               1.1.12-3etch1

libsqlite3-0            3.3.8-1.1

libss2                  1.39+1.40-WIP-2006.11.14+dfsg-2etch1

libssl0.9.7             0.9.7k-3.1etch1

libssl0.9.8             0.9.8c-4etch3

libssp0                 4.1.1-21

libstdc++2.10-dev       2.95.4-27

libstdc++2.10-glibc2.2  2.95.4-27

libstdc++5              3.3.6-15

libstdc++5-3.3-dev      3.3.6-15

libstdc++6              4.1.1-21

libstdc++6-4.1-dev      4.1.1-21

libstonith0             1.2.5-3

libstroke0              0.5.1-5

libsvga1                1.4.3-24

libsysfs-dev            2.1.0-1

libsysfs2               2.1.0-1

libt1-5                 5.1.0-2etch1

libtag1c2a              1.4-4

libtagc0                1.4-4

libtasn1-0              0.1.2-5

libtasn1-2              0.2.10-3

libtasn1-3              0.3.6-2

libtasn1-3-dev          0.3.6-2

libterm-readkey-perl    2.30-3

libtext-charwidth-perl  0.04-4

libtext-iconv-perl      1.4-3

libtext-wrapi18n-perl   0.06-5

libtextwrap1            0.1-5

libtiff4                3.8.2-7+etch1

libungif4g              4.1.4-4

libusb-0.1-4            0.1.12-5

libuuid1                1.39+1.40-WIP-2006.11.14+dfsg-2etch1

libvolume-id0           0.105-4

libvorbis0a             1.1.2.dfsg-1.4

libvorbisfile3          1.1.2.dfsg-1.4

libwrap0                7.6.dbs-13

libwww0                 5.4.0-11

libx11-6                1.0.3-7

libx11-data             1.0.3-7

libx11-dev              1.0.3-7

libxau-dev              1.0.1-2

libxau6                 1.0.1-2

libxaw-headers          1.0.2-4

libxaw7                 1.0.2-4

libxaw7-dev             1.0.2-4

libxcursor-dev          1.1.7-4

libxcursor1             1.1.7-4

libxdmcp-dev            1.0.1-2

libxdmcp6               1.0.1-2

libxext-dev             1.0.1-2

libxext6                1.0.1-2

libxfixes-dev           4.0.1-5

libxfixes3              4.0.1-5

libxfont-dev            1.2.2-2.etch1

libxfont1               1.2.2-2.etch1

libxft-dev              2.1.8.2-8

libxft2                 2.1.8.2-8

libxi-dev               1.0.1-4

libxi6                  1.0.1-4

libxinerama-dev         1.0.1-4.1

libxinerama1            1.0.1-4.1

libxkbfile1             1.0.3-2

libxml1                 1.8.17-14

libxml2                 2.6.27.dfsg-4

libxmu-dev              1.0.2-2

libxmu-headers          1.0.2-2

libxmu6                 1.0.2-2

libxmuu-dev             1.0.2-2

libxmuu1                1.0.2-2

libxp-dev               1.0.0.xsf1-1

libxp6                  1.0.0.xsf1-1

libxpm-dev              3.5.5-2

libxpm4                 3.5.5-2

libxrandr-dev           1.1.0.2-5

libxrandr2              1.1.0.2-5

libxrender-dev          0.9.1-3

libxrender1             0.9.1-3

libxss1                 1.1.0-1

libxt-dev               1.0.2-2

libxt6                  1.0.2-2

libxtrap-dev            1.0.0-4

libxtrap6               1.0.0-4

libxtst-dev             1.0.1-5

libxtst6                1.0.1-5

libxv-dev               1.0.2-1

libxv1                  1.0.2-1

libxxf86dga1            1.0.1-2

libxxf86vm1             1.0.1-2

libzvt2                 1.4.2-34

linux-headers-2.6.18-5  2.6.18.dfsg.1-13etch6

linux-headers-2.6.18-5-686-bigmem               2.6.18.dfsg.1-13etch6

linux-headers-2.6.24-etchnhalf.1-686-bigmem     2.6.24-6~etchnhalf.4

linux-headers-2.6.24-etchnhalf.1-common         2.6.24-6~etchnhalf.4

linux-image-2.6.18-5-686-bigmem                 2.6.18.dfsg.1-13etch6

linux-kbuild-2.6.18     2.6.18-1

linux-kbuild-2.6.24     2.6.24-1~etchnhalf.1

linux-kernel-headers    2.6.18-7

linux-patch-debian-2.6.18                       2.6.18.dfsg.1-22etch2

linux-patch-debian-2.6.24                       2.6.24-6~etchnhalf.4

linux-source-2.6.18     2.6.18.dfsg.1-22etch2

linux-source-2.6.24     2.6.24-6~etchnhalf.4

linux-tree-2.6.24       2.6.24-6~etchnhalf.4

locales                 2.3.6.ds1-13etch7

localization-config     0.116

login                   4.0.18.1-7

logrotate               3.7.1-3

lsb-base                3.1-23.2etch1

lsof                    4.77.dfsg.1-3

ltrace                  0.4-1

lynx                    2.8.5-2sarge2.2

m4                      1.4.8-2

mailx                   8.1.2-0.20050715cvs-1

make                    3.81-2

makedev                 2.3.1-83

man-db                  2.4.3-6

manpages                2.39-1

manpages-dev            2.39-1

manpages-es             1.55-4

mawk                    1.3.3-11

mbr                     1.1.9-2

mdadm                   2.5.6-9

memstat                 0.4.0.0.1

mesa-common-dev         6.5.1-0.6

mime-support            3.39-1

mktemp                  1.5-2

moc                     2.4.1-1

modconf                 0.3.1

module-init-tools       3.3-pre4-2

modutils                2.4.27.0-6

mount                   2.12r-19etch1

mozilla-firefox         2.0.0.16-0etch1

mpack                   1.6-4

mtools                  3.9.10.ds1-3

mtr-tiny                0.71-2etch1

mutt                    1.5.13-1.1etch1

myspell-es              1.9-8

nagios-nrpe-server      2.5.1-3

nagios-plugins-basic    1.4.5-1etch1

nano                    2.0.2-1etch1

ncurses-base            5.5-5

ncurses-bin             5.5-5

ncurses-term            5.5-5

net-tools               1.60-17

netbase                 4.29

netcat                  1.10-32

netcdfg3                3.5.0-7.1

netkit-ping             20020927-6

netpbm                  10.0-11.1+etch1

nfs-common              1.0.10-6+etch.1

nfs-kernel-server       1.0.10-6+etch.1

nis                     3.17-6

nowebm                  2.11b-2

ntp                     4.2.2.p4+dfsg-2

ntpdate                 4.2.2.p4+dfsg-2

nvi                     1.79-25

oaf                     0.6.10-8

openbsd-inetd           0.20050402-6

openssh-blacklist       0.1.1

openssh-client          4.3p2-9etch2

openssh-server          4.3p2-9etch2

openssl                 0.9.8c-4etch3

parted                  1.7.1-5.1

passwd                  4.0.18.1-7

patch                   2.5.9-4

pciutils                2.2.4~pre4-1

pdl                     2.4.3-3

perl                    5.8.8-7etch3

perl-base               5.8.8-7etch3

perl-modules            5.8.8-7etch3

php5-common             5.2.0-8+etch11

php5-gd                 5.2.0-8+etch11

pidentd                 3.0.19.ds1-1

pkg-config              0.21-1

plotutils               2.4.1-15

po-debconf              1.0.8

policycoreutils         1.32-3

portmap                 5-26

procmail                3.22-16

procps                  3.2.7-3

proj                    4.4.9d-2

psmisc                  22.3-1

psutils                 1.17-24

python                  2.4.4-2

python-central          0.5.12

python-dev              2.4.4-2

python-gadfly           1.0.0-11

python-gdk-imlib-1.2    0.6.12-8

python-gendoc           0.73-11

python-glade-1.2        0.6.12-8

python-gtk-1.2          0.6.12-8

python-htmlgen          2.2.2-11

python-minimal          2.4.4-2

python-newt             0.52.2-10

python-pmw              1.2-5

python-selinux          1.32-3

python-semanage         1.8-1

python-support          0.5.6

python-tk               2.4.4-1

python2.4               2.4.4-3+etch1

python2.4-dev           2.4.4-3+etch1

python2.4-minimal       2.4.4-3+etch1

python2.4-numeric       23.8-1

python2.4-xml           0.8.4-1

qt3-designer            3.3.7-4etch2

qt3-dev-tool            3.3.7-4etch2

quilt                   0.45-6

rasmol                  2.7.2.1.1-5

rcs                     5.7-18

rdate                   1.4-8

readline-common         5.2-2

reiserfsprogs           3.6.19-4

render-dev              0.9.2-4

reportbug               3.31

rpm                     4.4.1-13

rrdtool                 1.2.15-0.3

rsh-server              0.17-13

rsync                   2.6.9-2etch2

sed                     4.1.5-1

setserial               2.17-43

sharutils               4.2.1-15

shellutils              5.97-5.3

slang1                  1.4.9dbs-8

slang1a-utf8            1.4.9dbs-8

slatec                  4.1-4

ssh                     4.3p2-9etch2

strace                  4.5.14-2

sudo                    1.6.8p12-4

svgalibg1               1.4.3-24

sysklogd                1.4.1-18

syslinux                3.31-4

sysstat                 7.0.0-4

sysv-rc                 2.86.ds1-38+etchnhalf.1

sysvinit                2.86.ds1-38+etchnhalf.1

sysvinit-utils          2.86.ds1-38+etchnhalf.1

tar                     1.16-2etch1

tasksel                 2.66

tasksel-data            2.66

tcl8.3                  8.3.5-5

tcl8.3-dev              8.3.5-5

tcl8.4                  8.4.12-1.1

tcl8.4-dev              8.4.12-1.1

tcpd                    7.6.dbs-13

tcsh                    6.14.00-7

telnet                  0.17-34

tetex-base              3.0.dfsg.3-5etch1

tetex-bin               3.0-30

tetex-doc               3.0.dfsg.3-5etch1

tex-common              1.0.1

texinfo                 4.8.dfsg.1-4

textutils               5.97-5.3

time                    1.7-21

tk8.4                   8.4.12-1etch2

tk8.4-dev               8.4.12-1etch2

tktable                 2.9-1

tktable-dev             2.9-1

tofrodos                1.7.6-2

traceroute              1.4a12-21

ttf-bitstream-vera      1.10-7

ttf-dejavu              2.15-1

tzdata                  2007k-1etch1

ucf                     2.0020

udev                    0.105-4

untex                   9210-10

unzip                   5.52-9etch1

update-inetd            4.27-0.5

usbutils                0.72-7

user-es                 0.34

util-linux              2.12r-19etch1

util-linux-locales      2.12r-19etch1

vim-common              7.0-122+1etch3

vim-tiny                7.0-122+1etch3

w3m                     0.5.1-5.1

wakeonlan               0.41-6

wamerican               6-2

wcatalan                0.5-3

wenglish                5-4

wget                    1.10.2-2

whiptail                0.52.2-10

whois                   4.7.20

wspanish                1.0.19

x-dev                   7.0.7-2

x11-common              7.1.0-19

x11proto-core-dev       7.0.7-2

x11proto-fixes-dev      4.0-2

x11proto-fonts-dev      2.0.2-5

x11proto-input-dev      1.3.2-4

x11proto-kb-dev         1.0.3-2

x11proto-print-dev      1.0.3.xsf1-1

x11proto-randr-dev      1.1.2-4

x11proto-record-dev     1.13.2-4

x11proto-render-dev     0.9.2-4

x11proto-trap-dev       3.4.3-5

x11proto-video-dev      2.2.2-4

x11proto-xext-dev       7.0.2-5

x11proto-xinerama-dev   1.1.2-4

xaw3dg                  1.5+E-14

xbase-clients           7.1.ds1-2

xbitmaps                1.0.1-2

xcursor-themes          1.0.1-5

xdm                     1.0.5-2

xfig                    3.2.5-alpha5-9

xfonts-100dpi           1.0.0-3

xfonts-75dpi            1.0.0-3

xfonts-base             1.0.0-4

xfonts-encodings        1.0.0-6

xfonts-scalable         1.0.0-6

xfonts-utils            1.0.1-1

xfsprogs                2.8.11-1

xkb-data                0.9-4

xlibmesa-gl             7.1.0-19

xlibmesa-gl-dev         7.1.0-19

xlibmesa-glu            7.1.0-19

xlibs-data              7.1.0-19

xlibs-static-dev        7.1.0-19

xmhtml1                 1.1.7-14

xpdf                    3.01-9.1+etch5

xpdf-common             3.01-9.1+etch5

xpdf-reader             3.01-9.1+etch5

xpdf-utils              3.01-9.1+etch5

xserver-xfree86         7.1.0-19

xserver-xorg            7.1.0-19

xserver-xorg-core       1.1.1-21etch5

xserver-xorg-input-all  7.1.0-19

xserver-xorg-input-evd  1.1.2-6

xserver-xorg-input-kbd  1.1.0-4

xserver-xorg-input-mou  1.1.1-3

xserver-xorg-input-syn  0.14.6-1

xserver-xorg-input-wac  0.7.4.1-5

xserver-xorg-video-all  7.1.0-19

xserver-xorg-video-apm  1.1.1-3

xserver-xorg-video-ark  0.6.0-3

xserver-xorg-video-ati  6.6.3-2

xserver-xorg-video-chi  1.1.1-4

xserver-xorg-video-cir  1.1.0-3

xserver-xorg-video-cyr  1.1.0-4

xserver-xorg-video-dum  0.2.0-3

xserver-xorg-video-fbd  0.3.1-1

xserver-xorg-video-gli  1.1.1-3

xserver-xorg-video-i12  1.2.0-3

xserver-xorg-video-i74  1.1.0-3

xserver-xorg-video-i810 1.7.2-4

xserver-xorg-video-imst 1.1.0-3

xserver-xorg-video-mga  1.4.4.dfsg.1-2

xserver-xorg-video-neo  1.1.1-5

xserver-xorg-video-newp 0.2.0-3

xserver-xorg-video-nsc  2.8.1-3

xserver-xorg-video-nv   2.0.3-1

xserver-xorg-video-rend 4.1.0.dfsg.1-4

xserver-xorg-video-s3   0.4.1-5

xserver-xorg-video-sis  0.9.1-4

xserver-xorg-video-vesa 1.3.0-1

xserver-xorg-video-vga  4.1.0-3

xserver-xorg-video-via  0.2.1-6

xterm                   222-1etch2

xtrans-dev              1.0.1-3

xutils                  7.1.ds.3-1

xutils-dev              7.1.ds-6

yorick                  2.1.01cvs20060706-1

yorick-data             2.1.01cvs20060706-1

zlib-bin                1.2.3-13

zlib1g                  1.2.3-13

zlib1g-dev              1.2.3-13

 

 

19.2. Índice de Figuras

 

4.1. El protocolo NFS en los modelos OSI y TCP/IP, 21

4.2. Ejemplo de Cluster con Lustre, 24

4.3. Ejemplo de configuración de GlusterFS con 4 nodos de almacenamiento

       y 1 nodo cliente, 25

 

5.1. Arquitectura de un cluster tipo SSI, 27

5.2. División de procesos en openMosix, 28

 

7.1. Esquema de cluster openMosix de LSI, 35

7.2. el CPD de UPC en el edificio Omega, 38

 

9.1. Esquema de hosts con replicación de datos vía connexion de red dedicada, 44

9.2. Arquitectura del cluster con Lustre (version 1.0), 45

9.3. Arquitectura revisada del cluster con Lustre (version 1.1), 52

9.4. Throughput de lectura y escritura del filesysten Lustre, 53

9.5. Throughput del filesystem Lustre en lecturas, 54

9.6. Throughput del filesystem Lustre en escrituras, 55

 

10.1. Arquitectura del cluster con GlusterFS (version 2.0), 56

10.2. Throughput de lectura y escritura del filesystem GlusterFS, 61

10.3. Throughput del filesystem GlusterFS en lecturas, 62

10.4. Throughput del filesystem GlusterFS en escrituras, 63

 

11.1. Esquema de las zonas albergadas en los nodos master-cluster, 77

11.2. Esquema de cluster con colas de ejecución y de espera, 79

11.3. Ventana de creación de colas deasde qmon, 80

11.4. Ventana de administración de grupos en qmon, 81

11.5. Ventana de control de políticas del cluster desde qmon, 82

11.6. Ventana de control de la política functional desde qmon, 83

 

13.1. Pamtalla de nodo arrancando por PXE, 90

13.2. Interfaz de administrador de Tivoli, 91

 

14.1. Daemons y flujo de datos en un sistema Ganglia, 96

14.2. Pantalla principal de la web Ganglia, 98

14.3. Gráfica de la métrica jobs_running, 100

14.4. Gráfica de las métrica jobs_queued, 101

14.5. Gráfica de la métrica temperature_max, 101

14.6. Vista Ganglia general del cluster, 103

14.7. Vista Ganglia de una cola, 104

14.8. Vista Ganglia de un nodo, 105

 

15.1. Vista de la web Nagios, 109

 

16.1. Web awstats (1), 118

16.2. Web awstats (2), 119

 

18.1. Esquema de cluster con SAN y Lustre, 134

 

19.3. Juegos de pruebas

 

A fin de evaluar los diferentes modelos de cluster propuestos, creamos un juego de pruebas que nos ayude a valorar cada propuesta. El juego de pruebas consta de las siguientes partes:

 

  • Test de estabilidad: destinados a medir la capacidad de mantener un funcionamiento adecuado en todo tipo de escenarios.

 

  • Benchmarks sintéticos de disco: que miden el rendimiento máximo del filesystem.

 

  • Test de usabilidad: más allá de benchmarks y números proporcionan la información acerca del tiempo de respuesta del filesystem a determinadas acciones de los usuarios.

 

Las pruebas se realizarán en el mismo orden que se han expuesto. Si el filesystem no tuviese el comportamiento esperado en una de ellas, el modelo sería desechado y no sería necesario realizar las pruebas siguientes.

 

19.3.1. Test de estabilidad

 

El test de estabilidad del filesystem consistirá en la ejecucición de un benchmark sintético, explicado en el punto [19.3.2.2], pero con un juego de pruebas de un tamaño muy grande[16]  que obligue al sistema a trabajar de forma ininterrumpida durante varios días.

 

El tiempo que tarde en finalizar el test no es importante. Sólo cuando el test finalice correctamente, sin ningún error en los logs, consideraremos que el sistema de ficheros es estable.

19.3.2. Benchmarks sintéticos

 

El objetivo de la batería de benchmarks sintéticos es obtener el rendimiento máximo o ideal de los distintos modelos de cluster. Las prestaciones obtenidas con este tipo de pruebas rara vez se obtienen en el uso cotidiano, y deben ser considerados como valores pico.

19.3.2.1. Throughput máximo

 

dd es un commando habitual en sistemas UNIX que transfiere datos entre dos disponisitivos. Los dispositivos pueden ser cualquier dispositivo UNIX como discos, particiones, entrada y salida estándar, etc.

 

Tras realizar la transferencia de datos especificada dd muestra la tasa de transferencia obtenida. Utilizaremos este dato como indicativo de la tasa máxima de transferencia de los filesystems de los distintos sistemas propuestos. Concretamente realizaremos las siguientes pruebas orientadas a medir el throughput máximo mediante múltiples lecturas y escrituras secuenciales concurrentes de 1,2,3,4 y 5 ficheros de 50 MBytes.

 

 

En el caso de las pruebas de escritura leeremos de memoria, concretamente del dispositivo /dev/null. El comando es el siguiente:

 

master-cluster1> dd if=/dev/zero of=/home/usuaris/ivanc/test50MB bs=1024

 

Análogamente, el comando de prueba de lectura escribirá en /dev/null:

 

master-cluster1> dd if=/home/usuaris/shm/test50MB of=/dev/null bs=1024

19.3.2.2. Test ad-hoc

 

Por último realizaremos una serie de test propios que simularán la ejecución  de multitud de procesos con uso intensivo de E/S. Para ejecutar estos procesos aprovecharemos la disponibilidad del sistema de colas Sun Grid, que se encargará de repartirlos entre los diferentes nodos del cluster.

 

Cada proceso leerá o escribirá un fichero de 5 Gbytes con el siguiente contenido:

 

·        1024 directorios

o       1024 directorios

§         1024 ficheros de 5 Mbytes

 

Concretamente nuestra batería de pruebas consistirá en la ejecución de 1, 2, 3, 6, 9, 18 y 36 instancias concurrentes del test con el fin de someter el sistema de ficheros a distintos niveles de carga de E/S.

 

Midiendo el tiempo que tarda en finalizar cada test obtendremos la tasa de lectura y escritura por proceso y el throughput agregado del sistema.

 

El funcionamiento del test es el siguiente:

 

master-cluster1> ./master_lectura.sh [número_de_jobs] [concurrencia]

 

El script master_lectura.sh (apéndices [19.1.38]) lanza tantos procesos de E/S como se especifique como parámetro numero_de_jobs. El parámetro concurrencia permite ejecutar tantos jobs como queramos en un mismo host.

 

El proceso de E/S, llamado slave.sh (apéndices [19.1.39]) es un shellscript Sun Grid que ejecuta el programa test-disco_lectura.sh (apéndices [19.1.40), que es el encargado de leer datos del path especificado.

 

Análogamente ejecutamos el test de escritura:

 

master-cluster1> ./master_escritura.sh [número_de_jobs] [concurrencia]

 

En este caso master_escritura.sh (apéndices [19.1.38]) encola tantos jobs slave2.sh (apéndices [19.1.39]) como se especifique en el parámetro número_de_jobs.

 

A su vez slave2.sh ejecuta el programa test-disco_escritura.sh (apéndices [19.1.40]), que tiene como parámetros el archivo comprimido con los datos y el path donde se dejarán.

 

Los resultados de estos tests se dejan en el directorio RESULTADOS, con nombre resultado_lectura.txt y resultado_escritura.txt. Puede encontrarse un ejemplos del  formato de estos ficheros en los apéndices [19.1.44].

19.3.3. Test de usabilidad

 

El espacio de disco distribuido que planteamos en el cluster pretende ser el lugar que albergue los datos de los usuarios. Por ello, el filesystem debe responder como si se tratase de un filesystem local, sin importar los niveles de carga del sistema.

 

De nada nos sirve un sistema de ficheros paralelo con un throughput muy alto si las latencias y los tiempos de respuesta que aprecian los usuarios al trabajar con él son altos.

 

Con el propósito de comprobar la respuesta del filesystem en tareas cotidianas de un usuario medio medimos el tiempo de respuesta en acciones de usuario típicas como:

 

·        Hacer login en el sistema.

·        Listar ficheros de un directorio.

·        Listar ficheros de un directorio con miles de ficheros.

·        Abrir fichero con un editor (vi).

·        Modificar y guardar cambios en fichero (vi).

 

19.4. Referencias bibliográficas

 

La siguiente lista contiene las referencias de la información consultada en la realización de este proyecto.

 

·        Wikipedia.org, The Free Encyclopedia

Wikimedia Foundation, Inc.

 

URL: http://wikipedia.org/.

 

Wikipedia es una enciclopedia colaborativa que contiene gran cantidad de información relacionada con la informáica.

 

·        LinuxHPC.org, Linux High performance Computing

 

URL: http://linuxhpc.org/.

 

Portal que ofrece noticas relacionadas con computación de altas prestaciones, alta disponibilidad y clusters paralelos en Linux.

 

·        Lustre wiki

Sun Microsystems, Inc.

 

URL: http://wiki.lustre.org/.

 

Wikipedia official del sistema de ficheros Lustre, con todo tipo de recursos, incluyendo enlaces a descargas, manuales, foros de discussion, etc.

 

·        Lustre File System

Sun Microsystems, Inc.

 

URL: http://www.sun.com/software/products/lustre

 

Espacio de la web de Sun Microsystems dedicado a su filesystem Lustre.

 

·        Global Parallel Filesystem

IBM, Inc.

 

URL: http://www-03.ibm.com/systems/cluster/gpfs/.

 

Espacio de la web de IBM dedicado a su filesystem GPFS.

 

·        GlusterFS – Non stop cluster storage

 

URL: http://gluster.org/.

 

Web official del proyecto GlusterFS, con todo tipo de recursos.

 

·        Samba.org

 

URL: http://samba.org/.

 

Web official del proyecto Samba.

 

·        Debian.org

Software in the Public Interest, Inc.

 

URL: http://www.debian.org/.

 

Sitio web oficial de la distribución de Linux Debian.

 

·        High Availability Linux Project

 

URL: http://www.linux-ha.org/.

 

Web dedicada a proyectos relacionados con la alta disponibilidad en entornos Linux, como heartbeat.

 

·        DRBD

Linbit HA-Solutions

 

URL: http://www.drbd.org/.

 

Web official del proyecto DRBD.

 

·        Sun Grid Engine

Sun Microsystems, Inc.

 

URL: http://sun.com/software/gridware/.

 

Espacio de la web de Sun microsystems dedicado a su sistema de colas Sun Grid.

 

·        PBS GridWorks

Altair Corporate

 

URL: http://pbsgridworks.com

 

Web official del sistemas de colas openPBS.

 

·        Condor project homepage

 

URL: http://www.cs.wisc.edu/condor/.

 

Página del proyecto Condor, con manuales de instalación y administración.

 

·        Using Samba

Richard Sharpe, Tim Potter, Jim Morris. Ed. McMillian, 2000.

 

Libro de referencia sobre el protocolo Samba.

 

·        Managing NFS and NIS

Hal Stern, Mike Eisler & Ricardo Labiaga. Ed. O’ Reilly, 2001.

 

Manual de administración de los servicios NFS y NIS.

 

·        SANs and NAS

W. Curtis Preston. Ed. O’ Reilly, 2002.

 

Manual para administradores de sistemas de almacenamiento.

 

·        IBM Tivoli software

IBM, Inc.

 

URL: http://www.ibm.com/software/tiovli/.

 

Espacio de la web de IBM dedicado a su software Tivoli.

 

·        Nagios.org

Nagios Enterprises

 

URL: http://ww.nagios.org/.

 

Web official del proyecto de monitorización de clusters Nagios.

 

·        The DHCP Handbook

Ralph Droms, Ted Lemon. Ed. MacMillan Publishing Company, 1999.

 

Libro de referencia de DHCP. Contiene información sobre todas sus características, configuraciones, opciones, etc.

 

·        Exim.org

 

URL: http://www.exim.org/.

 

Página web official del proyecto MTA exim.

 

·        NTP: The Network Time Protocol

ntp.org

 

URL: http://www.ntp.org/.

 

Página web official del proyecto NTP con manuales y acceso a mailing list.

 

·        Google Groups

Google, Inc.

 

URL: http://groups.google.com

 

Servicio de grupos de discusión de todo tipo, incluidos temas informáticos.

 

·        Dell.com

Dell, Inc.

 

URL: http://www.dell.com/.

 

Fabricante de hardware.



[1] HPC: High performance Computing. Ver apartado [3.3].

2 Según lista TOP500 (http://top500.org) con los 500 mayores superordenadores del mundo en Abril de 2007.

[3] Plantearemos tres modelos de cluster: version 1.0, version 1.1 y version 2.0.

[4] Configuración de dos o más discos con datos replicados con el fin de aportar mayor seguridad.

 

[5] Utilizamos el kernel por defecto de Debian Etch.

[6] Un brick es, en terminología de GlusterFS, la zona de disco de un nodo servidor.

[7] Versión 1.3.9 en el momentos de realizar el proyecto.

[8] RAID0 o strip realiza lecturas y escrituras en paralelo en varios discos para obtener un mayor rendimiento.

[9] El uso de diferentes translators y sus valores obedece a datos empíricos obtenidos durante la fase de pruebas.

[10] Este espacio es más que suficiente para un filesystem con millones de ficheros.

[11]  Versión 6.1 en el momento de realizar este proyecto.

9 Los ficheros ha.cf  y haresources de los nodos master-cluster se encuentran en los apéndices [19.1.5] y [19.1.6].

[12] Versión 2.2.

[13] Usamos la versión 3 (DHCP3)

[14] Instalamos Exim versión 4

* Las pruebas de estabilidad se realizaron durante el fin de semana.

[15] En el momento de instalar el cluster. Existe la posibilidad de comprar más racks.

[16] Concretamente 136 GBytes comprimidos en un fichero tar.bz formado por ficheros de 52 GBytes.