Запустите процессы N с одного systemd сервисного файла

Я нашел, что этот systemd сервисный файл запустил autossh для поддержания на высоком уровне туннеля ssh: https://gist.github.com/thomasfr/9707568

[Unit]
Description=Keeps a tunnel to 'remote.example.com' open
After=network.target

[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa

[Install]
WantedBy=multi-user.target

Есть ли способ настроить systemd для запуска нескольких туннелей в одном сервисе.

Я не хочу создавать файлы системной службы N, так как я хочу избежать copy+paste.

Все сервисные файлы были бы идентичны кроме "remote.example.com", будет замена другими именами хостов.

1.5 года спустя...

Я задал этот вопрос примерно 1,5 года назад.

Мой ум изменился немного. Да, это хорошо, что можно сделать это с systemd (я все еще использую его), но я буду использовать управление конфигурацией в будущем.

Почему systemd должен реализовать шаблонный язык и заменить %h?

Несколько месяцев спустя я думаю, этот цикл и шаблонная обработка должны быть решены с инструментом, который автоматизирует конфигурацию. Я использую один инструмент этого списка в Википедии теперь.

36
задан 23 March 2017 в 11:59
3 ответа

Что ж, если предположить, что только вещь, изменяемая для каждого файла единицы, является частью remote.example.com , вы можете использовать экземпляр Служба .

Из справочной страницы systemd.unit :

При желании экземпляры модулей могут быть созданы из файла шаблона во время выполнения. Это позволяет создавать несколько единиц из одной конфигурации. файл. Если systemd ищет файл конфигурации модуля, он сначала поиск буквального имени единицы в файловой системе. Если это не дает успех и имя модуля содержит символ "@", systemd будет выглядеть для шаблона объекта с тем же именем, но с экземпляром строка (т.е. часть между символом "@" и суффиксом) удалено. Пример: если запрашивается услуга (скрытая) и нет найден файл с таким именем, systemd будет искать getty @ .service и создайте экземпляр службы из этого файла конфигурации, если он будет найден.

По сути, вы создаете единый файл модуля, который содержит переменную (обычно % i ), в которой возникают различия, а затем они связываются, когда вы "включить" эту службу.

Например, у меня есть файл модуля с именем /etc/systemd/system/autossh@.service , который выглядит следующим образом:

[Unit]
Description=AutoSSH service for ServiceABC on %i
After=network.target

[Service]
Environment=AUTOSSH_GATETIME=30 AUTOSSH_LOGFILE=/var/log/autossh/%i.log AUTOSSH_PIDFILE=/var/run/autossh.%i.pid
PIDFile=/var/run/autossh.%i.pid
#Type=forking
ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i

[Install]
WantedBy=multi-user.target

Который я затем включил

[user@anotherhost ~]$ sudo systemctl enable autossh@somehost.example.com
ln -s '/etc/systemd/system/autossh@.service' '/etc/systemd/system/multi-user.target.wants/autossh@somehost.example.com.service'

И может взаимодействовать с

[user@anotherhost ~]$ sudo systemctl start autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.service - AutoSSH service for ServiceABC on somehost.example
   Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
   Active: active (running) since Tue 2015-10-20 13:19:01 EDT; 17s ago
 Main PID: 32524 (autossh)
   CGroup: /system.slice/system-autossh.slice/autossh@somehost.example.com.service
           ├─32524 /usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
           └─32525 /usr/bin/ssh -L 40000:127.0.0.1:40000 -R 40000:127.0.0.1:40001 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com

Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.com.service - AutoSSH service for ServiceABC on somehost.example.com
   Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
   Active: inactive (dead) since Tue 2015-10-20 13:24:10 EDT; 2s ago
  Process: 32524 ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i (code=exited, status=0/SUCCESS)
 Main PID: 32524 (code=exited, status=0/SUCCESS)

Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopping AutoSSH service for ServiceABC on somehost.example.com...
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopped AutoSSH service for ServiceABC on somehost.example.com.

. Как видите, все экземпляры % i в файле модуля заменяются на somehost.example.com .

Есть куча дополнительные спецификаторы , которые вы можете использовать в файле модуля, но я считаю, что % i лучше всего работает в подобных случаях.

47
ответ дан 28 November 2019 в 19:49

Вот пример Python, который я искал. @ в имени файла службы позволяет запускать N процессов:

$ cat /etc/systemd/system/my-worker@.service

[Unit]
Description=manages my worker service, instance %i
After=multi-user.target

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10

Различные методы для его вызова

Включение различных подсчетов, например:

  • Разрешить 30 рабочих:

     sudo systemctl enable (скрыто  )
     
  • Включить 2 рабочих:

     sudo systemctl enable (скрыто)
     

Затем обязательно перезагрузите:

sudo systemctl daemon-reload

Теперь вы можете запускать / останавливать, а затем различными способами:

  • Запуск 1:

     sudo systemctl start (скрыто)
     
  • Несколько запусков:

     sudo systemctl start (скрыто)
     
  • Остановить несколько:

     sudo systemctl stop (скрыто)
     
  • Проверить статус:

     sudo systemctl status my-worker @ 1
     

ОБНОВЛЕНИЕ : Чтобы управлять экземплярами как одной службой, вы можете сделать что-то вроде (скрыто). Теперь вы можете управлять всеми экземплярами с помощью sudo systemctl some-worker (start | restart | stop)

Вот какой-то шаблон для вашего script.py :

#!/usr/bin/env python

import logging


def worker_loop():
    shutdown = False
    while True:

        try:
            if shutdown:
                break

            # Your execution logic here.
            # Common logic - i.e. consume from a queue, perform some work, ack message
            print("hello world")

        except (IOError, KeyboardInterrupt):
            shutdown = True
            logging.info("shutdown received - processing will halt when jobs complete")
        except Exception as e:
            logging.exception("unhandled exception on shutdown. {}".format(e))


if __name__ == '__main__':
    worker_loop()
15
ответ дан 28 November 2019 в 19:49

Ответ Грегала мне очень помог. Вот пример шаблона модуля, который я использовал в своем коде на примере, приведенном выше, для сервера заданий механика. Я сделал скрипт оболочки, который позволяет мне создать X количество "рабочих", используя этот шаблон.

[Unit]
Description=az gearman worker
After=gearman-job-server.service

[Service]
PIDFile=/var/run/gearman_worker_az%i.pid
Type=simple
User=www-data
WorkingDirectory=/var/www/mysite.com/jobs/
ExecStart=/usr/bin/php -f gearman_worker_az.php > /dev/null 2>&1
Restart=on-success
KillMode=process

[Install]
WantedBy=multi-user.target
1
ответ дан 28 November 2019 в 19:49

Теги

Похожие вопросы