Reduce los costos de CI/CD con una arquitectura maestro-esclavo en Jenkins e instancias spot de AWS

Claudia Márquez
Caleidos
Published in
7 min readFeb 17, 2021

Jenkins es un software para integración continua, siendo una de las principales herramientas dentro de los stack de DevOps utilizadas en las organizaciones a nivel mundial. Una de las características principales de Jenkins es su escalabilidad, con la posibilidad de manejar una topología maestro-esclavo, en la que podemos ejecutar los stages de nuestros jobs en distintos agentes, lo que permite mantener un Jenkins “maestro” funcionando con recursos mínimos.

Esto evita trabajar con un solo servidor para Jenkins, ya que puede sobrecargarse en momentos en los que hay muchas ejecuciones o sub-utilizarse cuando no se estén haciendo cambios en las aplicaciones (por ejemplo, en las madrugadas). ¿Pero qué pasa si se tiene varios agentes esclavo? ¿Cómo mantenemos eficiente la infraestructura sin caer en un escenario donde nos llenemos de instancias de computo?

AWS ofrece las instancias spot de Amazon EC2, que son instancias con las que podemos ahorrar hasta un 90% de costos comparado con instancias a demanda y que son un candidato perfecto para ser utilizadas como agentes de Jenkins. Estas instancias son creadas solo cuando se necesita ejecutar un job y destruidas de manera automática cuando ya no son requeridas, lo que permite un uso eficiente de los recurso de cómputo. En un Jenkins en el que necesitamos un total de 4 horas durante el dia para ejecutar nuestros jobs, utilizando una instancia spot t3.medium gastamos $2.76 mensualmente, un ahorro significativo comparándolo con el uso a demanda de una instancia esclavo t3.small que esté encendida las 24 horas que costaría $30.37 dólares mensuales.

En este tutorial vamos a aprender cómo crear una arquitectura maestro-esclavo utilizando un Spot Fleet Request de instancias spot de Amazon EC2 para cargas de trabajo de Windows. Si tu empresa necesita ayuda con Jenkins o en la implementación de otras prácticas DevOps, puedes pedir más información en el siguiente enlace.

Arquitectura

Arquitectura Maestro — Esclavo

Tenemos una instancia EC2 con Jenkins instalado. Esta tiene un rol para poder listar y realizar acciones con el Spot Fleet Request. El Spot fleet request cambiará de tamaño automáticamente con la ejecución de los jobs, pudiendo estar en 0 instancias cuando no hay ninguna ejecución.

Para poder implementar la arquitectura, crearemos una AMI que utilizaremos como base en el Spot Fleet Request.

Creación de Ami Base

Para crear un Spot Fleet, necesitamos crear una AMI que tenga el software requerido para funcionar como agentes de Jenkins.

  1. Creamos una instancia EC2 basada en Windows 2019 with containers, para poder utilizar docker dentro de nuestros pipelines de despliegue. En los grupos de seguridad abrimos los puertos 3389 (RDP) y 22 (SSH) para poder hacer la conexión con la instancia.

Creación de usuario

Necesitamos crear un usuario administrador que Jenkins utilizará para conectarse con los agentes.

2. Con la instancia lanzada, nos conectamos por RDP para realizar la instalación del software base. Lanzamos una nueva ventana de Ejecución y escribimos lusrmgr.msc para abrir el manejo de usuarios y grupos (Local Users and Groups).

3. Hacemos clic sobre Users y hacemos clic derecho y seleccionamos la opción New User.

4. Escribimos el nombre de usuario jenkins y una contraseña segura. Desmarcamos la opción User must change password at next logon y seleccionamos las opciones Password never expires y la opción User cannot change password.

5. Con el usuario creado hacemos clic derecho sobre el usuario creado y accedemos a la opción Properties. En la ventana de propiedades seleccionamos la pestaña Member of y hacemos clic en el botón Add y agregamos el grupo Administrators.

Instalación de OpenSSH

Necesitamos instalar OpenSSH para permitir la conexión entre el maestro y los agentes por SSH.

  1. Ejecutamos una ventana de Powershell como administrador y ejecutamos los siguientes comandos:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType ‘Automatic’

2. Podemos validar la instalación con el siguiente comando:

Get-WindowsCapability -Online | ? Name -like ‘OpenSSH*’

Instalación de software

Los agentes de Jenkins necesitan tener Git y Java para funcionar correctamente. Vamos a instalarlo con Chocolatey.

  1. Ejecutamos una ventana de Powershell como administrador y ejecutamos el siguiente comando para instalar Chocolatey
[Net.ServicePointManager]::SecurityProtocol = “tls12, tls11, tls”Set-ExecutionPolicy RemoteSigned -Confirm:$falseiwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex

2. Instalamos Java y Git con los siguientes comandos:

choco install javaruntime -ychoco install git.install -y

Creación de AMI

  1. En la consola de AWS, seleccionamos la instancia creada y vamos al Menú Actions > Image > Create Image para generar una imagen en base a la instancia.

Generación de Spot Fleet Request

Una vez creada la AMI, vamos a proceder a crear un Spot Fleet Request. Hemos preparado una plantilla Cloudformation para lanzar todos los elementos de la arquitectura requerida.

Lanzar el Stack

En los parámetros, debemos ingresar la imagen de la AMI creada en el paso anterior. Asi como la vpc y el grupo de seguridad del Jenkins maestro. Podemos personalizar el tamaño de la instancia e indicar la llave que se utilizará en caso se requiera ingresar a los agentes.

Configuración de Jenkins

Realizaremos la configuración en Jenkins para poder utilizar el Spot Fleet creados, para esto se debe tener instalado el plugin EC2 Fleet Jenkins Plugin.

  1. Ingresar a la configuración de Jenkins (/configure) y en la parte inferior en la sección Nube, seleccionar la opción Añadir una nueba nube > EC2 Fleet.
  2. Ingresar un valor en el campo Name, seleccionar la region en la que se creó el Spot Fleet Request y seleccionar el Spot Fleet Request creado en la sección anterior.

3. En el Launcher, crear las credenciales con el usuario y contraseña de la AMI de Windows creada.

4. En la opción Host Key Verification Strategy, seleccionar la opción Non verifying Verification Strategy.

5. Seleccionar la opción Avanzado, en el campo Prefix Start Agent Command el valor:

powershell -Command “cd C:\Users\jenkins ; java -jar remoting.jar” ; exit 0 ; # ‘

6. En el campo Suffix Start Agent Command el valor:

7. Seleccionar la casilla Connect using private IP

8. Escribir un label para ser utilizado dentro de los Jenkinsfile de los proyectos

9. Escribir C:\Users\jenkins en el campo Jenkins Filesystem Root

10. En Minimum Cluster Size ingresar 0

Validación de uso de agentes

Con la configuración de la nube creada, ya podemos utilizar el Spot Fleet Request para ejecutar los pasos de nuestros pipelines.

Vamos a crear un pipeline base para validar el funcionamiento.

  1. Creamos un nuevo Job de tipo Pipeline.

2. Dentro del Job en la sección Pipeline, seleccionamos Pipeline script e insertamos el siguiente script.

pipeline {  // En esta línea estamos especificando la etiqueta configurada para el Spot Fleet Request configurada en el paso anterior
agent { node { label ‘ec2-fleet’ } }
stages { stage(‘Build’) { steps { echo “Build” } } stage(‘Test’) { steps { script { docker.image(‘hello-world’).inside() { echo ‘example inside docker container’ } } } } stage(‘Deploy’) { steps { echo ‘Deploy’ } } }}

3. Cuando ejecutamos el pipeline vamos a observar que en la pantalla principal de Jenkins visualizaremos el estado de las flotas de instancias, indicando para cada Spot Fleet Request el número actual de instancias y las objetivo.

Concluido este paso, ya tenemos lista nuestra flota de instancias spot que puede ser utilizada en nuestros jobs de Jenkins para distribuir la carga de trabajo automáticamente.

Si tu empresa necesita implementar prácticas DevOps, que les permita agilizar el negocio y ser más eficientes, puedes pedir más información en el siguiente enlace.

--

--