Как запустить одну команду при запуске с использованием systemd?

113

Я хотел бы запустить кластер Apache Spark после загрузки, используя следующую команду:

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

Затем выполните эту команду, когда система готовится к перезагрузке / выключению:

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

Как я могу начать? Есть ли базовый шаблон, на котором я могу построить?

Я попытался использовать очень простой (file:) /lib/systemd/system/spark.service:

[Unit]
Description=Spark service

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

Который не работает.

macourtney7
источник
Взгляните на: wiki.ubuntu.com/SystemdForUpstartUsers
Привет @WillemK, я уже посмотрел эту страницу. Этот вопрос я нашел , что я не могу просто заменить execс ExecStart=. Плюс, я не использовал выскочку раньше.
macourtney7
1
Точка до пути вашего скрипта выглядит крайне подозрительно.
Андреа
@AndreaLazzarotto Я думаю, что OP пытается запустить сценарий так же, как OP в терминале, поэтому ....
Джордж Удосен
Привет @AndreaLazzarotto, это правильно. Извиняюсь за путаницу.
macourtney7

Ответы:

144

Ваш .serviceфайл должен выглядеть так:

[Unit]
Description=Spark service

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

[Install]
WantedBy=multi-user.target

Теперь сделайте еще несколько шагов, чтобы включить и использовать .serviceфайл:

  1. Поместите его в /lib/systemd/systemпапку с именемmyfirst.service

  2. Сделайте так, чтобы ваш скрипт выполнялся с:

    chmod u+x /path/to/spark/sbin/start-all.sh
    
  3. Начни это:

    sudo systemctl start myfirst
    
  4. Включите его для запуска при загрузке:

    sudo systemctl enable myfirst
    
  5. Останови это:

    sudo systemctl stop myfirst
    

Примечания:

  1. Вам не нужно запускать Spark с sudo в вашем сервисе, так как пользователь сервиса по умолчанию уже root.

  2. Посмотрите на ссылки ниже для большего количества systemdвариантов.

ОБНОВИТЬ

Теперь то, что мы имеем выше, просто зачаточно, вот полная настройка для 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

Для настройки сервиса:

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

дальнейшее чтение

Пожалуйста, прочитайте следующие ссылки. Spark - сложная установка, поэтому вы должны понимать, как она интегрируется с сервисом инициализации 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

Джордж Удосен
источник
Отметил и обновил
Джордж Удосен
1
Спасибо за это, я создал файл на основе того, что вы предложили. После запуска sudo systemctl start sparkполучаю следующую ошибку: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
Основная часть systemctl status spark.serviceвыглядит следующим образом: Executable path is not absoluteаspark.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
macourtney7
Проблемы следующие: 1) Требуется двоичный путь Spark (должен заменить то, что есть в служебном файле), 2) У Spark есть команда выключения, что это такое. 3) Перешли ли вы по ссылкам, которые я вам дал. Я не использую искру, так что
поставьте
@GeorgeUdosen Спасибо за ваш ответ, мой вопрос: как я могу запустить spark под определенной командой после перезагрузки? Вопрос здесь askubuntu.com/questions/979498/…
Soheil Pourbafrani
2

Это создает и запускается /root/boot.shпри загрузке (с правами root) с использованием минимального служебного файла:

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

Вы можете Ctrl+ Cэто в корневой терминал.

Чтобы изменить параметры, например, использовать другой $bootscript, установите эту переменную вручную и просто пропустите эту строку при копировании команд.

После запуска команд вы можете отредактировать загрузочный скрипт, используя ваш любимый редактор, и он запустится при следующей загрузке. Вы также можете сразу запустить его, используя:

systemctl start $servicename

Любой шаг может быть сделан с помощью sudo, но он немного сложнее, и в некоторых системах sudo не установлен, поэтому некоторым людям придется изменить пример перед использованием. Поэтому я решил не включать sudo в пример.

Люк
источник
Я немного запутался в документации по systemd, но если это не так, то Type=oneshot RemainAfterExit=yessystemd сочтет задачу неактивной, если пользовательский скрипт не оставит некоторые процессы запущенными.
Питер Ламберг
@PeterLamberg Я тоже пытался читать документы по systemd, и все же мы оба здесь;). Я помню, что они не были очень ясны, но ответ, который я разместил, работает для меня на нескольких системах (я возвращаюсь на эту страницу время от времени, когда мне это нужно снова). Вы имеете в виду, что, поскольку он считается «неактивным», каждый последующий вызов «start» перезапускает скрипт? Потому что я считаю, что, как ожидается, для сценария оболочки. Мне было бы странно, если бы мне пришлось «остановить» что-то, что на самом деле не работает, прежде чем я смогу запустить это снова.
Люк