Bagaimana cara menjalankan satu perintah saat startup menggunakan systemd?

113

Saya ingin memulai cluster Apache Spark setelah boot menggunakan perintah berikut:

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

Kemudian jalankan perintah ini ketika sistem bersiap untuk reboot / shutdown:

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

Bagaimana saya bisa memulai? Apakah ada templat dasar yang bisa saya buat?

Saya sudah mencoba menggunakan yang sangat sederhana (file /lib/systemd/system/spark.service:):

[Unit]
Description=Spark service

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

Yang tidak berhasil.

macourtney7
sumber
Hai @ WillemK, saya sudah melihat halaman ini. Masalah ini saya temukan adalah saya tidak bisa hanya mengganti execdengan ExecStart=. Plus, saya belum pernah menggunakan pemula baru.
macourtney7
1
Titik sebelum jalur skrip Anda terlihat sangat mencurigakan.
Andrea Lazzarotto
@AndreaLazzarotto Saya pikir OP mencoba menjalankan skrip seperti yang dilakukan OP di terminal ....
George Udosen
Hai @AndreaLazzarotto, ini benar. Permintaan maaf untuk kebingungan yang disebabkan.
macourtney7

Jawaban:

144

.serviceFile Anda akan terlihat seperti ini:

[Unit]
Description=Spark service

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

[Install]
WantedBy=multi-user.target

Sekarang lakukan beberapa langkah lagi untuk mengaktifkan dan menggunakan .servicefile:

  1. Tempatkan di /lib/systemd/systemfolder dengan ucapkan namamyfirst.service

  2. Jadikan skrip Anda dapat dieksekusi dengan:

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

    sudo systemctl start myfirst
    
  4. Aktifkan untuk dijalankan saat boot:

    sudo systemctl enable myfirst
    
  5. Hentikan:

    sudo systemctl stop myfirst
    

Catatan:

  1. Anda tidak perlu meluncurkan Spark dengan sudo di layanan Anda, karena pengguna layanan default sudah root.

  2. Lihat tautan di bawah ini untuk systemdopsi lebih lanjut .

MEMPERBARUI

Sekarang apa yang kita miliki di atas hanyalah dasar, berikut ini adalah pengaturan lengkap untuk percikan:

[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

Untuk mengatur layanan:

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

Bacaan lebih lanjut

Silakan baca tautan berikut. Spark adalah pengaturan yang rumit, jadi Anda harus memahami bagaimana itu terintegrasi dengan layanan 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
sumber
Tercatat dan diperbarui
George Udosen
1
Terima kasih untuk ini, saya telah membuat file berdasarkan apa yang Anda sarankan. Saat berjalan sudo systemctl start sparkmenerima kesalahan berikut: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
Bagian utama systemctl status spark.serviceadalah sebagai berikut: Executable path is not absolutedanspark.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
macourtney7
Masalahnya adalah 1) Jalur biner Spark (harus mengganti apa yang kita miliki dalam file layanan) diperlukan, 2) Spark memiliki perintah mematikan apa itu. 3) Apakah Anda pergi melalui tautan yang saya berikan kepada Anda. Saya tidak menggunakan percikan jadi suplai mereka
George Udosen
@GeorgeUdosen Terima kasih atas jawaban Anda, pertanyaan saya adalah bagaimana saya bisa menjalankan percikan di bawah perintah tertentu setelah reboot? Pertanyaannya ada di sini askubuntu.com/questions/979498/…
Soheil Pourbafrani
2

Ini membuat dan berjalan /root/boot.shsaat boot (sebagai root) menggunakan file layanan 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

Anda dapat memberi ini Ctrl+ Cke terminal root.

Untuk memodifikasi parameter, misalnya untuk menggunakan yang berbeda $bootscript, atur variabel itu secara manual dan lewati saja baris itu saat menyalin perintah.

Setelah menjalankan perintah, Anda dapat mengedit skrip boot menggunakan editor favorit Anda, dan skrip boot akan dijalankan pada boot berikutnya. Anda juga dapat segera menjalankannya dengan menggunakan:

systemctl start $servicename

Setiap langkah dapat dilakukan dengan sudo, tetapi ini sedikit lebih rumit, dan beberapa sistem tidak memiliki sudo yang diinstal sehingga beberapa orang harus memodifikasi contoh sebelum digunakan. Karena itu saya memilih untuk tidak memasukkan sudo dalam contoh.

Luc
sumber
Saya agak bingung dengan systemd docs, tetapi seharusnya tidak Type=oneshot RemainAfterExit=yesatau systemd akan menganggap tugas tidak aktif kecuali skrip kustom membiarkan beberapa proses berjalan.
Peter Lamberg
@ PeterLamberg Saya mencoba membaca docs systemd juga, tapi di sini kita berdua;). Saya ingat mereka tidak begitu jelas, tetapi jawaban yang saya posting berfungsi untuk saya pada banyak sistem (saya mengunjungi kembali halaman ini setiap saat ketika saya membutuhkannya lagi). Maksud Anda, karena dianggap 'tidak aktif', setiap panggilan 'mulai' yang berurutan akan menjalankan ulang skrip? Karena saya akan menganggap itu seperti yang diharapkan untuk skrip shell. Saya akan merasa aneh jika saya harus 'menghentikan' sesuatu yang tidak benar-benar berjalan sebelum saya bisa memulainya lagi.
Luc