En una entrega anterior hablamos sobre Systemd, una suite de Linux que se encarga de gestionar y controlar los procesos del sistema. Aprendimos a crear, configurar y ejecutar nuestros scripts a través de ella. Sin embargo ¿Qué pensarías si te dijera que Systemd no es la única herramienta que nos permite realizar estas tareas? Sí, así como lo escuchas. Actualmente en el mercado existe una gran cantidad de opciones que nos permiten gestionar los procesos de nuestro sistema; sin embargo existe una que destaca sobre las demás, sí, me refiero a Supervisor.
Supervisor es una herramienta de gestión que día a día gana más popularidad entre los desarrolladores. Y esto no es de extrañarse, gracias a la gran facilidad de configuración nos ofrece. Es por ello que para este post me gustaría traer un pequeño tutorial sobre como podemos instalar, configurar y gestionar nuestros scripts con estas asombrosa herramienta. 😎
Es un tutorial sumamente interesante, enfocado a todas aquellas personas en el área de DevOps o administración de servidores, así que, si este es tu caso, te invito a que te quedes. 🤗
Bien, como ya es costumbre, una vez dicho todo esto, y sin más dilación, comencemos con el tutorial.
Supervisor
Supervisor, según lo describe la documentación oficial, es un sistema cliente / servidor que permite a sus usuarios monitorear y controlar una serie de procesos en sistemas operativos UNIX._ Perfecto para el despliegue de nuestras aplicaciones. 💻
Para este tutorial lo primero que haremos será instalar Supervisor en nuestros sistema.
Como Supervisor es una herramienta escrita en Python, por lo tanto podemos instalarla utilizando pip, sin embargo para fines prácticos (ya que no todos queremos gestionar proyectos en Python) para este post instalaremos Supervisor como un paquete del sistema.
sudo apt-get install supervisor
Para este tutorial trabajare con el siguiente script.
import time
import datetime
while True:
now = datetime.datetime.now()
print(now.strftime("%b %d %Y %H:%M:%S"))
time.sleep(10)
Un programa en Python que imprime en consola la fecha actual cada 10 segundos. Algo bastante sencillo, sin embargo nos servirá bastante bien.
Ok, lo primero que debemos hacer una vez Supervisor haya sido instalado, será iniciar el servicio.
sudo systemctl start supervisor
Recordemos que Supervisor es un servicio, y como tal, podemos gestionarlo con Systemd. Es algo curioso. 👻
Y por supuesto, si queremos que Supervisor inicie junto con el sistema (Tal como lo vimos en el post anterior) (Y muy recomendable) ejecutamos el siguiente comando.
sudo systemctl enable supervisor
Finalmente, reiniciamos Supervisor.
sudo systemctl restart supervisor
Y para cerciorarnos que todo funcione correctamente, consultamos su status.
sudo service supervisor status
En mi caso todo Ok.
● supervisor.service - Supervisor process control system for UNIX
Loaded: loaded (/lib/systemd/system/supervisor.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-07-29 02:32:37 UTC; 1min 33s ago
Docs: http://supervisord.org
Main PID: 1723 (supervisord)
Tasks: 1 (limit: 1136)
Memory: 14.5M
CGroup: /system.slice/supervisor.service
└─1723 /usr/bin/python3 /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
Lo siguiente que haremos será crear y configurar nuestro archivo .conf.
Ejecutamos el siguiente comando.
sudo nano /etc/supervisor/conf.d/<my file name>.conf
En mi caso el archivo tendrá por nombre pywombat. Por lo tanto mi comando a ejecutar será el siguiente.
sudo nano /etc/supervisor/conf.d/pywombat.conf
Dentro del archivo colocamos:
[program:pywombat]
command=python3 /root/main.py
autostart=true
Como podemos observar el archivo por si solo es muy descriptivo. Definimos el comando que deseamos ejecutar e indicamos que este se ejecute de forma automática cuando supervisor inicie. 🤠
Si queremos ser un poco más robustos en la configuración, podemos añadir un par de atributos más.
[program:pywombat]
command=python3 /root/main.py
autostart=true
autorestart=true
stderr_logfile=/root/pywombat.err.log
stdout_logfile=/root/pywombat.out.log
environment = PYTHONUNBUFFERED=1
Con estos 4 nuevos atributos indicamos que, en caso exista algún tipo de error que impida continuar con el script, este debe reiniciarse de forma automática, y los outputs (Tanto el estándar error como el estándar output) deberán almacenarse en archivos .log Lo cual sin duda es una excelente idea para impresiones en consola. 😉
El atributo environment es necesario para indicarle a Python que desactivamos el buffer, permitiendo así la escritura en el archivo. log.
Por cierto, si quieres manejar de forma correcta las salidas de errores con Python te recomiendo le eches un vistazo al siguiente post.
Una vez nuestro servicio haya sido creado y guardado, lo siguiente será iniciarlo, y para ello usaremos el programa supervisorctl.
Lo primero será notificar a Supervisor que existen nuevos cambios en /etc/supervisor/conf.d (Ruta donde hemos creado nuestro archivo).
supervisorctl reread
Y posteriormente actualizamos y comenzamos el servicio.
supervisorctl update
Aquí hay algo importante a mencionar, el comando reread (re leer) debemos usarlos cuando hayamos registrado un nuevo servicio o actualizado uno, y debemos hacerlo seguido de update, ya que si reiniciamos Supervisor (pensando que con un solo comando será suficiente) los cambios no se verán reflejados. 😮
Así que si creas o actualizar un registros estos 2 comandos son obligatorios.
Finalizamos conozcamos el status de todos los servicios registrados.
supervisorctl status
Si todo ha salido bien, deberíamos ver un mensaje como el siguiente (En mi caso un solo servicio).
pywombat RUNNING pid 1787, uptime 0:00:02
Si por alguna razón el servicio no comenzó, ejecutamos start directamente al servicio.
supervisorctl start pywombat
Perfecto, ya hemos creado nuestro primer servicio son Supervisor. Y si echamos un vistazo a nuestro directorio encontraremos los archivos .logs. 🥳
Detener servicios
Una vez nuestros servicio este en ejecución, algo probable es que deseemos detenerlos, y para ello realizaremos los siguientes pasos.
Primero listar todos los servicios en ejecución,
supervisorctl status
pywombat RUNNING pid 2160, uptime 0:01:20
Una vez sepamos el nombre del servicio a detener utilizamos el comando stop. Para ello tenemos 2 opciones, la primera es hacerlo directamente desde la terminal (Tal y como lo hemos estado haciendo hasta ahora).
supervisorctl stop pywombat
O, la segunda opción es utilizar el modo interactivo de Supervisor para ello ejecutamos supervisorctl en terminal. Para practicar un poco (y ver otro tema) lo hagamos con el modo interactivo.
supervisorctl
pywombat RUNNING pid 2145, uptime 0:00:34
Una vez en el modo interactivo podemos conocer todos los comandos disponibles con help. 🐱
supervisor> help
default commands (type help <topic>):
=====================================
add exit open reload restart start tail
avail fg pid remove shutdown status update
clear maintail quit reread signal stop version
En nuestro caso como deseamos detener el servicio usamos stop.
supervisor> stop pywombat
pywombat: stopped
Echamos nuevamente un vistazo a los status.
supervisor> status
pywombat STOPPED Jul 29 03:21 AM
Perfecto, el servicio se ha detenido.
Y finalmente si queremos re iniciar el servicio usamos el comando restart.
supervisor> restart pywombat
pywombat: ERROR (not running)
pywombat: started
Para salir del modo interactivo quit. 🍇
Conclusión
Si has seguido ambos tutoriales (Tanto este como el de Systemd) sin duda te haz dado cuenta de la gran brecha técnica que existe entre ambas herramientas. Si estas comenzando en el área de administración de servidores sin duda alguna Supervisor es tu mejor opción, sin embargo esto no deja de lado que tengamos que conocer, por lo menos las bases, de Systemd. 🐧