«En el principio… fue la línea de comandos» — Neal Stephenson, In the Beginning… was the Command Line
En esta guía abordamos un caso real: cómo desplegar Jenkins sobre Azure Kubernetes Service (AKS) usando instancias Spot para ahorrar hasta un 90% en costos de cómputo, sin sacrificar rendimiento ni resiliencia. Jenkins no es una excusa, sino el caso práctico elegido para explorar —con profundidad y sin atajos— cómo construir una arquitectura cloud-native eficiente, controlable, y preparada para fallos. A través de Jenkins como ejemplo real, veremos cómo estructurar pools de nodos diferenciados, cómo optimizar agentes CI/CD sobre Spot, y cómo mantener todo bajo control con CLI, observabilidad y scripting. No usaremos magia negra ni automatizaciones opacas: cada paso se ejecuta desde línea de comandos, y cada decisión se razona desde el principio. Jenkins será el hilo conductor que nos permite ir mucho más allá del CI: hablaremos de resiliencia, tolerancia a fallos, seguridad, eficiencia y gobierno técnico en entornos modernos.
Arquitectura: Jenkins en AKS + Spot (ahorro del 80–90%)
Implementamos una solución con Jenkins ejecutándose en un clúster AKS de múltiples node pools (grupos de nodos) para aprovechar Azure Spot VM. La arquitectura se compone de:
-
Node Pool de Sistema: nodos estándar para los pods del sistema Kubernetes (componentes base del clúster).
-
Node Pool “Regular”: nodos dedicados para el Jenkins Master (Controlador), con disponibilidad garantizada (no son Spot).
-
Node Pool “Spot”: nodos con instancias Spot de Azure, destinados a los workers (agentes) de Jenkins, autoescalables de 0 hasta N nodos según la demanda.
-
Toleraciones y labels: configuraciones para que solo los pods de agentes Jenkins se ejecuten en nodos Spot (por ejemplo, usando
nodeSelector
y tolerations apropiadas para las etiquetas/taints de Spot). -
RBAC seguro: roles y bindings para que Jenkins pueda crear/monitorizar pods en el namespace de agentes sin exceder permisos.
-
Load Balancer externo: para exponer la interfaz web de Jenkins Master al exterior (Servicio
LoadBalancer
en AKS que provee IP pública).
Este diseño permite que los agentes de Jenkins se creen bajo demanda en nodos Spot y se destruyan al terminar el trabajo, logrando un ahorro enorme de costos al usar capacidad ociosa de Azure. Las Spot VMs son ideales para cargas interruptibles como los jobs CI/CD de Jenkins, ya que si Azure recupera la VM Spot (algo infrecuente), Jenkins simplemente reintentará la build en otro agente sin mayores consecuencias. En resumen: pagamos mucho menos por los recursos de build, y solo pagamos cuando hay builds en ejecución, gracias al escalado automático a 0.
En este ejemplo, los nodos Spot y sus agentes son completamente stateless, lo que simplifica el diseño y reduce la superficie de error. Cada agente se lanza en un pod efímero que se elimina al finalizar su ejecución, sin necesidad de mantener datos entre builds. Esto permite una arquitectura altamente resiliente, donde perder un nodo Spot no supone pérdida de información ni impacto funcional real.
No obstante, si fuese necesario conservar estado —por ejemplo, para mantener workspaces, artefactos intermedios o cachés de dependencias entre builds—, esta arquitectura podría extenderse fácilmente. Bastaría con incorporar volúmenes persistentes montados en los pods (como Azure Files, Azure Disks o PVCs con política Retain), o utilizar almacenamiento externo como Azure Blob Storage para guardar los datos críticos. De este modo, incluso en entornos donde el estado importa, es posible seguir beneficiándose del ahorro en costes que ofrecen los nodos Spot, con una capa adicional de tolerancia a fallos.

El Jenkins Master reside en un nodo del pool Regular, expuesto mediante un Load Balancer de Azure. Cuando se requieren agentes para ejecutar builds, Jenkins (a través del plugin de Kubernetes) crea pods dinámicos con label spot en el namespace de workers. Kubernetes programa esos pods en los nodos Spot (prioritizados con Spot
), lo que hace que el Cluster Autoscaler arranque instancias Spot según sea necesario. Los agentes Jenkins se ejecutan en esos nodos Spot y desaparecen al terminar, permitiendo al autoscaler escalar los nodos Spot nuevamente a 0 (ahorro de costes). Los componentes del sistema corren en nodos dedicados de sistema para estabilidad. De esta forma, el Jenkins Master siempre corre en un nodo estable, mientras que los agentes usan nodos baratos Spot con la tolerancia a fallos adecuada.
Paso a paso con Azure CLI (evitando la “magia” de Terraform)
¿Por qué hacer todo a mano con CLI en lugar de usar Terraform o Bicep? Porque quería que entendierais cada paso y facilitar el troubleshooting. Las herramientas IaC automatizan pero pueden ocultar detalles; en cambio, usando comandos de Azure CLI vemos exactamente qué ocurre en cada fase, dejando todo documentado en comandos reproducibles. No todo en esta vida es GUI; siempre fue, es y será CLI.
A continuación resumimos los pasos principales ejecutados con Azure CLI (az
) y kubectl
para construir la solución:
-
Preparar entorno Azure: creación del Resource Group y red virtual. (Ejemplo:
az group create --name RG_Jenkins --location westeurope
, luego una VNet/Subnet para AKS.) -
Crear clúster AKS: usamos
az aks create
para desplegar el clúster con un node pool inicial de sistema. Tras crear el clúster, obtenemos credenciales conaz aks get-credentials
para operar conkubectl
. -
Agregar node pools adicionales: añadimos un pool “regular” para Jenkins Master y otro pool “spot” para agentes. El pool Spot lo creamos con opciones
--priority Spot --eviction-policy Delete
, configurando autoescalado (--enable-cluster-autoscaler
) conmin=0
ymax=N
nodos (y definiendo--max-count=N
apropiado). También aplicamos--node-taints
para marcar esos nodos como Spot (por ejemplokubernetes.azure.com/scalesetpriority=spot:NoSchedule
), de forma que solo pods tolerantes puedan usarlos. Antes de crear este pool, comprobamos cuotas de CPU Spot disponibles (Azure limita cuántos vCPU Spot puedes usar) – nuestro script verifica la cuota y advierte en caso de alcanzarla. -
Desplegar Jenkins Master: con Helm usando el chart oficial de Jenkins. Añadimos el repo de Helm de Jenkins y ejecutamos un comando tipo:
helm install jenkins-master jenkins/jenkins --namespace jenkins-master --create-namespace -f jenkins_helm_values.yaml --wait
. En los values definimos que el pod de Jenkins Master solo se ejecute en nodos del pool regular (usandonodeSelector: nodepool=regular
y una toleration al taintnodepool=regular:NoSchedule
), asegurando que el Master no caiga si se evicta un Spot. También configuramos credenciales admin (por ejemplo usuario admin / pass admin123) y una lista básica de plugins esenciales (Kubernetes, Git, Pipeline, etc.) que se instalan al arranque. -
Configurar RBAC para Jenkins: creamos cuentas de servicio y permisos. En nuestro caso, el chart de Jenkins ya crea una ServiceAccount
jenkins-master
. Le otorgamos un ClusterRole con permisos para crear pods, leer nodos, etc., y hacemos binding al ServiceAccount de Jenkins en el ámbito cluster. Adicionalmente, creamos un Role + RoleBinding específico en el namespacejenkins-workers
(donde correrán los agentes) para permitir a Jenkins manejar pods, PVCs, services, etc. solo en ese namespace. Aplicamos toda esta config conkubectl apply -f <manifiestos YAML>
(nuestro script lo automatiza insertando el YAML en un heredoc). -
Verificar Jenkins arriba: esperamos a que el pod de Jenkins esté
READY
. Nuestro script ejecutakubectl wait pod -n jenkins-master --for=condition=ready --timeout=300s
para asegurarse. Una vez listo, obtenemos la IP pública con:kubectl get svc jenkins-master -n jenkins-master -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
. Con esa IP confirmamos acceso web (Jenkins quedó enhttp://<IP>:8080
). 🎉 ¡Jenkins Master en AKS funcionando!
(Todos estos pasos los encontrarás en los scripts shell del repositorio: 00_setup_subscription.sh
, 01_create_cluster.sh
y 02_deploy_jenkins.sh
, que documentan claramente el proceso. Sí, podríamos haber hecho terraform apply
y obtener lo mismo, pero entonces no sabríamos cómo se construyó exactamente cada pieza; aquí preferimos la pedagogía sobre la automatización. “Para entenderlo, primero hazlo a mano” – filosofía 100% línea de comando.)

Integrando instancias Spot en Jenkins (configurando agentes dinámicos)
Con Jenkins en marcha, el siguiente paso es configurarlo para que use los nodos Spot como agentes de build. Para ello, aprovechamos el plugin Kubernetes de Jenkins (que ya habíamos instalado) para definir un Cloud de Kubernetes. Automaticé esta configuración mediante un script Groovy para evitar clics manuales en la UI de Jenkins:
-
Script Groovy de configuración: Crea un cloud Kubernetes nuevo (nombre
spot-final
) apuntando al servidor interno del cluster (https://kubernetes.default.svc
), en el namespacejenkins-workers
, con la conexión al Jenkins Master (usando la URL interna y el túnel JNLP por defecto). Luego define un Pod Template llamadoworker-spot
con labelspot
que Jenkins usará para lanzar agentes. En ese template indicamos:-
Node Selector:
spot=true
– nos aseguramos de que el pod agente solo se programe en nodos Spot. (Añadimos la etiquetaspot=true
a los nodos Spot del cluster para este propósito). -
Toleration: tolerar el taint de Spot (
kubernetes.azure.com/scalesetpriority=spot:NoSchedule
). Esto permite que el scheduler de K8s asigne el pod al nodo Spot a pesar del taint. -
Capacidad: límite de hasta 5 agentes simultáneos (
instanceCap: 5
) y que cada agente inactivo más de 1 minuto se termine (así liberamos el nodo rápidamente cuando no hay carga). -
Contenedor base: usamos la imagen estándar
jenkins/inbound-agent:latest
para el contenedor JNLP del agente, con requests de CPU/mem bajos (100m, 256Mi) y limits moderados (500m, 512Mi). -
Workspace Volume: configuramos un
EmptyDir
efímero como volumen de trabajo (cada pod agente tiene su espacio temporal aislado).
-
El script Groovy primero limpia cualquier configuración previa de clouds que empiece por «spot», para evitar duplicados si se re-ejecuta. Luego agrega el nuevo cloud a Jenkins y hace Jenkins.instance.save()
. Al ejecutarlo, en la consola de Jenkins vimos mensajes de éxito indicando que se creó el cloud spot-final y el template worker-spot con label «spot».
Para aplicar este script Groovy en Jenkins, usamos la Script Console de Jenkins. Nuestro script de automatización guía al usuario a pegar el contenido del archivo generado (jenkins_spot_cloud.groovy
) en la consola script, y darle a Run. Tras correrlo, Jenkins quedó configurado para usar nuestro clúster AKS como fuente de agentes dinámicos.
Con esto, Jenkins ya sabe cómo crear pods-agente en Kubernetes. ¡Pero faltaba probar que realmente funcionara en la práctica!
Creamos entonces un pipeline de prueba. El pipeline (escrito en Jenkinsfile Declarative) simplemente solicita un agente con label ‘spot’ y ejecuta varios stages de demostración dentro de ese agente (por ejemplo, imprimir un mensaje, dormir unos segundos simulando trabajo, etc.).
Al lanzar este pipeline de prueba en Jenkins; Jenkins solicita un nuevo pod agente; el clúster AKS activa automáticamente un nodo Spot (si no había ninguno corriendo) gracias al Cluster Autoscaler; en pocos segundos el pod worker-spot
aparece en el namespace jenkins-workers
. Jenkins conecta con él vía JNLP y ejecuta los stages allí. En el log de la build veremos que efectivamente los pasos corren en el agente con label «spot». Al terminar, Jenkins borra el pod y tras ~1 minuto sin cargas, el nodo Spot mismo se cierra (escalado a 0 nuevamente) para no seguir generando costo. ¡Perfecto! Jenkins + AKS + Spot funcionando en armonía.

Jenkins Master, a través del plugin de Kubernetes, solicita al API de Kubernetes crear un pod para el agente con cierta etiqueta (por configuración, spot). Kubernetes no encuentra inmediatamente un nodo adecuado (porque el pool Spot estaba en 0 nodos), entonces el Cluster Autoscaler detecta el pod pendiente y solicita a Azure la creación de un nodo Spot. Azure aprovisiona una nueva VM Spot y la agrega al clúster AKS. El pod agente entonces puede programarse en ese nuevo nodo Spot; Jenkins establece conexión con el agente (vía JNLP) y ejecuta las etapas del pipeline en él. Al finalizar la build, el pod del agente se elimina, y al poco tiempo el autoscaler detecta que el nodo Spot quedó vacío, procediendo a destruirlo para retornar a 0 nodos (ahorrando costo hasta la próxima build). Todo este proceso sucede de forma transparente y automática, aprovechando al máximo la capacidad bajo demanda.
Observabilidad: Fluent Bit + Loki + Prometheus + Grafana para diagnosticar
Como parte de la solución, desplegamos un stack de observabilidad en el clúster, compuesto por Fluent Bit (encargado de recolectar logs de todos los pods/nodos), Loki (almacenando esos logs de forma indexada) y Grafana (para visualizar todo). Adicionalmente, incorporamos Prometheus para métricas, junto con Node Exporter, kube-state-metrics y otros componentes, para obtener una visión completa del rendimiento y estado del sistema. (Revisa los scripts 05_install_observability.sh
y 07_install_prometheus_monitoring.sh
para la instalación de estos componentes, y el script 08_setup_grafana.sh
junto con el contenido del directorio grafana/
para la configuración de dashboards.)
¿Para qué todo esto? Imagina que alguno de los componentes falla: por ejemplo, que Jenkins no pueda lanzar agentes, o que un nodo Spot sea evicto en mitad de una build. Con Loki + Grafana, podemos buscar fácilmente en los logs centralizados por palabra clave o filtrar por pod/nodo problemático, en lugar de revisar cada pod manualmente. También capturamos eventos de Kubernetes (como la eviction de un Spot VM) en Loki, lo que facilita ver cuándo Azure reclamó una VM Spot.
Durante mis pruebas, Grafana mostró, por ejemplo, los eventos de escalado: cuándo el clúster creó un nodo Spot y cuándo lo eliminó. Además, podíamos monitorear el log del Jenkins Master en tiempo real, y los logs de los pods agentes (p. ej. si fallan al iniciar, ahí veríamos el error). Este panel unificado de observabilidad es invaluable para troubleshooting en entornos distribuidos. Con Prometheus, también obtenemos métricas de CPU, memoria, etc., comparando el uso en nodos Spot vs nodos regulares, viendo cuántos pods se ejecutaron, tiempos de respuesta, etc. Incluso configuramos alertas básicas (vía AlertManager) para notificar si, por ejemplo, un pipeline lleva demasiado tiempo o si un nodo Spot fue preempted.
Sin embargo, pese a tener todas estas herramientas, siempre hay casos en que toca remangarse y usar la línea de comandos directamente para investigar un problema profundo. A veces, la interfaz gráfica o incluso Grafana no te muestran todo el contexto, o necesitas obtener la configuración exacta de algún componente. Aquí es donde el buen CLI vuelve a entrar en acción.

Deployamos un stack de monitorización completo dentro del clúster. Fluent Bit (en cada nodo) captura los logs de todos los pods (Jenkins Master, agentes, system, etc.) y los envía a Loki, donde quedan indexados y almacenados. Node Exporter (en cada nodo) recopila métricas de sistema (CPU, memoria, etc.), mientras kube-state-metrics expone métricas sobre el estado de Kubernetes (número de pods, estados, etc.); Prometheus recoge esas métricas periódicamente y las almacena. Grafana está configurado con Loki y Prometheus como orígenes de datos, proporcionando paneles unificados donde podemos ver tanto logs como métricas en un solo lugar. Configuramos además AlertManager para manejar alertas basadas en las métricas (por ejemplo, detectar si un nodo Spot es preemptado o si un job falla repetidamente). En Grafana creamos dashboards específicos: uno para monitorizar los agentes Spot (ver cuántos se lanzan, duración de jobs, interrupciones, ahorro estimado, etc.) y otro para la salud general del clúster y Jenkins. Gracias a esta observabilidad, cuando algo va mal podemos correlacionar eventos, logs y métricas rápidamente. Por ejemplo, si un job quedó colgado esperando agente, veremos en Grafana la línea de tiempo: cuándo Jenkins pidió el pod, si el autoscaler lanzó nodo, si hubo errores en los logs, todo sin salir de la herramienta.
Troubleshooting: resolviendo problemas paso a paso (con CLI)
Veamos un escenario hipotético de problema y cómo lo abordaríamos con nuestra metodología:
Caso de ejemplo: Lanzamos una build en Jenkins, pero no arranca ningún agente. La build queda encolada indefinidamente esperando un nodo (agente) y nunca progresa. ¿Qué pasó?
Para diagnosticar este tipo de incidencia, seguiríamos una serie de comprobaciones utilizando tanto las herramientas gráficas como, sobre todo, comandos CLI directos:
-
Verificar autoscaler (nodos disponibles): Primero, comprobamos si el clúster intentó crear un nodo Spot. Por ejemplo, con
kubectl get nodes
vemos los nodos actuales del clúster. Si no apareció ningún nodo nuevo para agentes, significa que el autoscaler no lanzó ninguno. -
Confirmar configuración de etiquetas: ¿El pipeline de Jenkins solicitó correctamente un agente con el label
spot
? (En nuestro pipeline de prueba, sí lo hizo.) ¿Los nodos Spot del clúster tienen la etiquetaspot=true
requerida? Quizá olvidamos añadirla. Si el Jenkins Master pide agentesspot
pero ningún nodo cumple esa etiqueta, Kubernetes no podrá programar el pod. Solución: añadir esa etiqueta a los nodos Spot (kubectl label node <nombre-nodo-spot> spot=true
) o ajustar elnodeSelector
del template de agentes en Jenkins para usar la etiqueta/taint correcta que tengan los nodos Spot. -
Validar autoscaler y cuotas de Azure: El Cluster Autoscaler estaba habilitado (
min=0
), pero podría ser que no haya podido lanzar nodo por cuota insuficiente o configuración. Nuestro despliegue ya consideraba el tema de la cuota: la CLI nos advirtió del límite de Low Priority Cores disponible. Si al pedir un nuevo nodo Spot Azure lo deniega por cuota, en los eventos del clúster o en los logs del autoscaler se reflejaría. Solución: aumentar la cuota en Azure (solicitud de ampliación) o reducir el tamaño de VM usada para Spot. -
Revisar logs de Jenkins Master: Si los agentes ni siquiera se intentan crear, conviene inspeccionar los logs del Jenkins Master para ver mensajes del plugin Kubernetes. Con
kubectl logs -n jenkins-master deploy/jenkins-master
podemos ver si Jenkins arrojó algún error al intentar proveer el agente. Por ejemplo, a veces la conexión del plugin falla por certificados (SSL), o puede registrar algo como “no matching node found for label ‘spot’” indicando que el scheduler no encontró nodo con esa etiqueta (lo cual confirma el problema de la etiqueta mencionado arriba). Cualquier mensaje de error aquí es una pista directa. -
Inspeccionar eventos de Kubernetes: Los eventos nos dan información reciente sobre decisiones del scheduler. Ejecutamos
kubectl get events -A | grep jenkins
para filtrar eventos relacionados con Jenkins. Podríamos ver, por ejemplo:FailedScheduling
con mensaje “0/1 nodes available: 1 node(s) didn’t match node selector”, lo que apunta nuevamente a un problema de node selector o taints (nodo Spot estaba disponible pero el pod no podía asignarse por las restricciones). O quizás un eventoFailedScheduling: 0/0 nodes available
– indicando que no había ningún nodo apto (el autoscaler no llegó a proveerlo, posiblemente por la cuota excedida). -
Validar RBAC: Si los agentes ni siquiera aparecen como pods pendientes en el clúster, podría ser que Jenkins no tuviera permisos para crearlos. Verificamos que en Jenkins (Manage Jenkins > System > Kubernetes Clouds) el cloud esté configurado correctamente y asociado a la ServiceAccount esperada. En el lado de Kubernetes, podemos comprobar que el ServiceAccount de Jenkins tiene los RoleBinding/ClusterRoleBinding que creamos. Por ejemplo, listar con
kubectl get clusterrolebinding jenkins-master
ykubectl describe sa jenkins-master -n jenkins-master
para asegurarnos de que están vinculados. Si faltara algún permiso (por ejemplo, crear pods en el namespace de workers), habría que ajustarlo y volver a probar. -
Caso Spot evicted a mitad de build: Supongamos ahora que el problema fue distinto: un agente sí inició y empezó a ejecutar la build, pero Azure reclamó la VM Spot a mitad de proceso (eventualidad rara, pero posible). ¿Cómo detectamos eso? En Grafana/Loki veríamos un evento de nodo evicted con razón Preempted. Con CLI pura,
kubectl describe node <nombre-nodo>
mostraría que el nodo pasó a estadoNotReady
con Reason=Terminated. Kubernetes también podría listar un evento tipo “Node <X> evicted: Spot VM preempted”. En este caso Jenkins marca la build como fallo (si el agente muere, el job falla) pero típicamente los pipelines CI/CD están preparados para reintentar. Solución: dejar que Jenkins reintente en otro agente (o configurar reintentos automáticos si es crítico). Si esto ocurriera con frecuencia, considerar estrategias como: usar tipos de instancia Spot menos propensas a preemption, o reservar un pool de agentes alternativo (no Spot) para etapas muy críticas donde no queremos interrupciones. -
Lección aprendida: Por cada síntoma, combinamos las herramientas gráficas con comandos directos: Azure CLI para el estado de la infraestructura, kubectl para el estado de recursos K8s, y Jenkins (su UI, logs o incluso CLI/Jenkins Script Console) para detalles de la aplicación. Este enfoque sistemático de troubleshooting es aplicable no solo a Jenkins, sino a cualquier sistema distribuido sobre Kubernetes. Primero, recopilas información básica (¿qué ves en los nodos? ¿qué dicen los logs? ¿y los eventos?), luego vas profundizando (¿coinciden las configuraciones? ¿hay errores de permisos? ¿limitaciones externas?). Integrando múltiples fuentes de información, encontrar la causa raíz de un problema se vuelve mucho más manejable.

Extrapolando el enfoque a otras herramientas (¿JMeter en AKS?)
La idea de usar un clúster para agentes dinámicos y hacer troubleshooting con CLI se puede aplicar a otras soluciones. Por ejemplo, JMeter, una de las herramientas de cabecera para pruebas de rendimiento.
JMeter soporta un modo distribuido con múltiples servers de carga (workers). Podríamos desplegar JMeter en AKS de forma similar a Jenkins: un pod maestro de JMeter orquestando varios pods agentes que generan carga. Incluso estos agentes podrían ubicarse en nodos Spot si queremos ahorrar costo en pruebas largas. La configuración del maestro/worker, las toleraciones, etc., sería muy análoga a lo que hicimos con Jenkins. La clave está en separar roles (un coordinador estable vs. trabajadores efímeros), usar node pools adecuados para cada uno, y aprovechar la elasticidad del clúster para escalarlos según demanda. Todo ello acompañado de monitoreo centralizado (por ejemplo, recogeríamos métricas de rendimiento de los pods de JMeter, logs de errores en los workers, etc. con herramientas similares a Loki/Prometheus).
En general, cualquier carga de trabajo batch o de agentes temporales (pruebas, procesamiento paralelo, CI/CD, rendering, etc.) puede beneficiarse de este patrón: nodos Spot autoescalables + pods efímeros orquestados por una herramienta central. Se obtiene aislamiento, escalabilidad y gran ahorro en costes, asumiendo una tolerancia a interrupciones transitorias.
Conclusión
Desplegar Jenkins en AKS con instancias Spot demuestra cómo combinar eficiencia de costos y flexibilidad en la nube sin perder confiabilidad. Ahorramos dinero utilizando nodos Spot para tareas efímeras y, gracias a Kubernetes, mantenemos aislamiento y escalabilidad automática de los agentes CI.
Además, reforzamos la importancia de instrumentar el entorno con buenas herramientas de observabilidad, pero también de no depender únicamente de interfaces gráficas. En última instancia, cuando algo falla y necesitas respuestas, la línea de comandos y un enfoque sistemático de troubleshooting son tus mejores aliados.
La automatización y las GUIs son geniales para el día a día, pero «en el principio fue la línea de comandos» y al final, siempre es la línea de comandos la que nos da la solución.
¿Quieres probarlo tú mismo?
Todo lo descrito en esta guía está empaquetado en una POC funcional que puedes desplegar en minutos. Incluye:
-
Scripts shell organizados paso a paso (
00_*
,01_*
, etc.). -
Manifiestos YAML con RBAC y configuración de agentes.
-
Archivos Helm preconfigurados.
-
Script Groovy para configurar el cloud de Jenkins.
-
Dashboards predefinidos para Grafana.
-
Un
README.md
detallado que te guía desde cero, con todos los comandos necesarios para lanzar tu propio Jenkins autoscalable con Spot.