CentOS 7 arranca demasiado rápido y la red no está lista al ejecutar scripts cron

9

Acabo de actualizar de CentOS 6.5 a 7.0 y no estoy muy contento ya que la nueva systemdprobablemente me está dando problemas. Parece que simplemente se está iniciando demasiado rápido, iniciando los procesos de forma asincrónica y arruinando las dependencias del servicio.

Por ejemplo, tengo algunas configuraciones de scripts crondque se activan después de un reinicio:

@reboot    /root/scripts/check_gmail.sh
@reboot    /root/scripts/start_gps_listener.sh

Esto da como resultado todo tipo de errores extraños (solo muestra uno de ellos):

Warning: stream_socket_client(): unable to connect to tcp://192.168.20.4:4001 
  (Network is unreachable) in /root/scripts/check_gmail.php on line 137
  ERROR: Network is unreachable (101)

En lo anterior, estoy escribiendo en un socket TCP. Para mí es bastante claro que crondse inicia antes de que la red se inicialice correctamente como network is unreachable.

Lo mismo ocurre con Apache y MySQL (MariaDB). MySQL es bastante lento para el inicio (muchos datos), lo que significa que tanto Apache como muchos de mis crondscripts de inicio están fallando ya que la base de datos MySQL no se está ejecutando cuando se llaman los scripts.

He intentado configurar dependencias pero sin suerte; He agregado networky mysqlservicios a [Unit](como se ve con systemctl list-dependencies). Idealmente, todos los servicios esperan hasta que MySQL esté en funcionamiento:

vi /lib/systemd/system/httpd.service
  [Unit]
  Description=The Apache HTTP Server
  After=network.target remote-fs.target nss-lookup.target network.service mysql.service

vi /lib/systemd/system/crond.service
  [Unit]
  Description=Command Scheduler
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.service mysql.service

Al arrancar con lo anterior, obtengo los mismos errores. También recibo los correos electrónicos mailqya que la red / DNS no está lista al procesar cron-scripts. Unos minutos después del inicio, se envían correctamente.

¿Alguien puede ayudar a hacer esto bien asegurándose de que los servicios se activen en el orden correcto? Parece muy incorrecto que sea un arranque tan rápido e idealmente lo hizo de la manera tradicional, "lanzando un servicio ... espera ... lanzando un nuevo servicio ... espera ... etc.".

Tenga en cuenta que no estoy seguro de que systemdese sea mi problema, es solo mi teoría de lo que puedo leer de la red.

DHS
fuente
¿Podría publicar la salida de grep -i concurrency /etc/default/rcS? Puede que esté mezclando mis sistemas de inicio, pero parece recordar que controla si los procesos esperan el uno al otro para terminar.
terdon
No tengo archivos con/etc/default/rc*
DHS
Lo siento, no sé dónde estaría el equivalente de CentOS. Estaba pensando en lo que se describe aquí para Debian, que hace que los servicios comiencen en paralelo. Puede haber algo similar en su caso.
terdon
2
Intenta agregar Requires=network.targeta las unidades de arriba.
casey
Sigue siendo el mismo problema después de insertado Requires=network.targeten/lib/systemd/system/crond.service
DHS

Respuestas:

9

Después de leer mucho más, encontré la solución que me funciona.

Leí esta guía, Servicios en ejecución después de que la red esté activa . Una pequeña cita de la guía:

Esto asegurará que todos los dispositivos de red configurados estén activos y tengan una dirección IP asignada antes de que continúe el arranque.

Esto es exactamente lo que quería, así que habilité este servicio y configuré una regla de dependencia en el archivo de servicio para crond:

[root@srv]# systemctl enable NetworkManager-wait-online

[root@srv]# vi /lib/systemd/system/crond.service
  Requires=network.target
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.target mysqld.service

Como mysqldtodavía se basa en lo antiguo init.dque necesitaba para crear un systemdservicio como se sugiere aquí, systemctl enable difiere de systemctl start :

[root@srv]# vi /lib/systemd/system/mysqld.service
  [Unit]
  Description=MySQL Server
  After=network.target
  [Service]
  Type=forking
  ExecStart=/etc/rc.d/init.d/mysql start
  ExecStop=/etc/rc.d/init.d/mysql stop
  [Install]
  WantedBy=multi-user.target

[root@srv]# systemctl daemon-reload
[root@srv]# chkconfig mysql off
[root@srv]# systemctl enable mysqld

Y finalmente configure el servicio Apache para iniciar después de MySQL:

[root@srv]# vi /lib/systemd/system/httpd.service
  Requires=mysqld.service
  After=network.target remote-fs.target nss-lookup.target mysqld.service

Esto funciona para mí al menos.

He usado estos comandos para verificarlo luego, donde claramente puedo ver que la red se inicia antes de al menos MySQL y Apache. Aunque no puedo ver el crondsitio, pero puedo ver que funciona en mis scripts:

[root@srv]# systemd-analyze critical-chain
  multi-user.target @10.510s
    + httpd.service @10.344s +165ms
      + mysqld.service @9.277s +1.065s
        + network.target @9.273s
          + network.service @8.917s +355ms
            + iptables.service @444ms +157ms
              + basic.target @443ms
                [CUT]

Algunos otros comandos útiles que utilicé son:

# See exactly what takes how long (who to blame for the delay)
[root@srv]# systemd-analyze blame

# Check available names that can be used in the service files
[root@srv]# systemctl list-unit-files

Si alguien puede ver una mejor manera de hacer esto, por favor comparta.

DHS
fuente
+1 para publicar los comandos que usó para depurar esto. Pude resolver un montón de problemas realmente desagradables systemd-analyze critical-chain. No solo voy a usar eso a menudo, sino que de repente me venden systemd. ¡Gracias!
Brian Topping
No debe modificar los archivos de servicios administrados por su administrador de paquetes de distribución. En su lugar, será mejor que use archivos de configuración desplegables. Consulte la respuesta a ¿Cómo anulo o configuro los servicios systemd?
Ludovic Ronsin el