Comment exécuter une seule commande au démarrage à l'aide de systemd?

113

Je souhaite démarrer un cluster Apache Spark après le démarrage à l'aide de la commande suivante:

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

Exécutez ensuite cette commande lorsque le système se prépare à redémarrer / arrêter:

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

Comment puis-je commencer? Existe-t-il un modèle de base sur lequel je peux construire?

J'ai essayé d'utiliser un extrêmement simple (fichier:) /lib/systemd/system/spark.service:

[Unit]
Description=Spark service

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

Ce qui ne marche pas

macourtney7
la source
Bonjour @ WillemK, j'avais déjà consulté cette page. Ce problème que j'ai trouvé est que je ne peux pas simplement remplacer execpar ExecStart=. De plus, je n'ai pas utilisé upstart avant.
macourtney7
1
Le point devant le chemin de votre script semble extrêmement suspect.
Andrea Lazzarotto
@AndreaLazzarotto Je pense que OP essaie d'exécuter le script comme l'OP le ferait dans le terminal, d'où ....
George Udosen
Bonjour @AndreaLazzarotto, c'est correct. Toutes mes excuses pour toute confusion causée.
macourtney7

Réponses:

144

Votre .servicefichier devrait ressembler à ceci:

[Unit]
Description=Spark service

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

[Install]
WantedBy=multi-user.target

Maintenant, effectuez quelques étapes supplémentaires pour activer et utiliser le .servicefichier:

  1. Placez-le dans le /lib/systemd/systemdossier avec dites un nom demyfirst.service

  2. Faites que votre script soit exécutable avec:

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

    sudo systemctl start myfirst
    
  4. Autorisez-le à s'exécuter au démarrage:

    sudo systemctl enable myfirst
    
  5. Arrête ça:

    sudo systemctl stop myfirst
    

Remarques:

  1. Vous n'avez pas besoin de lancer Spark avec sudo dans votre service, car l'utilisateur du service par défaut est déjà root.

  2. Regardez les liens ci-dessous pour plus d' systemdoptions.

MISE À JOUR

Maintenant, ce que nous avons ci-dessus est simplement rudimentaire, voici une configuration complète pour 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

Pour configurer le service:

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

Lectures complémentaires

Veuillez lire les liens suivants. Spark est une configuration complexe, vous devez donc comprendre comment elle s'intègre au service init d'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
la source
Noté et mis à jour
George Udosen
1
Merci pour cela, j'ai créé un fichier basé sur ce que vous avez suggéré. Lors de l'exécution sudo systemctl start sparkest recevoir l'erreur suivante: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 partie principale de systemctl status spark.serviceest la suivante: Executable path is not absoluteetspark.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
macourtney7
Les problèmes sont les suivants: 1) le chemin binaire de Spark (qui devrait remplacer ce que nous avons dans le fichier de service) est nécessaire, 2) Spark dispose d’une commande d’arrêt qui l’est. 3) Avez-vous parcouru les liens que je vous ai donnés? Je n'utilise pas d'étincelle alors fournissez-les
George Udosen
@GeorgeUdosen Merci pour votre réponse, ma question est comment puis-je lancer spark sous une commande spécifique après le redémarrage? La question est ici askubuntu.com/questions/979498/…
Soheil Pourbafrani
2

Cela crée et s’exécute /root/boot.shau démarrage (en tant que root) en utilisant un fichier de service minimal:

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

Vous pouvez Ctrl+ Cceci dans un terminal root.

Pour modifier les paramètres, par exemple pour utiliser un autre $bootscript, définissez cette variable manuellement et ignorez cette ligne lors de la copie des commandes.

Après avoir exécuté les commandes, vous pouvez éditer le script de démarrage à l’aide de votre éditeur favori et le lancer au prochain démarrage. Vous pouvez aussi le lancer immédiatement en utilisant:

systemctl start $servicename

Toutes les étapes pourraient être effectuées avec sudo, mais c'est un peu plus compliqué et certains systèmes n'ont pas installé sudo, de sorte que certaines personnes devraient modifier l'exemple avant de les utiliser. J'ai donc choisi de ne pas inclure sudo dans l'exemple.

Luc
la source
La documentation de Type=oneshot RemainAfterExit=yessystemd me laisse un peu perplexe, mais ce ne devrait pas être le cas, sinon Systemd considérera la tâche inactive à moins que le script personnalisé ne laisse certains processus en cours d'exécution.
Peter Lamberg le
@PeterLamberg J'ai aussi essayé de lire la documentation de systemd et pourtant, nous sommes tous les deux;). Je me souviens qu'elles n'étaient pas très claires, mais la réponse que j'ai postée fonctionne pour moi sur plusieurs systèmes (je revisite cette page de temps en temps lorsque j'en ai besoin à nouveau). Voulez-vous dire que, comme il est considéré comme "inactif", chaque appel successif de "démarrage" relance le script? Parce que je considérerais cela comme prévu pour un script shell. Je trouverais ça bizarre de devoir «arrêter» quelque chose qui ne tourne pas avant de pouvoir le recommencer.
Luc