Nadie consideraría realmente a systemd como una herramienta de solución de problemas, pero cuando encontré un problema en mi servidor web, mi creciente conocimiento de systemd y algunas de sus funciones me ayudaron a localizar y sortear el problema.
El problema era que mi servidor, yorktown, que brinda servicios de nombres, DHCP, NTP, HTTPD y servicios de correo electrónico SendMail para la red de mi oficina en casa, no pudo iniciar el demonio Apache HTTPD durante el inicio normal. Tuve que iniciarlo manualmente después de darme cuenta de que no estaba funcionando. El problema había estado ocurriendo durante algún tiempo y recientemente intenté solucionarlo.
Algunos de ustedes dirán que systemd en sí mismo es la causa de este problema y, según lo que sé ahora, estoy de acuerdo con usted. Sin embargo, tuve problemas similares con SystemV. (En el primer artículo de esta serie, analicé la controversia en torno a systemd como reemplazo del antiguo programa de inicio SystemV y los scripts de inicio. Si está interesado en obtener más información sobre systemd, lea también el segundo y el tercer artículo). Ningún software es perfecto, y ni systemd ni SystemV son una excepción, pero systemd brinda mucha más información para la resolución de problemas de la que jamás haya ofrecido SystemV.
Determinando el problema
El primer paso para encontrar el origen de este problema es determinar el estado del servicio httpd:
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Thu 2020-04-16 11:54:37 EDT; 15min ago
Docs: man:httpd.service(8)
Process: 1101 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 1101 (code=exited, status=1/FAILURE)
Status: "Reading configuration..."
CPU: 60ms
Apr 16 11:54:35 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 11:54:37 yorktown.both.org httpd[1101]: (99)Cannot assign requested address: AH00072: make_sock: could not bind to address 192.168.0.52:80
Apr 16 11:54:37 yorktown.both.org httpd[1101]: no listening sockets available, shutting down
Apr 16 11:54:37 yorktown.both.org httpd[1101]: AH00015: Unable to open logs
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Failed with result 'exit-code'.
Apr 16 11:54:37 yorktown.both.org systemd[1]: Failed to start The Apache HTTP Server.
[root@yorktown ~]#
Esta información de estado es una de las características de systemd que encuentro mucho más útil que cualquier cosa que ofrezca SystemV. La cantidad de información útil aquí me lleva fácilmente a una conclusión lógica que me lleva en la dirección correcta. Todo lo que obtuve del viejo chkconfig El comando es si el servicio se está ejecutando o no y el ID del proceso (PID) si es así. Eso no es muy útil.
La entrada clave en este informe de estado muestra que HTTPD no puede vincularse a la dirección IP, lo que significa que no puede aceptar solicitudes entrantes. Esto indica que la red no se está iniciando lo suficientemente rápido como para estar lista para que el servicio HTTPD se vincule a la dirección IP porque la dirección IP aún no se ha configurado. Se supone que esto no debe suceder, así que exploré los archivos de configuración de inicio de systemd de mi servicio de red; todo parecía estar correcto con las declaraciones correctas "después" y "requiere". Aquí está el /lib/systemd/system/httpd.service archivo de mi servidor:
# Modifying this file in-place is not recommended, because changes
# will be overwritten during package upgrades. To customize the
# behaviour, run "systemctl edit httpd" to create an override unit.
# For example, to pass additional options (such as -D definitions) to
# the httpd binary at startup, create an override unit (as is done by
# systemctl edit) and enter the following:
# [Service]
# Environment=OPTIONS=-DMY_DEFINE
[Unit]
Description=The Apache HTTP Server
Wants=httpd-init.service
After=network.target remote-fs.target nss-lookup.target httpd-init.service
Documentation=man:httpd.service(8)
[Service]
Type=notify
Environment=LANG=C
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true
[Install]
WantedBy=multi-user.target
El servicio httpd. unit especifica explícitamente que debe cargarse después de network.target y el httpd-init.service (entre otros). Traté de encontrar todos estos servicios usando las unidades de lista systemctl comando y buscándolos en el flujo de datos resultante. Todos estaban presentes y deberían haberse asegurado de que el servicio httpd no se cargara antes de configurar la dirección IP de la red.
Primera solución
Más sobre administradores de sistemas
- Habilitar el blog de administrador del sistema
- La empresa automatizada:una guía para administrar TI con automatización
- Libro electrónico:Automatización de Ansible para administradores de sistemas
- Historias del campo:una guía del administrador de sistemas para la automatización de TI
- eBook:Una guía de Kubernetes para SRE y administradores de sistemas
- Últimos artículos de administrador de sistemas
Un poco de búsqueda en Internet confirmó que otros habían encontrado problemas similares con httpd y otros servicios. Esto parece suceder porque uno de los servicios requeridos le indica a systemd que ha finalizado su inicio, pero en realidad genera un proceso secundario que no ha finalizado. Después de buscar un poco más, se me ocurrió una elusión.
No podía entender por qué la dirección IP tardaba tanto en asignarse a la tarjeta de interfaz de red. Entonces, pensé que si podía retrasar el inicio del servicio HTTPD por una cantidad de tiempo razonable, la dirección IP estaría asignada en ese momento.
Afortunadamente, el /lib/systemd/system/httpd.service El archivo anterior proporciona alguna dirección. Aunque dice que no lo alteres, sí indica cómo proceder:Usa el comando systemctl edit httpd , que crea automáticamente un nuevo archivo (/etc/systemd/system/httpd.service.d/override.conf ) y abre el editor GNU Nano. (Si no está familiarizado con Nano, asegúrese de mirar las sugerencias en la parte inferior de la interfaz de Nano).
Agregue el siguiente texto al nuevo archivo y guárdelo:
[root@yorktown ~]# cd /etc/systemd/system/httpd.service.d/
[root@yorktown httpd.service.d]# ll
total 4
-rw-r--r-- 1 root root 243 Apr 16 11:43 override.conf
[root@yorktown httpd.service.d]# cat override.conf
# Trying to delay the startup of httpd so that the network is
# fully up and running so that httpd can bind to the correct
# IP address
#
# By David Both, 2020-04-16
[Service]
ExecStartPre=/bin/sleep 30
El [Servicio] La sección de este archivo de anulación contiene una sola línea que retrasa el inicio del servicio HTTPD en 30 segundos. El siguiente comando de estado muestra el estado del servicio durante el tiempo de espera:
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/httpd.service.d
└─override.conf
/usr/lib/systemd/system/httpd.service.d
└─php-fpm.conf
Active: activating (start-pre) since Thu 2020-04-16 12:14:29 EDT; 28s ago
Docs: man:httpd.service(8)
Cntrl PID: 1102 (sleep)
Tasks: 1 (limit: 38363)
Memory: 260.0K
CPU: 2ms
CGroup: /system.slice/httpd.service
└─1102 /bin/sleep 30
Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.
[root@yorktown ~]#
Y este comando muestra el estado del servicio HTTPD después de que expire el retraso de 30 segundos. El servicio está funcionando correctamente:
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/httpd.service.d
└─override.conf
/usr/lib/systemd/system/httpd.service.d
└─php-fpm.conf
Active: active (running) since Thu 2020-04-16 12:15:01 EDT; 1min 18s ago
Docs: man:httpd.service(8)
Process: 1102 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
Main PID: 1567 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec: 0 B/sec"
Tasks: 213 (limit: 38363)
Memory: 21.8M
CPU: 82ms
CGroup: /system.slice/httpd.service
├─1567 /usr/sbin/httpd -DFOREGROUND
├─1569 /usr/sbin/httpd -DFOREGROUND
├─1570 /usr/sbin/httpd -DFOREGROUND
├─1571 /usr/sbin/httpd -DFOREGROUND
└─1572 /usr/sbin/httpd -DFOREGROUND
Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.
Podría haber experimentado para ver si un retraso más corto también funcionaría, pero mi sistema no es tan crítico, así que decidí no hacerlo. Funciona de manera confiable tal como está, así que estoy feliz.
Debido a que recopilé toda esta información, la informé a Red Hat Bugzilla como Error 1825554. Creo que es mucho más productivo informar errores que quejarse de ellos.
La mejor solución
Un par de días después de informar esto como un error, recibí una respuesta que indica que systemd es solo el administrador, y si es necesario ordenar httpd después de cumplir algunos requisitos, debe expresarse en el archivo de la unidad. La respuesta me dirigió al httpd.service página de manual Desearía haber encontrado esto antes porque es una solución mejor que la que se me ocurrió. Esta solución está dirigida explícitamente a la unidad de destino de requisitos previos en lugar de un retraso un tanto aleatorio.
Desde el httpd.service página man:
Iniciar el servicio en el momento del arranque
Las unidades httpd.service y httpd.socket están deshabilitadas por defecto. Para iniciar el servicio httpd en el momento del arranque, ejecute:systemctl enable httpd.service . En la configuración predeterminada, el demonio httpd aceptará conexiones en el puerto 80 (y, si mod_ssl está instalado, conexiones TLS en el puerto 443) para cualquier dirección IPv4 o IPv6 configurada.
Si httpd está configurado para depender de una dirección IP específica (por ejemplo, con una directiva "Escuchar") que solo puede estar disponible durante el inicio, o si httpd depende de otros servicios (como un demonio de base de datos), el servicio debe configurarse para garantizar un orden de inicio correcto.
Por ejemplo, para garantizar que httpd solo se ejecute después de configurar todas las interfaces de red configuradas, cree un archivo desplegable (como se describe anteriormente) con la siguiente sección:
[Unidad]
Después=red-online.objetivo
Deseos=red-online.objetivo
Sigo pensando que esto es un error porque es bastante común, al menos en mi experiencia, usar un Escuchar directiva en httpd.conf archivo de configuración. Siempre he usado Escuchar directivas, incluso en hosts con una sola dirección IP, y es claramente necesario en hosts con múltiples tarjetas de interfaz de red (NIC) y direcciones de protocolo de Internet (IP). Agregando las líneas anteriores al /usr/lib/systemd/system/httpd.service archivo predeterminado no causaría problemas para las configuraciones que no usan un Escuchar directiva y evitaría este problema para aquellos que lo hacen.
Mientras tanto, usaré la solución sugerida.
Próximos pasos
Este artículo describe un problema que tuve al iniciar el servicio Apache HTTPD en mi servidor. Lo guía a través de los pasos de determinación de problemas que tomé y muestra cómo usé systemd para ayudar. También cubrí la elusión que implementé usando systemd y la mejor solución que siguió de mi informe de errores.
Como mencioné al principio, es muy probable que esto sea el resultado de un problema con systemd, específicamente la configuración para el inicio de httpd. Sin embargo, systemd me proporcionó las herramientas para localizar el origen probable del problema y para formular e implementar una elusión. Ninguna solución realmente resuelve el problema a mi entera satisfacción. Por ahora, la causa raíz del problema aún existe y debe solucionarse. Si eso es simplemente agregar las líneas recomendadas a /usr/lib/systemd/system/httpd.service archivo, eso funcionaría para mí.
Una de las cosas que descubrí durante este proceso es que necesito aprender más sobre cómo definir las secuencias en las que comienzan las cosas. Exploraré eso en mi próximo artículo, el quinto de esta serie.
Recursos
Hay una gran cantidad de información sobre systemd disponible en Internet, pero mucha es concisa, obtusa o incluso engañosa. Además de los recursos mencionados en este artículo, las siguientes páginas web ofrecen información más detallada y confiable sobre el inicio de systemd.
- El Proyecto Fedora tiene una buena guía práctica para systemd. Tiene prácticamente todo lo que necesita saber para configurar, administrar y mantener una computadora Fedora usando systemd.
- El Proyecto Fedora también tiene una buena hoja de trucos que hace una referencia cruzada de los comandos antiguos de SystemV con los de systemd comparables.
- Para obtener información técnica detallada sobre systemd y las razones para crearlo, consulte la descripción de systemd de Freedesktop.org.
- "More systemd fun" de Linux.com ofrece información y consejos más avanzados sobre systemd.
También hay una serie de artículos profundamente técnicos para administradores de sistemas Linux escritos por Lennart Poettering, el diseñador y desarrollador principal de systemd. Estos artículos fueron escritos entre abril de 2010 y septiembre de 2011, pero son tan relevantes ahora como lo fueron entonces. Gran parte de todo lo bueno que se ha escrito sobre systemd y su ecosistema se basa en estos documentos.
- Repensar el PID 1
- systemd para administradores, Parte I
- systemd para administradores, Parte II
- systemd para administradores, Parte III
- systemd para administradores, Parte IV
- systemd para administradores, Parte V
- systemd para administradores, Parte VI
- systemd para administradores, Parte VII
- systemd para administradores, Parte VIII
- systemd para administradores, Parte IX
- systemd para administradores, Parte X
- systemd para administradores, Parte XI