En posts anteriores hemos utilizado imágenes docker de jenkins que descargamos de dockerhub. En este post les muestro como podemos, en caso que sea necesario, crear nuestras propias imágenes que satisfagan necesidades especificas de nuestros ambientes.
Como hemos visto hay dos tipos de instancias de docker según su configuración.
- Master
- Slave
Cada una tiene diferentes requerimientos y por ello tendríamos que crear imágenes distintas para cada uno.
Constuyendo Un Jenkins Slave
Comencemos con una imagen slave, porque es a menudo la mas personalizada. La ejecución de la compilación es llevada a cabo en este agente, entonces necesitamos que el ambiente este ajustado acorde al proyecto que nos gustaría compilar. Por ejemplo, podría requerir que el interprete de python estuviera presente en un proyecto escrito en python. Lo mismo aplica para cada librería, herramienta o framework de pruebas que se necesite para el proyecto.
Hay tres pasos necesarios para construir una imagen de docker:
- Crear un Dockerfile
- Construir la imagen
- Cambiar la configuración del agent en el master
Como ejemplo, vamos a crear un slave para un proyecto python. Por lo tanto podríamos construir nuestra imagen a partir de la imagen base publicisworldwide/jenkins-slave que usamos en posts anteriores:
El Dockerfile entonces se vería algo así:
FROM publicisworldwide/jenkins-slave RUN apt-get update && \ apt-get install -y python
luego en el mismo directorio donde tenemos ese dockerfile ejecutamos el siguiente comando:
$ docker build -t jenkins-slave-python .
Y el paso final es configurar el master para que use nuestra nueva imagen jenkins-slae-python en lugar de la que ya tenia configurada.
¿Que pasaría si necesitamos que Jenkins compile dos diferentes tipos de proyectos, por ejemplo, uno basado en Python y el otro basado en Ruby? En ese caso, podríamos preparar un agente, el cual es genérico para soportar a ambos. Aunque lo mas recomendable es crear una segunda imagen de docker con las especificaciones recomendadas para cada proyecto. Y luego tendríamos que crear dos diferentes slaves y etiquetarlos de esa forma.
Construyendo un Jenkins master
Como ya tenemos una imagen slave. Podríamos usar esa misma imagen para construir un master. Quizas no querramos usar slaves porque el proyecto es muy pequeño aun, y como la ejecución se realizara en master, su ambiente tiene que ser ajustado a las necesidades del proyecto.
Imaginemos el siguiente escenario: Nuestra organización escala Jenkins horizontalmente y cada equipo tiene su propia instancia. Entonces, alguna configuración en común existe. Como por ejemplo: Plug-Ins, estrategias de copias de respaldo, o el logo de la compañía. Entonces, repetir la misma configuración para cada equipo sería una perdida de tiempo. Entonces preparamos una imagen master que los equipos puedan usar.
Jenkins esta configurado usando archivos XML y proveen un DSL basado en Groovy para manipularlos. Entonces podemos agregar un script Groovy en nuestro Dockerfile para manipular la configuracion de Jenkins. Ademas, existen scripts especiales que nos ayudan con la configuración de Jenkins en caso de que requiera algo mas que cambios en el XML, como por ejemplo, instalar un plug-in.
Como ejemplo, vamos a crear una imagen master que tenga el plug-in de docker instalado y un numero de ejecutores configurado a 5. Entonces necesitamos:
- Crear un script Groovy para manipular el config.xml y poner el numero de ejecutores a 5
- Crear un Dockerfile que instale el plugin docker y ejecute el script de Groovy
- Construir la imagen
El script de groovy es lo de lo mas sencillo, basta con 2 lineas y le ponemos de nombre al archivo executors.groovy:
import jenkins.model.* Jenkins.instance.setNumExecutors(5)
lo guardamos en el mismo directorio que el Docker file, el cual contiene lo siguiente:
FROM jenkins COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/executors.groovy RUN /usr/local/bin/install-plugins.sh docker-plugin
Y finalmente corremos el comando para construir la imagen:
$ docker build -t jenkins-master .
Después de que cada imagen es creada, cada equipo dentro de la organización puede usarla para lanzar su propia instancia de jenkins.
Conclusión
Tener nuestras propias imágenes de jenkins nos permite proveer de configuraciones personalizadas y predeterminados a los equipos dentro de la organización.