Instalación y configuración inicial
Requisitos previos del sistema
Entorno Java
apt update
apt search openjdk
apt install -y openjdk-11-jdk
java -version
Despliegue de Jenkins
# Obtención del paquete WAR desde el repositorio oficial
wget https://get.jenkins.io/war-stable/2.426.2/jenkins.war
# Ajuste de fuentes de plugins para mejorar velocidad de descarga
sed -i 's|https://updates.jenkins.io/download|https://mirrors.tuna.tsinghua.edu.cn/jenkins|g' /var/lib/jenkins/updates/default.json
sed -i 's|https://www.google.com|https://www.baidu.com|g' /var/lib/jenkins/updates/default.json
Extensiones recomendadas
# Lista de plugins esenciales para un entorno productivo
# Gestión de carpetas y formateo
Folders
OWASP Markup Formatter
Build Timeout
# Credenciales y autenticación
Credentials Binding
PAM Authentication
# Utilidades de construcción
Timestamper
Workspace Cleanup
Environment Injector
Build Name and Description Setter
Display Console Output
# Soporte para pipelines
Pipeline
Pipeline Graph Analysis
Pipeline: API
Pipeline: Basic Steps
Pipeline: Declarative
# Control de versiones
Git
Git Parameter
# Conectividad con agentes
SSH Build Agents
Matrix Authorization Strategy
# Notificaciones y correo
Email Extension
Mailer
# Integraciones externas
GitLab
build user vars
DingTalk
# Herramientas de construcción
Ant
NodeJs
# Interfaz y visualización
Blue Ocean
Active Choices
Job Configuration History
# Contenedores y orquestación
Docker
Docker Pipeline
Kubernetes
Configuración de agentes remotos
Agentes basados en nodos físicos o virtuales
# 1. Preparar el entorno Java en el nodo esclavo
apt update && apt install -y openjdk-11-jdk
# 2. Configurar el agente en Jenkins:
# - Establecer el directorio de trabajo
# - Asignar etiquetas (labels) separadas por espacios
# - Registrar una clave SSH pública
Agentes en clúster Kubernetes
# Extraer la dirección del servidor K8s
grep server ~/.kube/config
# Generar archivos de certificado a partir del kubeconfig
grep certificate-authority-data ~/.kube/config | base64 -d > ca.pem
grep client-certificate-data ~/.kube/config | base64 -d > client.pem
grep client-key-data ~/.kube/config | base64 -d > client-key.pem
# Crear archivo PKCS12 para importar como credencial
openssl pkcs12 -export \
-out kube-cred.pfx \
-inkey client-key.pem \
-in client.pem \
-certfile ca.pem
# Subir el archivo .pfx como nueva credencial en Jenkins y verificar conexión
Sistema de Pipelines
Gestión de credenciales
# Opciones disponibles para almacenar credenciales:
# - Usuario con contraseña
# - Clave privada SSH
# - Token de acceso (GitLab, GitHub, etc.)
# - Texto secreto
# - Archivo secreto
# Cada credencial posee:
# - ID: identificador único visible en Jenkins
# - Descripción: nota explicativa sobre su propósito
Conceptos fundamentales del Pipeline
Pipeline
Secuencia automatizada de pasos que implementa el flujo de entrega continua, compuesta por múltiples etapas encadenadas.
Nodo (Agent)
Representa un ejecutor del pipeline, ya sea el nodo maestro o un agente esclavo. Cada agente actúa como una máquina independiente que recibe y ejecuta tareas asignadas.
Etapa (Stage)
Agrupación lógica de acciones relacionadas que pertenecen a una fase específica del proceso, como compilación, pruebas o despliegue.
Paso (Step)
Operación individual dentro de una etapa, representando la unidad mínima de ejecución en el pipeline.
Sintaxis disponibles
Sintaxis declarativa
pipeline {
agent any
stages {
stage('Compilacion') {
steps {
sh 'make build'
}
}
stage('Verificacion') {
steps {
sh 'make test'
junit 'results/**/*.xml'
}
}
stage('Publicacion') {
steps {
sh 'make release'
}
}
}
}
Sintaxis scriptada
node {
stage('Compilacion') {
sh 'make build'
}
stage('Verificacion') {
sh 'make test'
}
stage('Publicacion') {
sh 'make release'
}
}
Métodos de construcción
Interfaz clásica
Permite escribir directamente el código del pipeline en el editor integrado de Jenkins.
Blue Ocean
Ofrece una interfaz visual intuitiva para diseñar y ejecutar pipelines de forma gráfica.
Integración con repositorio SCM
# Crear un proyecto en GitLab, clonar localmente
git clone git@gitlab.example.com:equipo/proyecto-ci.git
# Generar el archivo Jenkinsfile y subirlo al repositorio
git add Jenkinsfile
git commit -m "Agregar pipeline de integracion continua"
git push origin main
# En Jenkins, seleccionar "Pipeline from SCM"
# Configurar la URL del repositorio y las credenciales de acceso
Generación de fragmentos de código
La herramienta de sintaxis del pipeline permite generar fragmentos de código reutilizables como plantillas.
Referencia de sintaxis del Pipeline
Documentación oficial: https://www.jenkins.io/zh/doc/book/pipeline/syntax/
Estructura general
# El bloque pipeline encapsula stages, steps e instrucciones
pipeline {
# Las sentencias no requieren separadores
# Cada directiva ocupa su propia línea
}
Directiva agent
Obligatoria. Puede declararse a nivel global o dentro de cada etapa. Parámetros soportados:
- any: ejecutar en cualquier agente disponible
- none: sin agente global, cada etapa debe definir el suyo
- label: filtrar agentes por etiqueta
- node: similar a label con opciones adicionales
- docker: ejecutar dentro de un contenedor específico
- dockerfile: construir imagen desde un Dockerfile y ejecutar en ella
Ejecución en agente por etiqueta
pipeline {
agent {
label 'worker-alpha'
}
stages {
stage('Verificacion') {
steps {
sh 'hostname'
}
}
}
}
Ejecución en contenedor Docker
pipeline {
agent {
docker {
image 'registry.example.com/tools/alpine:v2'
label 'worker-alpha'
}
}
stages {
stage('Verificacion') {
steps {
sh 'hostname -i'
}
}
}
}
Construcción desde Dockerfile
pipeline {
agent {
dockerfile {
filename 'Dockerfile'
dir './containers/alpine'
label 'worker-alpha'
additionalBuildArgs '--build-arg entorno=produccion'
}
}
stages {
stage('Verificacion') {
steps {
sh 'hostname -i'
}
}
}
}
Bloque post
Define acciones que se ejecutan según el resultado del pipeline o de una etapa. Los condicionales disponibles son:
- always: se ejecuta sin importar el resultado
- changed: se ejecuta solo si el estado cambió respecto a la ejecución anterior
- failure: se ejecuta cuando el estado es fallido (rojo en la interfaz)
- success: se ejecuta cuando el estado es exitoso (verde o azul)
- unstable: se ejecuta cuando hay fallos en pruebas o violaciones de código (amarillo)
- aborted: se ejecuta cuando el pipeline fue cancelado manualmente (gris)
pipeline {
agent any
stages {
stage('Ejemplo') {
steps {
echo 'Hola Mundo'
}
}
}
post {
always {
echo 'Este mensaje aparece siempre'
}
}
}
Ejemplo con post en múltiples niveles
pipeline {
agent {
dockerfile {
filename 'Dockerfile'
dir './containers/alpine'
label 'worker-alpha'
additionalBuildArgs '--build-arg version=stable'
}
}
stages {
stage('Compilacion') {
steps {
sh 'hostname -i'
}
post {
always {
echo "Ejecucion completada"
}
success {
echo "Compilacion exitosa"
}
failure {
echo "Compilacion fallida"
}
}
}
}
post {
always {
echo 'Siempre se ejecuta'
}
success {
echo 'Resultado: exito'
}
failure {
echo 'Resultado: fallo'
}
unstable {
echo 'Resultado: inestable'
}
changed {
echo 'Estado cambiado'
}
}
}
Bloque stages
Contenedor obligatorio que agrupa una o más etapas del pipeline.
pipeline {
agent any
stages {
stage('Ejemplo') {
steps {
echo 'Hola Mundo'
}
}
}
}
Bloque steps
Define las operaciones concretas a realizar dentro de una etapa. Es obligatorio dentro de cada stage.
pipeline {
agent any
stages {
stage('Ejemplo') {
steps {
echo 'Hola Mundo'
}
}
}
}
Variables de entorno
Se declaran con la directiva environment. Su alcance depende de dónde se definan. La función credentials() permite acceder a credenciales almacenadas.
pipeline {
agent any
environment {
COMPILADOR = 'clang'
}
stages {
stage('Ejemplo') {
environment {
CLAVE_SECRETA = credentials('mi-texto-secreto')
}
steps {
sh 'printenv'
}
}
}
}
Variables estáticas
# Las variables se resuelven siguiendo un alcance jerárquico interno a externo
pipeline {
agent {
dockerfile {
filename 'Dockerfile'
dir './containers/alpine'
label 'worker-alpha'
}
}
environment {
PROYECTO = 'MiAplicacion'
AMBIENTE = 'produccion'
}
stages {
stage('Compilacion') {
environment {
AMBIENTE = 'pruebas'
}
steps {
sh 'echo "Proyecto: $PROYECTO"'
sh 'echo "Ambiente: $AMBIENTE"'
}
}
}
}
Variables dinámicas
# Requiere que se haya definido un agente
pipeline {
agent {
label 'worker-alpha'
}
environment {
SALUDO = """${sh(
returnStdout: true,
script: 'echo "Hola desde el agente"'
)}"""
CODIGO_SALIDA = """${sh(
returnStatus: true,
script: 'exit 0'
)}"""
}
stages {
stage('Mostrar') {
steps {
sh 'echo "Saludo: $SALUDO"'
sh 'echo "Codigo: $CODIGO_SALIDA"'
}
}
}
}
Directiva options
Configura comportamientos específicos del pipeline:
- buildDiscarder: limitar el número de ejecuciones históricas conservadas
- disableConcurrentBuilds: impedir ejecuciones simultáneas
- skipDefaultCheckout: omitir la clonación automática del código fuente
- skipStagesAfterUnstable: detener etapas adicionales si el estado es inestable
- checkoutToSubdirectory: clonar código en un subdirectorio específico
- timeout: establecer un límite de tiempo para la ejecución
- retry: reintentar el pipeline un número determinado de veces en caso de fallo
- timestamps: añadir marca temporal a cada línea de la consola
pipeline {
agent any
options {
timeout(time: 30, unit: 'MINUTES')
disableConcurrentBuilds()
timestamps()
}
stages {
stage('Ejemplo') {
steps {
echo 'Proceso con limite de tiempo'
}
}
}
}
Directiva parameters
Define entradas que el usuario proporciona al iniciar la construcción. Se acceden mediante params.NOMBRE.
pipeline {
agent any
parameters {
string(name: 'DESTINATARIO', defaultValue: 'Equipo', description: '¿A quién dirigir el saludo?')
}
stages {
stage('Saludo') {
steps {
echo "Hola ${params.DESTINATARIO}"
}
}
}
}
Directiva triggers
Define los mecanismos que inician la ejecución del pipeline:
- cron: programación temporal con sintaxis cron
- pollSCM: sondeo del repositorio de código con detección de cambios
- upstream: activación cuando otros trabajos completan con un estado mínimo
triggers {
cron('H 2 * * 1-5') // Ejecutar de lunes a viernes a las 2 AM
pollSCM('H/15 * * * *') // Verificar cambios cada 15 minutos
upstream('compilar,empaquetar', threshold: hudson.model.Result.SUCCESS)
}
Directiva input
Crea puntos de interacción donde el pipeline espera confirmación o datos del usuario.
pipeline {
agent any
stages {
stage('Aprobacion') {
input {
message "¿Deseas continuar con el despliegue?"
ok "Sí, desplegar"
submitter "admin,lider-tecnico"
parameters {
string(name: 'VERSION', defaultValue: '1.0.0', description: 'Version a desplegar')
}
}
steps {
echo "Desplegando version ${VERSION}"
}
}
}
}
Directiva when
Controla la ejecución condicional de etapas. Se evalúa antes de asignar el agente a la etapa. Condiciones disponibles:
- branch: coincide con el nombre de la rama (solo pipelines multibranch)
- environment: verifica el valor de una variable de entorno
- expression: evalúa una expresión Groovy
- not: invierte la condición anidada
- allOf: todas las condiciones deben cumplirse (AND lógico)
- anyOf: al menos una condición debe cumplirse (OR lógico)
Directiva parallel
Ejecuta múltiples etapas simultáneamente, distribuyéndolas entre diferentes agentes para optimizar el tiempo.
pipeline {
agent any
stages {
stage('Preparacion') {
steps {
sh 'hostname; date'
echo 'Etapa inicial de preparacion'
}
}
stage('Ejecucion paralela') {
parallel {
stage('Analisis') {
agent { label 'worker-alpha' }
steps {
sh 'hostname; date'
echo 'Ejecutando analisis de codigo'
sleep 8
}
}
stage('Pruebas') {
agent any
steps {
sh 'hostname; date'
echo 'Ejecutando suite de pruebas'
sleep 5
}
}
}
}
stage('Finalizacion') {
agent { label 'worker-alpha' }
steps {
sh 'hostname; date'
echo 'Etapa final completada'
}
}
}
}
Manejo de secretos en pipelines
Texto secreto
pipeline {
agent {
label 'worker-alpha'
}
environment {
TOKEN_ACCESO = credentials('secreto-k8s')
}
stages {
stage('Uso') {
steps {
sh 'echo $TOKEN_ACCESO' // Se muestra enmascarado en la consola
}
}
}
}
Credenciales de usuario y contraseña
pipeline {
agent {
label 'worker-alpha'
}
environment {
GITLAB_CREDS = credentials('cred-gitlab')
GITLAB_USUARIO = credentials('cred-gitlab')
GITLAB_CONTRASENA = credentials('cred-gitlab')
}
stages {
stage('Autenticacion') {
steps {
sh 'echo "Usuario: $GITLAB_USUARIO"' // Visible en texto plano
sh 'echo "Password: $GITLAB_CONTRASENA"' // Enmascarado en consola
sh 'echo "Credencial: $GITLAB_CREDS"' // usuario:contraseña enmascarado
}
}
}
}
Herramientas (Tools)
Las herramientas representan utilidades instaladas en los agentes, como Maven, Docker o Git. Cada versión se registra con un nombre único, facilitando su invocación dentro del pipeline.
Casos de uso prácticos
Integración continua (CI)
Objetivo: al enviar código al repositorio, ejecutar automáticamente la obtención del código, análisis estático, compilación y publicación de artefactos en un registro privado.
Plugins necesarios: GitLab, SonarQube Scanner, Harbor.
Obtención del código fuente
Configurar clave SSH en el agente
Registrar la clave pública del agente en la configuración de acceso del repositorio GitLab.
Verfiicar la conexión
Crear un pipeline simple que ejecute git clone para confirmar que las credenciales funcionan correctamente.
Análisis estático con SonarQube
Configurar SonarQube Server
Registrar la instancia de SonarQube en la cnofiguración global de Jenkins.
Integrar con GitLab
# Instalar el plugin GitLab Branch Source
# Configurar la conexión con el servidor GitLab
Crear webhook de notificación
# Definir un pipeline y anotar la URL del webhook junto con el token generado
# Registrar dicha URL como webhook en la configuración del proyecto en GitLab
Registrar la herramienta sonar-scanner
En la configuración global de herramientas de Jenkins, agregar una entrada para sonar-scanner apuntando a la instalación local.
Archivo de configuración del proyecto
# Crear el archivo sonar-project.properties en la raíz del repositorio
sonar.projectKey=mia-app
sonar.projectName=Mia App
sonar.sources=src
Pipeline de análisis
node {
stage('Obtener codigo') {
checkout scm
}
stage('Analisis SonarQube') {
def scanner = tool 'sonar-scanner'
withSonarQubeEnv() {
sh "${scanner}/bin/sonar-scanner"
}
}
}
Empaquetado de aplicaciones
Construcción de imagen Docker
stage('Empaquetar') {
steps {
script {
def imagen = docker.build("registry.interno/mia-app:${env.BUILD_ID}", "-f docker/Dockerfile .")
imagen.push()
imagen.push('latest')
}
}
}
Compilación con Maven
pipeline {
agent {
docker {
image 'registry.interno/maven:3.8'
args '-v /opt/maven-conf/settings.xml:/usr/share/maven/conf/settings.xml'
}
}
stages {
stage('Compilar') {
steps {
sh 'mvn clean package -DskipTests=true'
}
}
}
}
Entrega continua (CD)
Plugins requeridos
- Git: obtiene el código fuente desde repositorios remotos
- Docker: gestiona entornos contenedorizados y credenciales de registros
- Kubernetes: provisiona agentes dinámicos dentro del clúster para ejecutar trabajos
- Kubernetes CLI: proporciona el entorno para ejecutar comandos kubectl y helm
- Config File Provider: almacena archivos de configuración reutilizables (settings.xml, properties, etc.)
- Pipeline Utility Steps: facilita la lectura y manipulación de archivos como pom.xml, JSON o YAML
- Git Parameter: lista dinámicamente las ramas del repositorio para que el usuario seleccione cuál desplegar
Credenciales necesarias
- Credencial de acceso al repositorio Git
- Token de servicio para el clúster Kubernetes
- Credencial de acceso al registro de contenedores Docker
Pipeline de despliegue con agentes Kubernetes
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-worker
spec:
nodeSelector:
kubernetes.io/hostname: node-trabajo-01
volumes:
- name: bin-kubectl
hostPath:
path: /usr/local/bin/kubectl
- name: kube-config
hostPath:
path: /home/deploy/.kube/config
containers:
- name: jnlp
image: registry.interno/jnlp-agent:latest
workingDir: /home/jenkins/workspace
- name: herramientas
image: registry.interno/busybox:stable
volumeMounts:
- name: bin-kubectl
mountPath: /usr/bin/kubectl
- name: kube-config
mountPath: /root/.kube/config
command:
- cat
tty: true
'''
retries 2
}
}
stages {
stage('Desplegar') {
steps {
container('herramientas') {
sh 'kubectl get nodes'
sh 'kubectl apply -f k8s/deployment.yaml'
}
}
}
}
}