Programar tareas en Systemd con Timer Units

Lo habitual cuando programamos tareas en GNU/Linux es utilizar cron, con permiso de at, para tareas no repetitivas; de ambos ya hemos hablado en la web. Sobre todo, cron sigue siendo el más utilizado, tenga nuestro sistema Systemd u otro sistema como Sysvinit. Aún así los Systemd Timer Units tienen algunos beneficios.

La idea de esta entrada es analizar los «Systemd Timer Units» y en que se diferencian de los trabajos programados con cron. Además, veremos algunos ejemplos de como crear nuestros propios trabajos programados con systemd.

Comparamos Systemd Timer Units versus Cron

Si bien las «Timer Units» se pueden utilizar para programar trabajos similares a cron, existen distintas ventajas y desventajas entre ambos.

Las unidades de tiempo, en inglés «Timer units» de Systemd, son básicamente servicios de systemd y con eso vienen todas sus capacidades, beneficios y también carencias.

Por ejemplo:

  • Las unidades de tiempo se registran en el diario de systemd
  • Permite ejecutar fácilmente un trabajo independiente
  • Pueden ser activadas por eventos como cambios de arranque o en el hardware
  • Permiten usar tiempo real o tiempo monotónico.

Cron tiene dos grandes ventajas sobre los «Timer units» de Systemd:

  • Configurar trabajos en cron es bastante simple
  • Cron es capaz de enviar correos electrónicos utilizando la función de “MAILTO”

Crear nuestro primero Timer Unit

En esta sección, crearemos una «Timer unit» para hacer una copia de seguridad del directorio de  una web, y luego cada 24 horas mientras el sistema esté funcionando. Para crear una nueva unidad, necesitamos tres elementos:

  • Guión o script para la unidad del servicio a ejecutar
  • El fichero para la unidad de servicio (Service unit)
  • El fichero para la unidad de tiempo (Timer unit)

Creamos el script de copia de seguridad con rsync

Elaboramos un script con el siguiente contenido:

  1. #!/bin/bash
  2. rsync -av /var/www/html /backup/copia-$(date +"%d%m%Y")

Lo guardamos en /usr/local/bin, le otorgamos permisos de ejecución:

  1. chmod +x /usr/local/bin/mi-backup.sh

Podemos probarlo, tal y como se muestra en el ejemplo:

  1. david@servubuntu01:~$ sudo bash -x /usr/local/bin/mi-backup.sh
  2. ++ date +%d%m%Y
  3. + rsync -av /var/www/html /backup/copia-03072019
  4. sending incremental file list
  5. html/
  6. html/index.html
  7. html/index.nginx-debian.html
  8. html/info.php
  9.  
  10. sent 11,820 bytes  received 77 bytes  23,794.00 bytes/sec
  11. total size is 11,552  speedup is 0.9

Si os interesa también hacer copia de seguridad de la base de datos, en el caso de utilizar WordPress, por ejemplo, podéis hacer lo propio, creando un script con ayuda del artículo que escribí en su día, sobre la programación de copias de seguridad en MySQL y MariaDB

Creamos un nuevo Service Unit File que ejecute el script

La nueva unidad de servicio “Service Unit File” será responsable de ejecutar el script en systemd. En este ejemplo, crearemos la unidad de servicio con una configuración básica.

Creamos un archivos llamado mi-backup.service en la ubicación /etc/systemd/system/ con el siguiente contenido:

  1. [Unit]
  2. Description="Guión que realiza copia de seguridad diaria del contenido web"
  3.  
  4. [Service]
  5. ExecStart=/usr/local/bin/mi-backup.sh

Creamos un nuevo Timer Unit File

El último archivo necesario es el archivo de tiempo, eso es, «Timer Unit File«, que define cuándo se debe ejecutar el servicio. Este fichero se coloca en el mismo directorio que el archivo de servicio correspondiente. Debe tener el mismo nombre, pero con una extensión «.timer»

Creamos el archivo llamado mi-backup.timer en la ubicación /etc/systemd/system/, con el
contenido:

  1. [Unit]
  2. Description="Backup del contenido web"
  3.  
  4. [Timer]
  5. OnBootSec=3min
  6. OnUnitActiveSec=24h
  7. Unit=mi-backup.service
  8.  
  9. [Install]
  10. WantedBy=multi-user.target

El parámetro «OnBootSec«, indica el tiempo de espera después del arranque. «OnUnitActive» define el tiempo relativo a la última que se activó la unidad. «WantedBy» básicamente establece una dependencia que hace que nuestra unidad de tiempo «Timer Unit file«, comience cuando se inicia la unidad nombrada.

Verificar la sintaxis de las Unit Files

Podemos utilizar el comando «systemd-analyse» para verificar que el contenido de unidad. Esto nos ayudará a comprobar los posibles problemas de sintaxis.

  1. sudo systemd-analyze verify /etc/systemd/system/mi-backup.*

Si no se devuelve nada, entonces el fichero es correcto y no tiene fallos.

Iniciar nuestro systemd Timer

Podemos iniciar el systemd Timer utilizando systemctl

  1. sudo systemctl start mi-backup.timer

Añadir un nuevo systemd Timer al arranque

Al igual que cualquier servicio incluido Systemd, para añadirlo solo hemos de escribir:

  1. sudo systemctl enable mi-backup.timer

Arrancar de manera manual el job

También existe la posibilidad de ejecutar el servicio creado, de forma manual. Tal y como se muestra en el ejemplo:

  1. sudo systemctl start mi-backup.timer

Una vez en funcionamiento, podemos por su estado:

  1. root@servubuntu01:~# systemctl status mi-backup.timer
  2. ● mi-backup.timer - "Backup del contenido web"
  3.    Loaded: loaded (/etc/systemd/system/mi-backup.timer; disabled; vendor preset:
  4.    Active: active (waiting) since Wed 2019-07-03 22:25:40 CEST; 6s ago
  5.   Trigger: Thu 2019-07-04 22:25:40 CEST; 23h left
  6.  
  7. jul 03 22:25:40 servubuntu01 systemd[1]: Started "Backup del contenido web".

Añadir al arranque

Además lo vamos a añadir, para que cuando se reinicie el host, este añadido al inicio:

  1. root@servubuntu01:~# systemctl enable mi-backup.timer
  2. Created symlink /etc/systemd/system/multi-user.target.wants/mi-backup.timer → /etc/systemd/system/mi-backup.timer

Ver el Sytemd Timer Logs con Journalctl

De Journalctl ya hemos hablado. Lo podemos utilizar para ver los registros:

  1. david@servubuntu01:~$ sudo journalctl -u mi-backup
  2. [sudo] contraseña para david:
  3. -- Logs begin at Mon 2019-06-17 20:09:35 CEST, end at Wed 2019-07-03 22:36:35 CE
  4. jul 03 22:25:40 servubuntu01 systemd[1]: Started "Guión que realiza copia de seg
  5. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: sending incremental file list
  6. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: sent 136 bytes  received 17 by
  7. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: total size is 11,552  speedup
  8. lines 1-5/5 (END)...skipping...
  9. -- Logs begin at Mon 2019-06-17 20:09:35 CEST, end at Wed 2019-07-03 22:36:35 CEST. --
  10. jul 03 22:25:40 servubuntu01 systemd[1]: Started "Guión que realiza copia de seguridad diaria del contenido web
  11. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: sending incremental file list
  12. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: sent 136 bytes  received 17 bytes  306.00 bytes/sec
  13. jul 03 22:25:40 servubuntu01 mi-backup.sh[26816]: total size is 11,552  speedup is 75.50

Y esto es todo, espero que la entrada os haya parecido interesante.

Fuentes consultadas:

Putorius.net – Using systemd Timer Units to Schedule Jobs