LINUX.ORG.RU

«А включаешь — не работает»

 


1

1

Написал ini-шник для запуска сервиса, добавил его через systemctl enable, проверил старт-стоп-рестарт через systemctl start, stop и restart. Перезагружаю машину — не запускается. Что я упустил?

Конфиг:

$ cat /etc/systemd/system/machine.service
[Unit]
Description=Machine in Docker
Requires=docker.service
After=docker.service

[Service]
ExecStart=/usr/bin/docker run machine
Более сложный вариант:
$ cat /etc/systemd/system/machine.service
[Unit]
Description=Machine in Docker
Requires=docker.service
After=docker.service

[Service]
ExecStart=/bin/sh -c '/usr/bin/docker run -d machine > /var/run/machine.key'
ExecStop=/bin/sh -c '/usr/bin/docker stop `cat /var/run/machine.key`'

Ручной запуск:

$ curl -I localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
$ sudo systemctl enable machine
$ sudo systemctl start machine
$ curl -I localhost
HTTP/1.0 302 FOUND

Но после ребута сервер сам не запускается.

Добавление в конфиг

[Install]
WantedBy=default.target
или
[Install]
WantedBy=multu-user.target
ничего не меняет.

Дистрибутив — Ubuntu 16.04. Но хотелось бы ответ без привлечения Upstart.

Что сделать, чтобы запускался после ребута?

UPDATE:

journalctl -e после запуска показывает строку «systemd[1]: Started Machine in Docker.» Но сервер не работает.

Ответ: в секции [Service] не хватало

Type=oneshot
RemainAfterExit=yes

★★

Встречался с подобным. Самописный конфиг, ложил в /lib/systemd/system. Разбираться некогда было, прописал systemctl start в /etc/rc.local. Подписался на тред.

P.S. Давно надо перевести сервак на devuan. Руки никак не дойдут.

Deleted ()
Ответ на: комментарий от olegd

Попробуй, у меня да. Причём, возникло после переключения в disable и снова enable. У меня тоже Ubuntu 16.04. Возможно, стоит завести/плюсануть багрепорт, если ты есть сообществе убунты на ланчпаде. У меня последний сервак доживает на убунте свою жизнь, и я забил.

Deleted ()

Что я упустил?

Логи.

Возможно docker не умеет сигналить systemd о том, что он готов принимать подключения и запускать контейнеры. В результате твой сервис запускается _сразу_ после того, как запускается сервис docker. Но взлетает он не мгновенно и может получиться так, что твой сервис пытается делать docker run после того, как демон докера запустился, но до того, как он взлетел и всё проинициализировал.

Deleted ()

Сначала добавь в конфиг

[Install]
WantedBy=default.target

А потом делай

systemctl enable machine.service

А то без этой секции оно не знает куда тебе его енейблить.

А вообще, делай лучше так: https://github.com/ibuildthecloud/systemd-docker

Эта штука правильно колдует cgroups.

alex_the_v ★★★ ()
Последнее исправление: alex_the_v (всего исправлений: 1)
Ответ на: комментарий от alex_the_v

Сначала добавь в конфиг
[Install]
WantedBy=default.target

Результат не меняется, об этом сказано в стартовом посте.

А вообще, делай лучше так: https://github.com/ibuildthecloud/systemd-docker

А без посторонних утилит, средствами одного systemd нельзя? Не проще ли тогда совсем отказаться от systemd и запускать сервер через rc*.* ?

olegd ★★ ()
Ответ на: комментарий от anonymous

WantedBy=default.target

почему не multi-user.target? Мне кажется, в этом вся проблема

Какая разница?

Мне нужно, чтобы сервер запускался при включении машины. Вне зависимости от того, логинится ли туда кто-то или нет. Вне зависимости от запуска иксов. Какую прописать target?

olegd ★★ ()
Ответ на: комментарий от littlechris

лучше сразу на devuan переходить.

При чём тут devuan? Я про него впервые слышу. Вопрос про Ubuntu.

systemctl status

На этом дереве отсутствует сервис, запущеный вручную, через systemctl start. Почему?

journalctl -e

Спасибо! И даже --no-pager работает.

[/etc/systemd/system/machine.service:11] Failed to parse service restart specifier, ignoring: /bin/sh -c '/usr/bin/docker restart `cat /var/run/machine.key`'

Почему это нормально работает для systemctl restart, но вызывает проблемы при загрузке?

olegd ★★ ()

Может прописать в localrc (ну или как там у тебя в rclocal)?

piwww ★★★ ()
Ответ на: комментарий от olegd

Почему это нормально работает для systemctl restart, но вызывает проблемы при загрузке?

Блин, просмотрел... Эта опция делает другое: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=.

systemctl restart делает сначала stop, а затем снова start.

Deleted ()
Ответ на: комментарий от Deleted

Блин, просмотрел... Эта опция делает другое:

systemctl restart делает сначала stop, а затем снова start.

Спасибо. Скопировал из чьего-то примера на Хабре.

Но не работает даже вариант без Restart и Stop.

olegd ★★ ()
Ответ на: комментарий от littlechris

default.target — симлинк на таргет по умолчанию и может меняться. multi-user.target — настоящий target.

Который из них правильно отражает роль машины — удалённого веб-сервера без монитора, с которым работают почти исключительно через браузер, и иногда по SSH? Задействуется ли multi-user.target, если на машину вообще никто не логинится?

olegd ★★ ()
Ответ на: комментарий от littlechris

journalctl -e

Кстати, как передать less параметры -I -S ? Для данного запуска, а не глобально для каждого вызова less. Надоедает при каждом просмотре журнала вбивать руками.

olegd ★★ ()
Ответ на: комментарий от mos

SYSTEMD_LESS

Спасибо!

Что еще

1. Существует ли мануал, где всё сведено на одну страницу?

2. В логе написано, что сервис успешно стартовал. Сервис не работает. Куда копать?

3. При использовании SYSTEMD_LESS=«IS» все выделения в логе заменяются на ESC[0;1;39m . В чём проблема?

olegd ★★ ()
Последнее исправление: olegd (всего исправлений: 2)
Ответ на: комментарий от anonymous

Покажи его status.

$ SYSTEMD_LESS="I" systemctl status machine.service
● machine.service - Machine in Docker
   Loaded: loaded (/etc/systemd/system/machine.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Tue 2018-03-20 14:07:22 MSK; 6s ago
  Process: 1574 ExecStop=/bin/sh -c /usr/bin/docker stop `cat /var/run/machine.key` (code=exited, status=0/SUCCESS)
  Process: 1446 ExecStart=/bin/sh -c /usr/bin/docker run -d machine > /var/run/machine.key (code=exited, status=0/SUCCESS)
 Main PID: 1446 (code=exited, status=0/SUCCESS)

Mar 20 14:07:08 al8 systemd[1]: Started Machine in Docker.
Mar 20 14:07:22 al8 sh[1574]: 15a1a00f8ab93235bac0e9917f85a63eec30a4d8aff07c020d65d73f947b482f

То есть запускается ExecStart и сразу же ExecStop? Почему?

olegd ★★ ()
Ответ на: комментарий от olegd

В чём проблема?

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

mos ★★☆☆☆ ()
Ответ на: комментарий от olegd

То есть запускается ExecStart и сразу же ExecStop

А чего ты ожидал? Если не указывать тип сервиса, используется дефолтный simple, который подразумевает, что запускаемый процесс не будет завершаться. У вас же команда запуска тут же завершается, отчего systemd считает, что сервис завершился, и вызывает ExecStop. man systemd.service, читать о Type=.

Вам нужен тип oneshot, а также RemainAfterExit=yes.

anonymous ()
Ответ на: комментарий от Deleted

Это после чистого запуска или после systemctl restart?

После чистого запуска.

Кстати, тебе ещё скорее всего надо указать RemainAfterExit=yes и Type=oneshot.

Именно! После этого всё заработало.

olegd ★★ ()
Ответ на: комментарий от anonymous

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

Он и не должен завершаться. Докер с заданием продолжает висеть в памяти. Но stdout/stdin/stderr освобождает. Это считается завершением?

Определение oneshot из мануала: «Behavior of oneshot is similar to simple; however, it is expected that the process has to exit before systemd starts follow-up units.» Исходя из того, что exit означает завершение процесса docker, я его понял с точностью до наоборот и безуспешно пытался что-то сделать с forking.

olegd ★★ ()
Ответ на: комментарий от intelfx

Неверно указан Type=. Тебе нужен Type=oneshot, RemainAfterExit=yes.

Спасибо, помогло.

olegd ★★ ()
Ответ на: комментарий от mos

В том что у это переменной по умолчанию задано значение.

set | grep SYSTEMD не находит ничего. echo $SYSTEMD_LESS выдаёт пустую строку. echo «$SYSTEMD_LESS"qwerty выдаёт qwerty без изменений.

Где задаётся дефолтное значение „FRSXMK“? Или оно захардкожено, но ESC-последовательности добавляются вне зависимости от того, поддерживает ли их пейджер?

olegd ★★ ()
Ответ на: комментарий от olegd

Он и не должен завершаться. Докер с заданием продолжает висеть в памяти. Но stdout/stdin/stderr освобождает. Это считается завершением?

Тут можно посоветовать только изучить основы Unix/Linux. Запускаемый тобой процесс — завершается. Потомков никаких не оставляет. Он передаёт задание процессу докера, который может быть запущен вообще в другом месте, а тот уже запускает контейнер. Поэтому с точки зрения systemd процесс docker run — это тип oneshot.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Тут можно посоветовать только изучить основы Unix/Linux.

Бесполезно. Поможет только практика :)

Запускаемый тобой процесс — завершается. Потомков никаких не оставляет. Он передаёт задание процессу докера, который может быть запущен вообще в другом месте, а тот уже запускает контейнер. Поэтому с точки зрения systemd процесс docker run — это тип oneshot.

Спасибо за объяснение. Я не знал, что эта команда тоже считается процессом.

olegd ★★ ()
Ответ на: комментарий от olegd

Я прошу прощения, а чем ещё может «считаться» эта команда? Ты запускаешь исполняемый файл /usr/bin/docker. Это и есть процесс.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

Нет, я запускаю sh, который запускает docker. И sh — завершающийся процесс. Про sh я забыл.

Либо запускаю docker, который запускает другой экземпляр docker. И systemd не видит между ними никакой связи.

olegd ★★ ()
Последнее исправление: olegd (всего исправлений: 1)
Ответ на: комментарий от mos

У меня для тебя остались только фейспалмы, поэтому ничем более помочь не могу.

Где в мануале написано правильное местонахождение переменной SYSTEMD_LESS? Сейчас нет нигде, используется захардкоженное значение.

olegd ★★ ()
Ответ на: комментарий от olegd

Если socket, как реализовать с ним?

System-D собирает в чёрный мешок все .socket-юниты и начинает ждать подключений. При подключении запускает соответствующий сервис и передаёт ему сокет. socket activation — одна из главных фич System-D.

Таким образом, в прописывании зависимостей от docker.service нет необходимости.

anonymous ()
Ответ на: комментарий от anonymous

в прописывании зависимостей от docker.service нет необходимости.

А если докер ещё не запустился, а уже требуется, корректно отработает?

anonymous ()
Ответ на: комментарий от olegd

multi-user.target. да, задействуется, это не связано с наличием ssh. В конце концов, вебсервер у вас работает наверняка под отдельным юзером.

littlechris ★★★ ()
Ответ на: комментарий от anonymous

логично)) Я просто пошел по пути наименьшего сопротивления, (изучать systemd не хочу, он мне нах не вперся), вбил в гугле кейворд, открыл https://wiki.ubuntu.com/SystemdForUpstartUsers, нашел «example services», и нашлёпал примитивный файлик. Подумал, что нехорошо в /lib класть, но решил, что класть на FHS — это в духе системдэшников.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от olegd

Второе. Твой sh запускает docker и ждёт его завершения. А вот docker связывается с другим docker (демоном), и вот между ними systemd действительно не видит никакой связи.

intelfx ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.