CentOS 7 uruchamia się zbyt szybko, a sieć nie jest gotowa do wykonywania skryptów cron

9

Właśnie zaktualizowałem CentOS 6.5 do 7.0 i nie jestem zbyt szczęśliwy, ponieważ nowy systemdprawdopodobnie przysparza mi problemów. Wygląda na to, że po prostu uruchamia się zbyt szybko, asynchronicznie uruchamia procesy i psuje zależności serwisowe.

Na przykład mam kilka skryptów, w crondktórych uruchamiane są po restarcie:

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

Powoduje to wszelkiego rodzaju dziwne błędy (pokazujące tylko jeden z nich):

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)

W powyższym piszę do gniazda TCP. Jest dla mnie całkiem jasne, że crondjest uruchamiany zanim sieć zostanie poprawnie zainicjowana jako network is unreachable.

To samo dotyczy Apache i MySQL (MariaDB). MySQL uruchamia się dość wolno (dużo danych), co oznacza, że ​​zarówno Apache, jak i wiele moich crondskryptów startowych zawodzi, ponieważ baza danych MySQL nie działa podczas wywoływania skryptów.

Próbowałem skonfigurować zależności, ale bez powodzenia; Dołączyłem networki mysqlusługi [Unit](jak widać z systemctl list-dependencies). Idealnie wszystkie usługi czekają na uruchomienie MySQL:

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

Podczas uruchamiania przy użyciu powyższego otrzymuję te same błędy. Dostaję również e-maile, mailqponieważ sieć / DNS nie jest gotowa podczas przetwarzania skryptów cron. Kilka minut po uruchomieniu są wysyłane poprawnie.

Czy ktoś może pomóc w uzyskaniu tego, upewniając się, że usługi są uruchamiane we właściwej kolejności? Wydaje się bardzo błędne, że tak szybko się uruchamia i idealnie zrobił to po staremu, „uruchamiając jedną usługę ... czekaj ... uruchamiając nową usługę ... czekaj ... itd.).

Zauważ, że nie jestem pewien, czy to jest systemdmój problem - to tylko moja teoria tego, co mogę czytać z sieci.

DHS
źródło
Czy możesz opublikować wynik grep -i concurrency /etc/default/rcS? Być może mieszam swoje systemy inicjujące, ale wydaje mi się, że pamiętam, że kontroluje to, czy procesy będą czekać na zakończenie innych.
terdon
Nie mam plików z/etc/default/rc*
DHS
Przepraszam, nie wiem, gdzie byłby odpowiednik CentOS. Myślałem o tym, co opisano tutaj dla Debiana, który sprawia, że ​​usługi zaczynają się równolegle. W twoim przypadku może być coś podobnego.
terdon
2
Spróbuj dodać Requires=network.targetdo powyższych jednostek.
casey
Wciąż ten sam problem po wstawieniu Requires=network.targetdo/lib/systemd/system/crond.service
DHS

Odpowiedzi:

10

Po dużo więcej lekturach znalazłem rozwiązanie, które działa dla mnie.

Przeczytałem ten przewodnik: Uruchamianie usług po uruchomieniu sieci . Mały cytat z przewodnika:

Zapewni to, że wszystkie skonfigurowane urządzenia sieciowe są uruchomione i mają przypisany adres IP przed kontynuowaniem rozruchu.

Właśnie tego chciałem, więc włączyłem tę usługę i ustawiłem regułę zależności w pliku usługi dla 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

Ponieważ mysqldnadal opiera się na starym, init.dktóry potrzebowałem do stworzenia systemdusługi, jak tu sugerowano, włączenie systemctl różni się od uruchomienia systemctl :

[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

I na koniec skonfiguruj usługę Apache do uruchamiania po MySQL:

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

To przynajmniej działa dla mnie.

Użyłem tych poleceń, aby sprawdzić to później, gdzie wyraźnie widzę, że sieć jest uruchamiana przed przynajmniej MySQL i Apache. Chociaż crondnigdzie nie widzę, ale widzę, że działa w moich skryptach:

[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]

Kilka innych przydatnych poleceń, których użyłem, to:

# 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

Jeśli ktoś widzi lepszy sposób, aby to zrobić, prosimy o udostępnienie.

DHS
źródło
+1 za opublikowanie poleceń użytych do debugowania tego. Byłem w stanie rozwiązać naprawdę paskudny węzeł problemów systemd-analyze critical-chain. Nie tylko zamierzam tak często używać, ale nagle jestem sprzedawany systemd. Dzięki!
Brian Topping
Nie należy modyfikować plików usług zarządzanych przez menedżera pakietów dystrybucyjnych. Zamiast tego lepiej użyć drop-in plików konfiguracyjnych. Zobacz odpowiedź Jak zastąpić lub skonfigurować usługi systemowe?
Ludovic Ronsin