Jak uruchomić jedno polecenie podczas uruchamiania przy użyciu systemd?

113

Chciałbym uruchomić klaster Apache Spark po uruchomieniu za pomocą następującego polecenia:

sudo ./path/to/spark/sbin/start-all.sh

Następnie uruchom to polecenie, gdy system przygotowuje się do ponownego uruchomienia / zamknięcia:

sudo ./path/to/spark/sbin/stop-all.sh

Jak mogę zacząć? Czy istnieje podstawowy szablon, na którym można zbudować?

Próbowałem użyć bardzo prostego (pliku /lib/systemd/system/spark.service:):

[Unit]
Description=Spark service

[Service]
ExecStart=sudo ./path/to/spark/sbin/start-all.sh

Co nie działa

macourtney7
źródło
Cześć @WillemK, już widziałem tę stronę. Ten problem znalazłem to nie mogę po prostu zastąpić execz ExecStart=. Ponadto nie korzystałem wcześniej z upstart.
macourtney7
1
Kropka przed ścieżką skryptu wygląda wyjątkowo podejrzanie.
Andrea Lazzarotto
@AndreaLazzarotto Myślę, że OP próbuje uruchomić skrypt w sposób, w jaki OP zrobiłby to w terminalu, stąd ....
George Udosen
Cześć @AndreaLazzarotto, to prawda. Przepraszamy za wszelkie nieporozumienia.
macourtney7

Odpowiedzi:

142

Twój .serviceplik powinien wyglądać następująco:

[Unit]
Description=Spark service

[Service]
ExecStart=/path/to/spark/sbin/start-all.sh

[Install]
WantedBy=multi-user.target

Teraz wykonaj jeszcze kilka kroków, aby włączyć i użyć .servicepliku:

  1. Umieść go w /lib/systemd/systemfolderze, podając nazwęmyfirst.service

  2. Spraw, aby Twój skrypt był wykonywalny za pomocą:

    chmod u+x /path/to/spark/sbin/start-all.sh
    
  3. Zacznij to:

    sudo systemctl start myfirst
    
  4. Włącz go, aby uruchamiał się podczas rozruchu:

    sudo systemctl enable myfirst
    
  5. Przestań:

    sudo systemctl stop myfirst
    

Uwagi:

  1. Nie musisz uruchamiać Spark z sudo w swojej usłudze, ponieważ domyślny użytkownik usługi jest już rootem.

  2. Spójrz na poniższe linki, aby uzyskać więcej systemdopcji.

AKTUALIZACJA

To, co mamy powyżej, jest po prostu szczątkowe, oto pełna konfiguracja dla Spark:

[Unit]
Description=Apache Spark Master and Slave Servers
After=network.target
After=systemd-user-sessions.service
After=network-online.target

[Service]
User=spark
Type=forking
ExecStart=/opt/spark-1.6.1-bin-hadoop2.6/sbin/start-all.sh
ExecStop=/opt/spark-1.6.1-bin-hadoop2.6/sbin/stop-all.sh
TimeoutSec=30
Restart=on-failure
RestartSec=30
StartLimitInterval=350
StartLimitBurst=10

[Install]
WantedBy=multi-user.target

Aby skonfigurować usługę:

sudo systemctl start spark.service
sudo systemctl stop spark.service
sudo systemctl enable spark.service

Dalsza lektura

Przeczytaj poniższe linki. Spark jest złożoną konfiguracją, więc powinieneś zrozumieć, jak integruje się z usługą init Ubuntu.

https://datasciencenovice.wordpress.com/2016/11/30/spark-stand-alone-cluster-as-a-systemd-service-ubuntu-16-04centos-7/

https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files

https://www.freedesktop.org/software/systemd/man/systemd.unit.html

George Udosen
źródło
Zauważono i zaktualizowano
George Udosen
1
Dzięki za to stworzyłem plik na podstawie tego, co zasugerowałeś. Po uruchomieniu sudo systemctl start sparkpojawia się następujący błąd:Failed to start spark.service: Unit spark.service is not loaded properly: Invalid argument. See system logs and 'systemctl status spark.service' for details.
macourtney7
Główna część systemctl status spark.servicejest następująca: Executable path is not absoluteorazspark.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
macourtney7
Problemy są następujące: 1) Konieczna jest ścieżka binarna Spark (powinna zastąpić to, co mamy w pliku usługi), 2) Spark ma polecenie zamknięcia systemu, co to jest. 3) Czy przejrzałeś linki, które ci dałem? Nie używam iskry, więc dostarczaj je
George Udosen
@GeorgeUdosen Dziękuję za odpowiedź, moje pytanie brzmi: jak uruchomić Spark pod konkretnym poleceniem po ponownym uruchomieniu? Pytanie znajduje się tutaj askubuntu.com/questions/979498/...
Soheil Pourbafrani
2

Spowoduje to /root/boot.shutworzenie i uruchomienie przy rozruchu (jako root) przy użyciu minimalnego pliku usługi:

bootscript=/root/boot.sh
servicename=customboot

cat > $bootscript <<EOF
#!/usr/bin/env bash
echo "$bootscript ran at $(date)!" > /tmp/it-works
EOF

chmod +x $bootscript

cat > /etc/systemd/system/$servicename.service <<EOF
[Service]
ExecStart=$bootscript
[Install]
WantedBy=default.target
EOF

systemctl enable $servicename

Możesz dodać to Ctrl+ Cdo głównego terminalu.

Aby zmodyfikować parametry, na przykład użyć innej $bootscript, ustaw tę zmienną ręcznie i po prostu pomiń ten wiersz podczas kopiowania poleceń.

Po uruchomieniu poleceń możesz edytować skrypt rozruchowy za pomocą swojego ulubionego edytora, a zostanie on uruchomiony przy następnym uruchomieniu. Możesz również natychmiast uruchomić go, używając:

systemctl start $servicename

Każdy krok można wykonać za pomocą sudo, ale jest to nieco bardziej skomplikowane, a niektóre systemy nie mają zainstalowanego sudo, więc niektórzy ludzie będą musieli zmodyfikować przykład przed użyciem. Dlatego postanowiłem nie uwzględniać sudo w tym przykładzie.

Luc
źródło
Jestem trochę zdezorientowany przez systemd docs, ale nie powinienem Type=oneshot RemainAfterExit=yeslub systemd uzna, że ​​zadanie jest nieaktywne, chyba że skrypt niestandardowy pozostawia niektóre procesy uruchomione.
Peter Lamberg
@PeterLamberg Próbowałem też czytać dokumenty systemowe, a jednak oboje jesteśmy;). Pamiętam, że nie były bardzo jasne, ale odpowiedź, którą zamieściłem, działa dla mnie na wielu systemach (odwiedzam tę stronę co jakiś czas, kiedy jej potrzebuję). Czy masz na myśli to, że ponieważ jest uważane za „nieaktywne”, każde kolejne wywołanie „start” spowoduje ponowne uruchomienie skryptu? Ponieważ uważam to za oczekiwane dla skryptu powłoki. Byłbym dziwny, gdybym musiał „zatrzymać” coś, co tak naprawdę nie działa, zanim będę mógł zacząć od nowa.
Luc