Как переопределить или настроить службы systemd?

109

Многие сценарии инициализации sysv использовали соответствующий файл, /etc/defaultчтобы позволить администратору настроить его. Upstart задания могут быть изменены с помощью .overrideфайлов. Как переопределить или настроить модули systemd, теперь это systemd по умолчанию в Ubuntu?

Мур
источник
Обратите внимание, что при очистке ExecStart=с пустой записью вы не можете добавить комментарий после него, например: ExecStart= # Empty line to clear previous entries.Это будет считаться другой ExecStart=записью и добавляться в список. PS. Я не мог добавить комментарий к ответу Муру из-за своей низкой репутации.
Тысик

Ответы:

185

systemdединицы не должны подчиняться файлам в /etc/default. systemdлегко настраивается, но требует, чтобы вы знали синтаксис файлов модулей systemd.

Пакеты отправляют файлы юнитов обычно в /lib/systemd/system/. Это не подлежит редактированию. Вместо этого systemdпозволяет переопределить эти файлы, создав соответствующие файлы в /etc/systemd/system/.

Для данной услуги fooпакет предоставит /lib/systemd/system/foo.service. Вы можете проверить его статус с помощью systemctl status fooили просмотреть его журналы с помощью journalctl -u foo. Чтобы переопределить что-либо в определении foo, выполните:

sudo systemctl edit foo

Это создает каталог с /etc/systemd/systemименем в честь устройства и override.confфайл в этом каталоге ( /etc/systemd/system/foo.service.d/override.conf). Вы можете добавить или переопределить настройки, используя этот файл (или другие .confфайлы в /etc/systemd/system/foo.service.d/).

Переопределение аргументов команды

Взять хотя бы gettyсервис. Скажем, я хочу, чтобы у моего пользователя был автологин TTY2 (это не рекомендуется, а всего лишь пример). TTY2 запускается getty@tty2службой ( tty2являющейся экземпляром шаблона /lib/systemd/system/getty@service). Для этого мне нужно изменить getty@tty2сервис.

$ systemctl cat getty@tty2
# /lib/systemd/system/getty@.service
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=

[Install]
WantedBy=getty.target
DefaultInstance=tty1

В частности, я должен изменить ExecStartстроку, которая в настоящее время:

$ systemctl cat getty@tty2 | grep Exec     
ExecStart=-/sbin/agetty --noclear %I $TERM

Чтобы переопределить это, сделайте:

sudo systemctl edit getty@tty2

И добавить:

[Service]
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

Обратите внимание, что:

  1. Я должен был явно ясно , ExecStartпрежде чем его снова, как это установка добавки, аналогична After, Environment(в целом, а не на переменную величину) и EnvironmentFile, и в отличие от переопределения параметров , как RestartSecили Type. ExecStartможет иметь несколько записей только для Type=oneshotуслуг.
  2. Я должен был использовать правильный заголовок раздела. В исходном файле ExecStartнаходится в [Service]разделе, так что мое переопределение также должно быть включено ExecStartв [Service]раздел. Часто взгляд на фактическое использование служебного файла systemctl catскажет вам, что вам нужно переопределить и в каком разделе он находится.

Обычно, если вы редактируете файл системного модуля, чтобы он вступил в силу, вам нужно выполнить:

sudo systemctl daemon-reload

Тем systemctl editне менее, автоматически делает это для вас.

В настоящее время:

$ systemctl cat getty@tty2 | grep Exec
ExecStart=-/sbin/agetty --noclear %I $TERM
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

$ systemctl show getty@tty2 | grep ExecS
ExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }

И если я сделаю:

sudo systemctl restart getty@tty2

и нажмите CtrlAltF2, Presto! Я войду в свой аккаунт на этом TTY.

Как я уже говорил, getty@tty2это экземпляр шаблона. Итак, что если я захочу переопределить все экземпляры этого шаблона? Это можно сделать, отредактировав сам шаблон (удалив идентификатор экземпляра - в данном случае tty2):

systemctl edit getty@

Переопределение окружающей среды

Распространенным случаем использования /etc/defaultфайлов является установка переменных среды. Обычно /etc/defaultэто сценарий оболочки, поэтому в нем можно использовать конструкции языка оболочки. С systemd, однако, это не так. Вы можете указать переменные среды двумя способами:

Через файл

Допустим, вы установили переменные среды в файле:

$ cat /path/to/some/file
FOO=bar

Затем вы можете добавить к переопределению:

[Service]
EnvironmentFile=/path/to/some/file

В частности, если ваш /etc/default/grubсодержит только назначения и без синтаксиса оболочки, вы можете использовать его как EnvironmentFile.

Через Environmentзаписи

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

[Service]
Environment=FOO=bar

Тем не менее, это может быть сложно с несколькими переменными, пробелами и т. Д. Посмотрите на один из моих других ответов для примера такого экземпляра.

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

Благодаря этому механизму становится очень легко переопределять systemdединицы, а также отменять такие изменения (просто удаляя файл переопределения). Это не единственные настройки, которые можно изменить.

Следующие ссылки будут полезны:

Мур
источник
1
Вы должны очистить переменную, прежде чем устанавливать ее для служб, которые не относятся к типу oneshot. Это решило мою проблему.
Колин
3
@MarkEdington из systemd.service(5)man- страницы , раздел на ExecStart: «Если Type = oneshot, должна быть указана ровно одна команда. Когда используется Type = oneshot, можно указать ноль или более команд. Команды могут быть указаны путем предоставления нескольких командных строк в одной и той же строке. директива или, альтернативно, эта директива может быть указана более одного раза с одинаковым эффектом. Если для этой опции назначена пустая строка, список команд для запуска сбрасывается, предыдущие назначения этой опции не будут иметь никакого эффекта ».
Муру
1
@Orient вы можете sudo rmпереопределить файл и затем systemctl daemon-reload, или вы можете systemctl editи заменить все в переопределении с комментариями. Комментарии в служебных файлах начинаются с #.
Муру
3
@Orientsystemctl revert foo
Ayell
1
Каков порядок приоритета для трех методов (файл переопределения, файл среды, переменная среды)? То есть, для переменной, определенной во всех трех, какое значение будет эффективным?
Николаос Какурос