Automatiza la ejecución de scripts en Proxmox

Apaga y enciende máquinas por consola, de manera automática y mucho más

Imagen de un botón de Start/Stop de un automóvil
Photo by Michael Lock / Unsplash

Según ha ido creciendo mi servidor de Proxmox, he ido añadiendo nodos al Datacenter y me he visto en la necesidad de empezar a mantener copias de seguridad de las máquinas virtuales y los contenedores LXC, con el fin de poder restaurarlos en caso de que alguno fallara.

Una de las maneras que tengo de hacer dichas copias de seguridad es sobre un disco duro conectado al router, y otra montando un sistema PBS (Proxmox Backup Server) en Tuxis, con la cuenta gratuita (que, de momento, me sirve más que de sobra con esos 150GB que me dan). Pero esto me llevó a plantearme otra cuestión: ¿Por qué no tener mi propio PBS en local? Y dicho y hecho... monté mi propio PBS como una máquina virtual más dentro de uno de los nodos de Proxmox, y como sistema de almacenamiento, utilicé el NAS mediante NFS, para añadir un poco de redundancia a los datos y porque el nodo como tal no tiene tanta capacidad de almacenamiento (sobre cómo lo hice tengo pendiente hacer una entrada en el blog).

Os pongo en situación

El problema que me surgió aquí fue que, como actualmente tengo el NAS en el salón y es relativamente ruidoso, no lo tengo encendido siempre, sino que lo arranco cuando me es necesario y los fines de semana. Y claro, estar haciendo eso constantemente sólo para lanzar copias de seguridad es un poco... peñazo, no nos vamos a engañar.

En base a los sistemas de copias de seguridad que tengo, me era más que suficiente con lanzar una copia semanal sobre mi PBS local, así que aproveché que los fines de semana se arranca solo para hacer que mi PBS también lo hiciera, se dispararan las copias de seguridad, se actualizara, etc. y después se apagara solo el resto de la semana, pues así ahorro recursos para el resto de las máquinas y no le afecta si el NAS está apagado.

Con este planteamiento, fue como descubrí el sistema de servicios y contadores de systemd, ya que tradicionalmente es algo que habría hecho con un simple cron, pero que aproveché para descubrir cómo funcionaba, y aquí os lo explico, usando como ejemplo el caso de uso que quiero hacer: Arrancar y detener automáticamente una máquina virtual de Proxmox.

Diferencias entre cron y timer de systemd

Podría explayarme en este apartado, pero me limitaré a dejaros una tabla comparativa con las ventajas de timer en systemd frente a cron:

Característica

systemd-timer

cron

Gestión unificada con servicios

Sí, puedes enlazar directamente con .service

No, necesitas scripts o llamadas externas

Logs integrados (journalctl)

No (solo mails o redirecciones manuales)

Dependencias y condiciones

Sí (After=, Requires=, ConditionPathExists=, etc.)

No

Control fino (OnBootSec, OnActiveSec)

Sí (más expresivo que cron)

No

Temporizadores persistentes

Sí (Persistent=true)

No (si la máquina está apagada, se salta)

Paralelismo y aislamiento

Mejor control (cgroups, user permissions, etc.)

Limitado

Visto eso, ¿cuándo deberíamos usar uno u otro entonces?

Usa systemd-timer si:

  • Tu sistema ya usa systemd (casi todos hoy).
  • Quieres mejor visibilidad y control.
  • La tarea es importante o crítica (backups, reinicios de servicios, mantenimientos…).

Usa cron si:

  • Solo necesitas una ejecución rápida y simple.
  • No te importa el logging ni el control del entorno.
  • Es un script heredado o mantenido en sistemas heterogéneos.

En mi caso, como es un sistema moderno que ya lo tiene, va a ser una tarea importante (levantar el servidor de copias de seguridad para que Proxmox pueda usarlo), opté por la primera opción.

Configurar un servicio en systemd

El primer paso será crear el script que queramos ejecutar y hacerlo ejecutable, valga la redundancia, mediante chmod +x /ruta/al/script.sh. Una vez lo tenemos, podemos crear el servicio.

Como levantar o parar una máquina en Proxmox es un comando muy sencillo, en lugar de crear un script para ello vamos a invocar directamente al comando, por lo que lo haremos directamente creando un fichero start-pbs.service en la ruta /etc/systemd/system con el siguiente contenido:

[Unit]
Description=Iniciar PBS (VM 100)
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/qm start 100

Contenido del servicio start-pbs.service

En el ejemplo de arriba, lo estoy haciendo para la máquina con ID 100, pero deberéis poner el que corresponda con la vuestra (OBVIAMENTE).

Configurar un temporizador (timer) en systemd

Una vez tenemos el servicio creado, es hora de crear el temporizador que lo ejecutará automáticamente. De nuevo, en la misma ruta /etc/systemd/system crearemos un fichero llamado start-pbs.timer y le añadiremos lo siguiente:

[Unit]
Description=Temporizador para iniciar PBS (VM 100) todos los sabados a las 7:00 AM

[Timer]
OnCalendar=Sat 07:00:00
Persistent=true

[Install]
WantedBy=timers.target

Contenido del temporizador start-pbs.timer

En este caso, se ejecutará todos los sábados a las 7 de la mañana, puesto que tengo configurado el backup de Proxmox a eso de las 7 y media (de forma que dejo bastante margen... manías mías). La forma de especificar los tiempos es muy potente, hasta el punto de poder definir expresiones como OnCalendar=Mon,Tue *-*-01..04 12:00:00, la cual indica que se disparará los días del 1 al 4 de cada mes a las 12 del mediodía sólo si caen en lunes o martes. En función de vuestra necesidad, os aconsejo buscar en internet o preguntarle a alguna IA cómo debería escribirse (ya que meternos en ese jardín da para un par de entradas mínimo).

En cuanto a la opción Persistente=true nos garantizará que, si por lo que fuera, en ese momento la máquina estuviera apagada, en cuanto arrancara nos lanzaría el servicio.

Por otro lado, es recomendable (y una buena práctica) que tanto el servicio como el temporizador tengan el mismo nombre (en nuestro caso, start-pbs.*). Si bien no es obligatorio, nos evita tener que especificar en el temporizador, dentro de [Timer] el servicio que debe invocar (mediante Unit=start-pbs.service).

Activar el temporizador

Una vez tenemos todo listo, deberemos recargar systemd para que registre los nuevos servicios y temporizadores creados. Para ello, bastará con ejecutar systemctl daemon-reexec o systemctl daemon-reload si no hemos reiniciado systemd como tal.

A continuación, ejecutaremos systemctl enable --now start-pbs.timer para habilitar el temporizador y que empiece a tenerse en cuenta para la próxima ejecución.

Para verificar el estado, podemos lanzar systemctl list-timers | grep start-pbs y nos mostrará algo como:

Sat 2025-08-09 07:00:00 CEST 2 days left   Sat 2025-08-02 07:00:08 CEST 4 days ago   start-pbs.timer              start-pbs.service

Verificación de que el temporizador está correctamente configurado

Como veis, en mi caso, me indica que se ejecutó por última vez el pasado sábado, que la próxima ejecución será en 2 días y que lanzó el servicio correcto. Si quisiera verificar los logs del servicio, bastaría con journalctl -u start-pbs.service para visualizarlos.

Lanzar el servicio sin esperar al temporizador

Por último, si queremos ejecutar el servicio sin necesidad de esperar al temporizador (bien porque queremos probarlo, bien porque tenemos una forma de invocarlo de manera asíncrona para ejecutarlo cuando lo necesitemos), es tan fácil como lanzar sudo systemctl start start-pbs.service y veremos cómo la máquina virtual se arranca en el momento.

Y con esto, podemos automatizar no sólo la ejecución de scripts en Proxmox, sino que también dentro de las máquinas virtuales, o preparar servicios que pueden ser arrancados tras invocar un bot de Telegram, por ejemplo. Tan flexible o más que un cron y más robusto.

¡Y hasta aquí esta entrada! Espero que os sea de utilidad o que, al menos, os descubra algo nuevo, como me pasó a mí.

Si te ha gustado la entrada, o te ha sido útil y quieres ayudarme a pagar los gastos que conlleva el servidor y mantener así el blog libre completamente de anuncios, puedes hacer una donación pulsando sobre el siguiente botón: