En posts anteriores hemos venido examinando como hacer una configuración básica de un servidor de integración continua. Estas instalaciones y configuraciones funcionarían un equipo de desarrollo relativamente pequeño, pero el desempeño se puede ver rápidamente disminuido a medida que agregamos cosas a la cola, aun cuando son microservicios muy pequeños que se compilan.
Por esa razón, a menos que el proyecto sea muy pequeño, Jenkins no debería ejecutar compilaciones el mismo, y en lugar de eso delegar el trabajo a sus “agentes” (slaves). Para ser mas preciso, el Jenkins que hasta ahora hemos instalado y configurado podría llamarse “master” y este puede delegar el trabajo pesado a sus “slaves” (no tiene nada que ver con la vida real...)
Para entenderlo mejor, veamos un diagrama que ilustra la interacción entre masters y slaves
En un ambiente distribuido, los master Jenkins son responsables de:
- Recibir los disparadores de compilación (ejemplo: un commit de GitHub)
- Enviar notificaciones con el resultado de la compilación (HipChat, email etc…)
- Manejo de interacciones HTTP con los usuarios
- Orquestar la ejecución de las compilaciones en los slaves
El agente es una maquina que se encarga de todo lo que pasa después de que la compilación ha comenzado.
Como las responsabilidades de estos actores en la escena de la integración continua son muy diferentes cada uno tiene, por lógica, requerimientos físicos diferentes. Estos son las recomendaciones oficiales:
- master Es una máquina que, a menos que sea un proyecto muy pequeño tendría que tener unos 200MB de RAM y si es un proyecto grande hasta 70GB.
- slave No hay un requerimiento de memoria especifico para un slave, pero debería ser de al menos 2GB mas que el requerimiento de memoria para el proyecto en cuestión, multiplicado el numero de ejecutores que manejara. Es decir, fácil unos 100GB de RAM.
Los agentes también deberían ser lo mas genéricos posibles. Por ejemplo, si tenemos diferentes proyectos: uno en java, uno en python, y uno en ruby, entonces seria perfecto si cada agente pudiera compilar o construir cualquiera de estos proyectos. En este caso, los agentes podrían ser intercambiados, lo cual ayuda a optimizar el uso de los agentes.
Si los agentes no pueden ser lo suficientemente genéricos para todos los proyectos, entonces es posible etiquetar a los agentes y a los proyectos, para que una compilación dada pueda ser ejecutada en un tipo de agente especifico.
Escalabilidad
Resulta que podemos usar slaves de Jenkins para balancear la carga y escalar nuestra infraestructura. Este proceso es llamado “Escalabilidad Horizontal”. Pero también existe otra posibilidad que implica solo usar un master y simplemente incrementar la cantidad de recursos para la máquina, este proceso es llamado “Escalabilidad Vertical”.
Escalabilidad Vertical
La escalabilidad vertical significa que cuando la carga de los master crece, entonces mas recursos son aplicados a la maquina en donde corre. Entonces, cuando nuevos proyectos aparecen en la organización, compramos mas RAM, agregamos mas núcleos de CPU y extendemos los discos duros. Esto podría sonar como una solución muy pobre, sin embargo, es usada muy a menudo, aun por organizaciones muy conocidas. Tener un solo master instalado en una maquina con hardware ultra-eficiente tiene una ventaja muy grande: mantenimiento. Cualquier actualización, scripts, ajustes de seguridad, asignación de roles, o instalaciones de plugins, tienen que ser hechos en un solo lugar.
Escalabilidad Horizontal
A diferencia de la anterior, en la escalabilidad horizontal cuando la organización crece, entonces mas instancias de master son creadas. Esto requiere que se reserven instancias de forma inteligente para cada equipo, y en el caso extremo, cada equipo puede tener su propio master. En ese caso, podría incluso pasar que no se agregan slaves.
Las complicaciones que se presentan al escalar de este modo es que se vuelve muy difícil automatizar integraciones de proyectos de diferentes equipos, y que dichos equipos tienen que gastar mas tiempo en el mantenimiento de Jenkins. Sin embargo la escalabilidad horizontal tiene varias ventajas significativas:
- Cada equipo puede tener sus propias configuraciones en el master
- Los equipos usualmente se sienten mejor, y trabajar mas eficientemente si el jenkins les pertenece
- Si la instancia master se rompe, no afecta a toda la organización
- La infraestructura puede quedar segregada y ser estándar y de misión critical
- Algunos otras configuraciones propias del equipo pueden ser simplificadas.
Pruebas y producción
Aparte de las ideas de escalabilidad que he expuesto, hay una cosa mas que cubrir cuando trabajamos con jenkins: ¿Como probamos los cambios en la infraestructura?. Siendo Jenkins tan critico para toda la organización, pues garantiza la calidad del software, y en caso de un proceso de entrega continua incluso instalaciones en servidores de producción, necesita estar altamente disponible, entonces como cualquier otra cosa no es correcto “probar en producción”. Por lo tanto es necesario nos vemos en la necesidad de tener instancias de pruebas que sean idénticas a las de producción para hacer pruebas de las actualizaciones y mejoras en la infraestructura.