Tabla de contenido
INTROCUCCIÓN
1.2. Justificación del proyecto
1.4. Organización del documento
1.5. La doble utilidad del documento
1.6. Convenciones y tipografía
2.3. Requerimientos del proyecto
PRIMERA PARTE: SISTEMAS DE CLUSTERING
4.2. Sistemas de ficheros distribuidos
4.2.1.
Network File System (NFS)
4.3. Sistemas de ficheros paralelos
6.1. Funcionamiento de un sistema HA
6.2. Soluciones de HA en entornos Linux
SEGUNDA PARTE: DISEÑO E IMPLEMENTACIÓN
7. Estudio, análisis y diseño de una solución
7.1. Análisis del sistema inicial
7.2. Revisión de objetivos y requisitos
7.2.2.
Requisitos no funcionales
7.3.7.
Sistema de Monitorización
9.1. Arquitectura propuesta (versión 1.0)
9.2. Instalación (versión 1.0)
9.3. Configuración (versión 1.0)
9.3.1.
Consideraciones previas
9.5. Revisión de la arquitectura (versión 1.1)
9.6. Pruebas del nuevo modelo (versión 1.1)
10.1. Arquitectura propuesta (versión 2.0)
10.2. Instalación (versión 2.0)
10.3. Configuración (versión 2.0)
10.4.2.
Pruebas de rendimiento
11.1.1.
Instalación del Master host
11.1.2.
Instalación de un Execution host
11.2.1.
Zona Spool de mater hosts
12.2.1.
Cluster con GlusterFS (versión 2.0)
13.4. Personalización de imágenes
14.3.1.
Trabajos en ejecución:
15.2.1. Configuración
en cliente
15.2.2.
Configuración en servidor
16.1.2.
Configuración del servidor
16.1.3.
Configuración de los clientes
TERCERA PARTE: CONCLUSIONES
18.1. Objetivos y requisitos cumplidos
18.2. Planificación y estudios de costes
18.2.1.
Planificación temporal
18.3. Mejoras y ampliaciones del sistema
18.3.1.
Infraestructura de red
18.3.3.
Sistema de almacenamiento
18.3.5.
Checkpointing (transparente) de procesos
APÉNDICES
19.1. Ficheros de configuración y scripts
19.1.3. Fichero glusterfs-server.vol
19.1.4. Fichero glusterfs-client.vol
19.1.5. Fichero ha.cf de master-cluster1
19.1.6.
Fichero ha.cf de master-cluster2
19.1.8. Script sungrid de heartbeat
19.1.9.
Fichero drbd.conf de zona spool
19.1.10. Fichero glusterfs-server_sge-common.vol
19.1.11. Fichero glusterfs-client-sge.vol
19.1.12. Fichero bootnode-gluster.shtml
19.1.17. Script jobs_run-slave.sh
19.1.18. Script jobs_queued.sh
19.1.20.
Fichero cluster_extra.tpl
19.1.21. Fichero meta_view.tpl
19.1.25. Fichero update.exim4.conf en master-cluster1
19.1.26.
Fichero update.exim4.conf en nodos de computación y servidores de disco
19.1.27. Fichero ntp.conf en nodos master-cluster
19.1.28.
Fichero ntp.conf en nodos de computación y servidores de disco
19.1.32. Script wakeup-cluster.sh
19.1.33. Script halt-cluster.sh
19.1.35.
Script alta_usuario.sh
19.1.36. Script build_users.sh
19.1.37. Script build_homes.sh
19.1.38. Script master_lectura.sh
19.1.40. Script test-disco_lectura.sh
19.1.41. Script
master_escritura.sh
19.1.43. Script test-disco_escritura.sh
19.1.44.
Fichero resultado_lectura.sh
19.1.45.
Listado de paquetes de software instalado
19.4. Referencias bibliográficas
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.
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
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á.
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:
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.
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
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
Figura 4.2: Ejemplo de cluster Lustre
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.
Figura 4.3: Ejemplo de configuración de GlusterFS con 4 nodos de almacenamiento y 1 nodo cliente
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.
openMosix
tiene su origen en Mosix, un sistema
de clustering SSI (Single System Image), cuyo desarrollo comenzó en 1981 en
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:
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.
Condor es un
software que crea un entorno de computación HTC formado por estaciones de
trabajo UNIX conectadas en red. Fue creado por
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.
PBS (Portable Batch System) es un sistema de
trabajos batch y un sistema de
gestión de recursos. Fue desarrollado por
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.
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.
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.
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.
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.
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.
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
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.
Recordemos
que este proyecto tiene dos objetivos:
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.
Veamos
qué servicios debe prestar 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.
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.
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:
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 [
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Lustre está dividido en tres partes:
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
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/
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-
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
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.
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,
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.
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.
Una vez nuestro filesystem paralelo es funcional, procedemos a realizar las pruebas pertinentes, tal y como está descritas en el apartado [19.3].
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.
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)
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.
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].
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.
|
|
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.
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 |
|
206.4 |
103.2 |
3 |
|
303.9 |
101.3 |
6 |
|
300.0 |
50.0 |
9 |
|
292.5 |
32.5 |
18 |
|
264.3 |
14.6 |
36 |
|
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.
|
|
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 |
|
19.0 |
19.0 |
2 |
|
37.3 |
18.6 |
3 |
|
54.7 |
18.2 |
6 |
|
52.3 |
8.71 |
9 |
|
51.5 |
5.72 |
18 |
|
49.7 |
2.76 |
36 |
|
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.
|
|
Figura
9.6: Throughput del filesystem Lustre en escrituras
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].
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.
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.
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
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.
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
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.
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].
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.
|
|
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.
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 |
|
199.8 |
99.9 |
3 |
|
285.2 |
95.0 |
6 |
|
267.4 |
44.5 |
9 |
|
243.3 |
27.0 |
18 |
|
219.0 |
12.16 |
36 |
|
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.
|
|
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 |
|
33.1 |
33.1 |
2 |
|
58.0 |
29.0 |
3 |
|
76.7 |
25.5 |
6 |
|
70.2 |
11.7 |
9 |
|
66.5 |
7.3 |
18 |
|
60.1 |
3.3 |
36 |
|
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.
|
|
Figura 10.4: Throughput del filesystem GlusterFS en escrituras
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.
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.
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
If you want to setup a shadow master host, you need to
use
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 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
Scheduler Tuning
The details on the different options are described in
the manual.
Configurations
1)
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 >
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>>>
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.
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.
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,
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
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 [
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 [
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].
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.
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
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
Utilizaremos Heartbeat para proporcionar alta disponibilidad a los principales servicios del cluster, que son Sun Grid y el sistema de ficheros paralelo.
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.
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.
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.
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.
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
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-
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
of
IBM Corporation in the
**
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
of
IBM Corporation in the
.
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";
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
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.
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].
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).
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-
CopyFile("disk://0:1:/boot/initrd.img-
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 [
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 [
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.
disc2
SI S disc1 storage 239.
disc3 SI
P disc4 storage 239.
disc4
SI S disc3 storage 239.
disc5
SI P disc6 storage 239.
disc6
SI S disc5 storage 239.
node200 NO - - tenada 239.
node102 NO - - eixam 239.
node301 NO - - nozomi 239.
node303 NO - - nozomi 239.
node104 NO - - eixam 239.
node105 NO - - eixam 239.
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 [
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:
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:
· 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.
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
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.
eixam 239.
nozomi 239.
tenada 239.
storage 239.
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 [
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.
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 [
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.
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 [
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.
El resultado es el que se
muestra en la figura [ 14.3].
Figura
14.3:Gráfica de la métrica jobs_running
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 [
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
Figura
14.4: Gráfica de la métrica jobs_queued
La temperatura
de
Creamos una
nueva métrica con el valor de la temperatura de
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 [
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.
Como resultado tendremos una nueva métrica llamada temperature_max dentro de la web ganglia disponible para cada nodo del cluster.
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 [
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 [
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.
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.
Figura 14.8: Vista de un nodo
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.
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
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.
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 [
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.
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
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.
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.
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
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 [
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
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
Exim es un MTA (Mail Transfer Agent) desarrollado
por
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.
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.
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 [
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.
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.
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 [
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 [
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.
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.
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
drwxr-xr-x 3
root root 4096
lrwxrwxrwx 1
root root 16
-rw-r--r-- 1
root root 153
-rw-r--r-- 1
root root 32
-rw-r--r-- 1
root root 104
-rw-r--r-- 1
root root 36
-rw-r--r-- 1
root root 64
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.
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.
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
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 [
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
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.
Instalamos el paquete de software awstats en las dos máquinas master-cluster:
master-cluster1>
apt-get install awstats
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 [
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.
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 [
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 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 [
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.
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 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.
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.
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
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 [
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
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.
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 [
Una vez el alta ha sido realizada sólo queda enviar mail informando al usuario y a su profesor responsable.
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
Para estos dos objetivos nos habíamos fijado una serie de requisitos. Veamos cómo los hemos cumplido.
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.
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.
La realización
de este proyecto ha tenido un coste temporal y económico. A continuación
haremos el desglose de estos costes.
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
·
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 |
220
horas |
230
horas |
+10
horas |
La desviación total sobre el tiempo estimado inicialmente ha
sido de 130 horas.
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,
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 €.
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.
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.
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
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
Por ello aparcamos la idea de utilizar link aggregation hasta que dispongamos de máquinas servidoras de disco con CPUs más potentes.
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).
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 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
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.
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.
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.
default 0
timeout 5
title Lustre-kernel, kernel
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
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;
}
}
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
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
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
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
master-cluster1
Filesystem.drbd::/dev/drbd1::/mnt/sge/default/spool::ext3 sungrid MailTo::cluster@lsi.upc.edu
#!/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
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;
}
}
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
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
<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-
</script>
#!/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
# $Id: gmond.conf,v 1.3
# 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
# 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.
mcast_channel 239.
#
# 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
# This is an
example of a Ganglia Meta Daemon configuration file
# http://ganglia.sourceforge.net/
#
# $Id:
gmetad.conf,v
#
#--------------------------------------------------------------------
# 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"
#!/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/
#!/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
#!/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
#!/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
<!-- A place
to put custom HTML for the cluster view. -->
<BR>
<A
HREF="./graph2.php?g=sge_jobs_run&z=large&{graph_args}">
<IMG
BORDER=0 ALT="{cluster} JOBS RUNNING"
SRC="./graph2.php?g=sge_jobs_run&z=small&{graph_args}">
</A>
<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> </td></tr>
<tr><td> </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> </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 -->
<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> </td></tr>
<tr><td> </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> </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 -->
<?php
/* $Id:
graph.php 970
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,
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);
}
}
?>
#!/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
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
fixed-address 192.168.2.108;
}
host node313 {
hardware ethernet
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
fixed-address 192.168.1.107;
}
host node118 {
hardware ethernet
fixed-address 192.168.1.118;
}
host node117 {
hardware ethernet
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
fixed-address 192.168.1.114;
}
host node113 {
hardware ethernet
fixed-address 192.168.1.113;
}
host node112 {
hardware ethernet
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
fixed-address 192.168.2.106;
}
host node205 {
hardware ethernet
fixed-address 192.168.2.105;
}
host node204 {
hardware ethernet
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
fixed-address 192.168.0.106;
}
host disc5 {
hardware ethernet
fixed-address 192.168.0.105;
}
host disc4 {
hardware ethernet
fixed-address 192.168.0.104;
}
host disc3 {
hardware ethernet
fixed-address 192.168.0.103;
}
host disc2 {
hardware ethernet
fixed-address 192.168.0.102;
}
host disc1 {
hardware ethernet
fixed-address 192.168.0.101;
}
}
}
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'
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'
#
/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
#
/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
/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)
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"
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>
#!/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.
#
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
#
# 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.
#
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
#!/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.
MCAST_CHANNEL_NOZOMI=239.
MCAST_CHANNEL_TENADA=239.
MCAST_CHANNEL_STORAGE=239.
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/
#!/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
#!/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
#!/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
#!/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
#!/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
#!/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
#!/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
#!/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
#!/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
=====================================================================
Ejecutando 1
Jobs con concurrencia 1
Tiempo CPU :
CPU : 9%
RAM : 0
^^^ node4 ^^^
=====================================================================
Ejecutando 6
Jobs con concurrencia 1
Tiempo CPU :
CPU : 5%
RAM : 0
^^^ node4 ^^^
Tiempo CPU :
CPU : 5%
RAM : 0
^^^ node5 ^^^
Tiempo CPU :
CPU : 6%
RAM : 0
^^^ node1 ^^^
Tiempo CPU :
CPU : 5%
RAM : 0
^^^ node2 ^^^
Tiempo CPU :
CPU : 5%
RAM : 0
^^^ node6 ^^^
Tiempo CPU :
CPU : 4%
RAM : 0
^^^ node3 ^^^
=====================================================================
Ejecutando 10
Jobs con concurrencia 1
Tiempo CPU :
CPU : 4%
RAM : 0
^^^ node4 ^^^
Tiempo CPU :
CPU : 4%
RAM : 0
^^^ node3 ^^^
Tiempo CPU :
CPU : 4%
RAM : 0
^^^ node2 ^^^
Tiempo CPU :
CPU : 4%
RAM : 0
^^^ node2 ^^^
Tiempo CPU :
CPU : 3%
RAM : 0
^^^ node5 ^^^
Tiempo CPU :
CPU : 3%
RAM : 0
^^^ node5 ^^^
Tiempo CPU :
CPU : 3%
RAM : 0
^^^ node6 ^^^
Tiempo CPU :
CPU : 3%
RAM : 0
^^^ node1 ^^^
Tiempo CPU :
CPU : 3%
RAM : 0
Tiempo CPU :
CPU : 3%
RAM : 0
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
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
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
debian-reference-common
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
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
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:
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.
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.
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.
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
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].
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).
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
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.
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.