Technology solutions that boost business performance

Contact
MX: Insurgentes Sur 318, Roma Norte
Cuauhtemoc (06700), CDMX, Mexico ARG: Juramento 1475, Piso 12, oficina 8
Belgrano (C14 28DMQ), CABA Argentina
SystemD

¿Cómo iniciar automáticamente un servicio después de un fallo en Linux?

Hay muchas razones para que un proceso se bloquee o caiga en Linux, usted puede investigar y solucionar el problema, pero podría tardar un poco.

Pero una cosa que puede hacer inmediatamente para volver a poner el servicio en línea es arrancar automáticamente cuando se apaga, lo que reduce el tiempo de inactividad para una mejor disponibilidad.

Es muy fácil automatizar esto en sistemas systemd ya que éste tiene opciones para hacerlo, puede realizarse por medio de un script para bash.

¿Qué es systemd?

Systemd fue desarrollado para reemplazar el sistema de inicio heredado de sistemas UNIX, llamado init. Systemd es un conjunto de demonios (daemons) que interactúan con el núcleo del sistema. systemd es el primer proceso que inicia el kernel y mantiene el identificador de proceso (PID) #1. Es un proceso padre para todo y Fedora 15 fue la primer distribución en que se implementó systemd en lugar de upstart.

Para administrar los demonios de systemd existe systemctl, una utilidad de línea de comandos y herramienta primaria de systemd, con la cual se pueden utilizar comandos como inicio, reinicio, parada, activación, desactivación, recarga y estado.

systemd usa archivos «.service» en lugar de scripts bash (usa SysV init). systemd clasifica todos los demonios en sus propios cgroups de Linux y puede ver la jerarquía del sistema explorando el archivo /cgroup/systemd.

Configuración

El archivo de servicio de systemd tiene tres partes principales (Unit, Service e Install). Para comenzar necesitamos agregar los siguientes parámetros requeridos bajo la sección [Service].

[Unit]
...

[Service]
Restart=on-failure
RestartSec=5s
...

[Install]
...

Restart: Configura si el servicio se reiniciará cuando el proceso de servicio salga, se interrumpa o se alcance un tiempo de espera.
on-failure: Al agregarlo, el servicio se reiniciará cuando el proceso salga con un código de salida distinto de cero, se termine con una señal, cuando se agote una operación (como la recarga de servicio) y cuando se active el tiempo de espera configurado.
RestartSec: Configura el tiempo de espera antes de reiniciar un servicio. Toma un valor sin unidades en segundos, o un intervalo de tiempo como “5min 20s”. El valor predeterminado es 100 ms.
5s: Esperará 5 segundos y luego iniciará el servicio.

¿Cómo agregar un parámetro de servicio de inicio automático en el sistema de Systemd?

Es sencillo añadir estos parámetros. Para hacerlo, abra el archivo de servicio correspondiente y añada los siguientes parámetros.

Para explicar esto, se probará el servicio httpd.

# vi /etc/systemd/system/multi-user.target.wants/httpd.service

[Unit]
Description=Apache Web Server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/usr/bin/httpd -k start -DFOREGROUND
ExecStop=/usr/bin/httpd -k graceful-stop
ExecReload=/usr/bin/httpd -k graceful
PrivateTmp=true
LimitNOFILE=infinity
KillMode=mixed
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Es necesario recargar el servicio de demonio una vez que haya realizado los cambios. Puede ver lo mismo ejecutando el comando “systemctl status[httpd]” como se muestra a continuación.

# systemctl status httpd

● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2019-08-05 16:45:24 CDT; 27min ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 14420 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
Main PID: 14424 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─14424 /usr/sbin/httpd -DFOREGROUND
├─14425 /usr/sbin/httpd -DFOREGROUND
├─14426 /usr/sbin/httpd -DFOREGROUND
├─14427 /usr/sbin/httpd -DFOREGROUND
├─14428 /usr/sbin/httpd -DFOREGROUND
└─14429 /usr/sbin/httpd -DFOREGROUND

Aug 05 16:45:23 thvtstrhl7 systemd[1]: Stopped The Apache HTTP Server.
Aug 05 16:45:23 thvtstrhl7 systemd[1]: Starting The Apache HTTP Server...
Aug 05 16:45:24 thvtstrhl7 systemd[1]: Started The Apache HTTP Server.
Warning: httpd.service changed on disk. Run 'systemctl daemon-reload' to reload units.

Para sólo recargar el servicio de demonio:

# systemctl daemon-reload

Se apagará, puede ser verificado ejecutando el siguiente comando una vez más.

# systemctl status httpd

● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2019-08-05 16:45:24 CDT; 27min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 14424 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─14424 /usr/sbin/httpd -DFOREGROUND
├─14425 /usr/sbin/httpd -DFOREGROUND
├─14426 /usr/sbin/httpd -DFOREGROUND
├─14427 /usr/sbin/httpd -DFOREGROUND
├─14428 /usr/sbin/httpd -DFOREGROUND
└─14429 /usr/sbin/httpd -DFOREGROUND

Aug 05 16:45:23 thvtstrhl7 systemd[1]: Stopped The Apache HTTP Server.
Aug 05 16:45:23 thvtstrhl7 systemd[1]: Starting The Apache HTTP Server...
Aug 05 16:45:24 thvtstrhl7 systemd[1]: Started The Apache HTTP Server.

Experimento

Para experimentar lo que recién se hizo, utilice el comando pidof para averiguar el PID de un proceso.

# pidof httpd

14429 14428 14427 14426 14425 14424

Una vez que obtenga la información del PID, sólo hay que matarlos a todos los procesos juntos de una vez con el siguiente comando:

# kill -9 14429 14428 14427 14426 14425 14424

Una vez que haya eliminado el PID de httpd, ejecute el siguiente comando para ver el estado. Está mostrando que el servicio se está reiniciando automáticamente. Pero aún así no está listo.

# systemctl status httpd

● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: activating (auto-restart) (Result: exit-code) since Mon 2019-08-05 17:14:26 CDT; 2s ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 15978 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
Process: 14424 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=killed, signal=KILL)
Main PID: 14424 (code=killed, signal=KILL)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"

Aug 05 17:14:26 thvtstrhl7 systemd[1]: httpd.service: control process exited, code=exited status=1
Aug 05 17:14:26 thvtstrhl7 systemd[1]: Unit httpd.service entered failed state.
Aug 05 17:14:26 thvtstrhl7 systemd[1]: httpd.service failed.

Tras ejecutar el comando anterior una vez más y ver cómo se ven los resultados, sepuede notar que está funcionando ahora tal como se esperaba.

Se inició hace 564 milisegundos.

# systemctl status httpd

● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2019-08-05 17:14:31 CDT; 564ms ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 15978 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
Main PID: 15987 (httpd)
Status: "Processing requests..."
CGroup: /system.slice/httpd.service
├─15987 /usr/sbin/httpd -DFOREGROUND
├─15988 /usr/sbin/httpd -DFOREGROUND
├─15989 /usr/sbin/httpd -DFOREGROUND
├─15990 /usr/sbin/httpd -DFOREGROUND
├─15991 /usr/sbin/httpd -DFOREGROUND
└─15992 /usr/sbin/httpd -DFOREGROUND

Aug 05 17:14:31 thvtstrhl7 systemd[1]: Starting The Apache HTTP Server...
Aug 05 17:14:31 thvtstrhl7 systemd[1]: Started The Apache HTTP Server.

Tal como se pudo observar, systemd se encargó de iniciar un servicio tras una interrupción, en este caso forzado, además, esto mismo se puede hacer para cualquier servicio que se requiera.

Leave a Comment