Cómo hacer una copia de seguridad y restaurar su instancia de Jenkins

Realiza copias de seguridad y restaura Jenkins de forma segura archivando JENKINS_HOME, preservando secretos y probando la recuperación antes de necesitarla.

Cómo hacer una copia de seguridad y restaurar tu instancia de Jenkins

Jenkins a menudo se convierte en el plano de control para tus compilaciones, despliegues, credenciales e historial de versiones. Si pierdes $JENKINS_HOME durante una falla de disco o una migración incorrecta, tus pipelines de CI/CD pueden detenerse incluso si el paquete de Jenkins en sí es fácil de reinstalar.

Esta guía te muestra qué respaldar, cómo crear un archivo del sistema de archivos de manera segura y cómo restaurar Jenkins sin romper credenciales ni permisos de archivos.

Comprendiendo el núcleo: El directorio $JENKINS_HOME

Cada instancia de Jenkins depende de un único directorio raíz, denominado $JENKINS_HOME. Este directorio contiene todos los archivos de configuración, complementos, registros y datos de trabajos. Hacer una copia de seguridad de Jenkins significa fundamentalmente respaldar el contenido de este directorio.

Dependiendo de tu método de instalación (por ejemplo, paquete Linux, contenedor Docker), la ubicación de $JENKINS_HOME generalmente varía:

  • Linux (Instalación por paquete): /var/lib/jenkins
  • Docker: A menudo montado en un volumen, por ejemplo, /var/jenkins_home
  • JAR independiente: El directorio donde se inició el proceso de Jenkins, a menos que se especifique mediante variables de entorno.

Identificando componentes críticos de datos

Si bien respaldar todo el directorio $JENKINS_HOME es el enfoque más simple, puede generar archivos extremadamente grandes si se incluyen el historial de compilaciones y los datos del espacio de trabajo. Para una copia de seguridad de recuperación ante desastres rápida y eficiente, debes asegurarte de que se capturen los siguientes directorios y archivos:

Componente Ruta dentro de $JENKINS_HOME Propósito
Configuración global config.xml Archivo de configuración principal para la instancia raíz de Jenkins.
Definiciones de trabajos jobs/ Contiene subdirectorios para cada trabajo configurado, cada uno con su propio config.xml.
Usuarios y credenciales users/ y credentials.xml Cuentas de usuario, configuraciones del ámbito de seguridad y secretos almacenados.
Claves de seguridad secrets/ Claves de cifrado esenciales para descifrar datos sensibles como credenciales almacenadas.
Lista de complementos plugins/ Contiene los archivos .hpi de todos los complementos instalados.
Definiciones de nodos nodes/ Configuraciones para todos los agentes de compilación conectados (si están definidos).

Método 1: La copia de seguridad del sistema de archivos (Recomendado)

El método más confiable para hacer una copia de seguridad de Jenkins es crear un archivo comprimido y consistente de los archivos necesarios mientras el servicio se detiene momentáneamente.

Paso 1: Detener el servicio de Jenkins

Para garantizar la consistencia de los datos y evitar escrituras parciales de archivos durante el proceso de copia de seguridad, el proceso de Jenkins debe detenerse. No detener el servicio corre el riesgo de una copia de seguridad incompleta o corrupta.

# Para sistemas que usan systemd (la mayoría de las distribuciones Linux modernas)
sudo systemctl stop jenkins

# O, para sistemas que usan el comando service
sudo service jenkins stop

Paso 2: Crear el archivo de copia de seguridad

Navega al directorio principal de $JENKINS_HOME y usa tar para crear un archivo comprimido. Se recomienda excluir los grandes artefactos de compilación para ahorrar espacio y tiempo.

Suponiendo que $JENKINS_HOME es /var/lib/jenkins:

JENKINS_HOME="/var/lib/jenkins"
BACKUP_TARGET="/mnt/backups/jenkins"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
ARCHIVE_NAME="jenkins_backup_${TIMESTAMP}.tar.gz"

# Crear el directorio de destino si no existe
mkdir -p $BACKUP_TARGET

# Crear el archivo, excluyendo el historial de compilaciones y espacios de trabajo
sudo tar -czvf "${BACKUP_TARGET}/${ARCHIVE_NAME}" \
    --exclude="${JENKINS_HOME}/workspace" \
    --exclude="${JENKINS_HOME}/caches" \
    --exclude="${JENKINS_HOME}/jobs/*/builds" \
    "${JENKINS_HOME}"

Consejo: Incluir el historial de compilaciones

Si es crítico conservar el historial de compilaciones (jobs/*/builds), puedes eliminar la bandera --exclude correspondiente. Sin embargo, prepárate para que los tamaños de archivo puedan alcanzar cientos de gigabytes.

Paso 3: Verificar y almacenar fuera del sitio

Una vez creado el archivo, verifica que se pueda leer antes de confiar en él:

tar -tzf "${BACKUP_TARGET}/${ARCHIVE_NAME}" >/dev/null

Luego transfiérelo a una ubicación de almacenamiento externa, como un bucket de S3 o un sistema de respaldo de red, para que una falla de disco local no destruya tanto Jenkins como su copia de seguridad.

Paso 4: Reiniciar Jenkins

sudo systemctl start jenkins

Método 2: Utilizar el complemento de copia de seguridad de Jenkins (Solución parcial)

Si bien existen complementos como ThinBackup o Backup Plugin, a menudo solo capturan archivos de configuración (config.xml) y pueden no manejar archivos grandes o todos los elementos de seguridad necesarios de manera robusta. Generalmente son adecuados para respaldar configuraciones de trabajos solamente y no se debe confiar en ellos para una estrategia completa y segura de recuperación ante desastres.

Restaurando tu instancia de Jenkins

La restauración implica copiar los datos respaldados al directorio $JENKINS_HOME de la máquina de destino y asegurarse de que los permisos de archivos sean correctos antes de iniciar el servicio.

Paso 1: Preparar el entorno de destino

Asegúrate de que el sistema de destino (o el sistema reparado) tenga Jenkins instalado, pero mantén el servicio detenido.

sudo systemctl stop jenkins

Paso 2: Limpiar los datos existentes de Jenkins (Opcional pero recomendado)

Si estás restaurando en una máquina que anteriormente alojaba Jenkins, limpia el contenido existente de $JENKINS_HOME para garantizar un entorno limpio.

# ¡Ten cuidado con el comando 'rm -rf'!
sudo rm -rf /var/lib/jenkins/*

Paso 3: Extraer el archivo de copia de seguridad

Copia el archivo comprimido (jenkins_backup_latest.tar.gz) a la máquina de destino y extráelo en el directorio $JENKINS_HOME. La bandera -C especifica el directorio de destino para la extracción.

# Suponiendo que el archivo está en /tmp y JENKINS_HOME es /var/lib/jenkins
sudo tar -xzvf /tmp/jenkins_backup_latest.tar.gz -C /var/lib/

# Nota: Si el comando tar incluyó el directorio principal en el archivo, ajusta la ruta.
# El resultado debe ser que el contenido del archivo reemplace el contenido de /var/lib/jenkins

Paso 4: Verificar y corregir permisos

Este es el paso más crítico después de la restauración. Si la propiedad del archivo es incorrecta, Jenkins no se iniciará o funcionará de manera insegura. Debes establecer la propiedad de forma recursiva al usuario y grupo bajo los cuales se ejecuta el servicio de Jenkins (a menudo jenkins:jenkins).

JENKINS_HOME="/var/lib/jenkins"
JENKINS_USER="jenkins"
JENKINS_GROUP="jenkins"

sudo chown -R $JENKINS_USER:$JENKINS_GROUP $JENKINS_HOME
sudo find "$JENKINS_HOME" -type d -exec chmod 755 {} \;
sudo find "$JENKINS_HOME" -type f -exec chmod 644 {} \;
sudo chmod -R go-rwx "$JENKINS_HOME/secrets" "$JENKINS_HOME/users" 2>/dev/null || true

Paso 5: Iniciar Jenkins y verificar

Inicia el servicio y monitorea los registros para asegurar un inicio exitoso.

sudo systemctl start jenkins

# Monitorear los registros de inicio
sudo tail -f /var/log/jenkins/jenkins.log

Tras un inicio exitoso, verifica que todos los trabajos, usuarios y complementos instalados estén presentes y funcionando correctamente.

Mejores prácticas para copias de seguridad automatizadas

Para ir más allá de las copias de seguridad manuales, implementa la automatización utilizando herramientas del sistema y gestión de configuración externa.

1. Aprovechar los trabajos de Cron

Programa el script de copia de seguridad (Pasos 1 y 2 del Método 1) para que se ejecute diaria o nocturnamente usando cron o un programador similar. Asegúrate de que el trabajo de cron se ejecute como un usuario con permisos adecuados para detener e iniciar el servicio de Jenkins y leer/escribir en el directorio $JENKINS_HOME.

2. Configuración como Código (CasC)

Considera adoptar la Configuración como Código de Jenkins (CasC). CasC define configuraciones, trabajos y complementos de Jenkins utilizando archivos YAML declarativos. Al almacenar estos archivos YAML en un repositorio de control de versiones separado (como Git), tu configuración se vuelve portátil y versionada, simplificando drásticamente el requisito principal de copia de seguridad.

Conclusión

Trata una copia de seguridad de Jenkins como útil solo después de haber probado una restauración. Un buen plan de recuperación conserva config.xml, jobs/, plugins/, users/, credentials.xml y secrets/, luego verifica que los trabajos puedan ejecutarse en una instancia limpia.

Advertencia: Asegurar las credenciales

Al restaurar una instancia, asegúrate de que el directorio secrets/ esté presente y sea correcto. Si Jenkins no puede encontrar las claves utilizadas para cifrar las credenciales (como claves API o contraseñas), esas credenciales se volverán inutilizables y deberán volver a ingresarse manualmente.