Come posso eseguire un singolo comando all'avvio usando systemd?


113

Vorrei avviare un cluster Apache Spark dopo l'avvio usando il seguente comando:

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

Quindi eseguire questo comando quando il sistema si prepara al riavvio / spegnimento:

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

Come posso iniziare? Esiste un modello base su cui posso basarmi?

Ho provato ad usare un file estremamente semplice (file:) /lib/systemd/system/spark.service:

[Unit]
Description=Spark service

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

Che non funziona.



Ciao @WillemK, avevo già guardato questa pagina. Questo problema che ho trovato è che non posso semplicemente sostituire execcon ExecStart=. Inoltre, non ho usato upstart prima.
macourtney7,

1
Il punto prima del percorso della tua sceneggiatura sembra estremamente sospetto.
Andrea Lazzarotto,

@AndreaLazzarotto Penso che OP stia cercando di eseguire la sceneggiatura come OP farebbe nel terminale, quindi il ....
George Udosen,

Ciao @AndreaLazzarotto, questo è corretto. Ci scusiamo per l'eventuale confusione causata.
macourtney7,

Risposte:


144

Il tuo .servicefile dovrebbe apparire così:

[Unit]
Description=Spark service

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

[Install]
WantedBy=multi-user.target

Ora esegui qualche altro passaggio per abilitare e utilizzare il .servicefile:

  1. Mettilo nella /lib/systemd/systemcartella con dire un nome dimyfirst.service

  2. Rendi eseguibile il tuo script con:

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

    sudo systemctl start myfirst
    
  4. Abilitalo per l'esecuzione all'avvio:

    sudo systemctl enable myfirst
    
  5. Smettila:

    sudo systemctl stop myfirst
    

Appunti:

  1. Non è necessario avviare Spark con sudo nel servizio, poiché l'utente del servizio predefinito è già root.

  2. Guarda i link qui sotto per ulteriori systemdopzioni.

AGGIORNARE

Ora quello che abbiamo sopra è solo rudimentale, ecco una configurazione completa per 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

Per configurare il servizio:

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

Ulteriori letture

Si prega di leggere i seguenti collegamenti. Spark è una configurazione complessa, quindi dovresti capire come si integra con il servizio init di 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


Notato e aggiornato
George Udosen

1
Grazie per questo, ho creato un file basato su ciò che mi hai suggerito. Durante l'esecuzione sudo systemctl start sparkviene visualizzato il seguente errore: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,

La parte principale di systemctl status spark.serviceè la seguente: Executable path is not absoluteespark.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
macourtney7,

I problemi sono 1) È necessario il percorso binario di Spark (dovrebbe sostituire quello che abbiamo nel file di servizio), 2) Spark ha un comando di spegnimento di cosa si tratta. 3) Hai esaminato i link che ti ho dato. Non uso Spark quindi forniscili
George Udosen,

@GeorgeUdosen Grazie per la tua risposta, la mia domanda è: come posso eseguire Spark sotto un comando specifico dopo il riavvio? La domanda è qui askubuntu.com/questions/979498/…
Soheil Pourbafrani,

2

Questo crea ed esegue /root/boot.shall'avvio (come root) usando un file di servizio minimo:

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

Puoi Ctrl+ Cquesto in un terminale di root.

Per modificare i parametri, ad esempio per usarne uno diverso $bootscript, impostare quella variabile manualmente e saltare quella riga quando si copiano i comandi.

Dopo aver eseguito i comandi, puoi modificare lo script di avvio usando il tuo editor preferito e verrà eseguito al prossimo avvio. Puoi anche eseguirlo immediatamente usando:

systemctl start $servicename

Ogni passaggio potrebbe essere eseguito con sudo, ma è leggermente più complicato e alcuni sistemi non hanno sudo installato, quindi alcune persone dovrebbero modificare l'esempio prima dell'uso. Pertanto ho scelto di non includere sudo nell'esempio.


Sono un po 'confuso dai documenti di systemd, ma non dovrebbe essere Type=oneshot RemainAfterExit=yeso systemd considererà l'attività inattiva a meno che lo script personalizzato non lasci alcuni processi in esecuzione.
Peter Lamberg,

@PeterLamberg Ho provato anche a leggere i documenti di systemd eppure eccoci entrambi qui;). Ricordo che non erano molto chiari, ma la risposta che ho pubblicato funziona per me su più sistemi (ogni tanto rivedo questa pagina quando ne ho bisogno). Vuoi dire che, poiché è considerato "inattivo", ogni successiva chiamata "start" eseguirà nuovamente lo script? Perché lo considererei come previsto per uno script di shell. Lo troverei strano se dovessi "fermare" qualcosa che non è effettivamente in esecuzione prima di poterlo ricominciare.
Luc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.