Systemd для продолжающих. part 1

10.3.2. Просмотр текущего таргета

Чтобы получить список загруженных таргетов, наберите следующую команду:

systemctl list-units --type target

Для каждого таргета эта команда отображает полное имя (UNIT), за ним следует примечание загружен ли юнит (LOAD), высокоуровневый (ACTIVE) и низкоуровневый (SUB) статус юнита, и краткое описание (DESCRIPTION).
По умолчанию команда отображает только активные юниты. Если вы хотите просмотреть список всех загруженных юнитов независимо от их состояния, запустите эту команду с флагом или :

systemctl list-units --type target --all

Как сменить текущий таргет см. в разделе .

Пример 10.11. Просмотр текщего таргета

~$ systemctl list-units --type target
UNIT                  LOAD   ACTIVE SUB    DESCRIPTION
basic.target          loaded active active Basic System
cryptsetup.target     loaded active active Encrypted Volumes
getty.target          loaded active active Login Prompts
graphical.target      loaded active active Graphical Interface
local-fs-pre.target   loaded active active Local File Systems (Pre)
local-fs.target       loaded active active Local File Systems
multi-user.target     loaded active active Multi-User System
network.target        loaded active active Network
paths.target          loaded active active Paths
remote-fs.target      loaded active active Remote File Systems
sockets.target        loaded active active Sockets
sound.target          loaded active active Sound Card
spice-vdagentd.target loaded active active Agent daemon for Spice guests
swap.target           loaded active active Swap
sysinit.target        loaded active active System Initialization
time-sync.target      loaded active active System Time Synchronized
timers.target         loaded active active Timers
 
LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.
 
17 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Примеры Service-файлов в Systemd

Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

WantedBy=multi-user.target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Unit

Description=The NGINX HTTP andreverse proxy server

After=syslog.target network.target remote-fs.target nss-lookup.target

Service

Type=forking

PIDFile=runnginx.pid

ExecStartPre=usrsbinnginx-t

ExecStart=usrsbinnginx

ExecReload=binkill-sHUP$MAINPID

ExecStop=binkill-sQUIT$MAINPID

PrivateTmp=true

Install

WantedBy=multi-user.target

Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target

Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
KillSignal=SIGCONT
PrivateTmp=true

WantedBy=multi-user.target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Unit

Description=The Apache HTTP Server

After=network.target remote-fs.target nss-lookup.target

Service

Type=notify

EnvironmentFile=etcsysconfighttpd

ExecStart=usrsbinhttpd$OPTIONS-DFOREGROUND

ExecReload=usrsbinhttpd$OPTIONS-kgraceful

ExecStop=binkill-WINCH${MAINPID}

KillSignal=SIGCONT

PrivateTmp=true

Install

WantedBy=multi-user.target

Description=Redis persistent key-value database
After=network.target

ExecStart=/usr/bin/redis-server /etc/redis.conf —daemonize no
ExecStop=/usr/bin/redis-shutdown
User=redis
Group=redis

WantedBy=multi-user.target

1
2
3
4
5
6
7
8
9
10
11
12

Unit

Description=Redis persistent key-value database

After=network.target

Service

ExecStart=usrbinredis-serveretcredis.conf—daemonize no

ExecStop=usrbinredis-shutdown

User=redis

Group=redis

Install

WantedBy=multi-user.target

Больше примеров в документации по systemd.service и systemd.unit.

How it works

As per default configuration in , the module automatically launches a instance when the user logs in for the first time. This process will survive as long as there is some session for that user, and will be killed as soon as the last session for the user is closed. When is enabled, the instance is started on boot and will not be killed. The systemd user instance is responsible for managing user services, which can be used to run daemons or automated tasks, with all the benefits of systemd, such as socket activation, timers, dependency system or strict process control via cgroups.

Similarly to system units, user units are located in the following directories (ordered by ascending precedence):

  • where units provided by installed packages belong.
  • where units of packages that have been installed in the home directory belong.
  • where system-wide user units are placed by the system administrator.
  • where the user puts their own units.

When a systemd user instance starts, it brings up the per user target . Other units can be controlled manually with . See .

Note:

  • runs as a separate process from the process. User units can not reference or depend on system units or units of other users.

Известные проблемы

Эта статья содержит фрагменты на иностранном языке. Вы можете помочь переведя её до конца. (cм. руководство по переводу)

Отладка в systemd

To get debug from systemd, you can either :

  • remove quiet from kernel command line
  • increase systemd verbosity by adding debug to kernel command line. You can also add systemd.sysv_console=1 (0: disabled, 1: enabled) to display legacy SysV initscripts output on console.
  • modify /etc/systemd/system.conf (check man systemd.conf) to increase verbosity like this :
LogLevel=debug
LogTarget=syslog-or-kmsg
SysVConsole=yes

serial console isn’t working

By default, systemd starts a minimal set of getty to let the system accessible.

When specifying on kernel command line which serial console should be used, only the last one in the list (which define the «active» console), will get a getty started :

  • console=tty0 console=ttyS0 will start a console on both tty0 (ie physical console) and serial console
  • console=ttyS0 console=tty0 will only start a console on tty0

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

ln -s /usr/lib/systemd/system/[email protected] /etc/systemd/system/getty.target.wants/[email protected]

Написание файлов юнитов

  • /usr/lib/systemd/system/: юниты, предоставляемые пакетами при их установке
  • /etc/systemd/system/: юниты, устанавливаемые системным администратором

Обработка зависимостей

В случае использования systemd зависимости могут быть указаны правильным построением файлов юнитов. Наиболее частый случай — юниту A требуется, чтобы юнит B был запущен перед тем, как запустится сам юнит A. В этом случае добавьте строки Requires=B и After=B в секцию файла службы A. Если подобная зависимость не является обязательной, взамен указанных выше добавьте, соответственно, строки Wants=B и After=B

Обратите внимание, что Wants= и Requires= не подразумевают After=, что означает, что если After= не определено, два юнита будут запущены параллельно друг другу.

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

Типы служб

Существует несколько различных типов запуска служб, которые надо иметь в виду при написании пользовательского файла службы. Тип определяется параметром Type= в секции :

  • Type=simple (по умолчанию): systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы. Исключение — активация сокета
  • Type=forking: systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. Используйте данный тип для запуска классических демонов за исключением тех случаев, когда, как вам известно, в таком поведении процесса нет необходимости. Вам следует также определить PIDFile=, чтобы systemd могла отслеживать основной процесс
  • Type=oneshot: полезен для скриптов, которые выполняют одно задание и завершаются. Вам может понадобиться также установить параметр RemainAfterExit=yes, чтобы systemd по-прежнему считала процесс активным, даже после его завершения
  • Type=notify: идентичен параметру Type=simple, но с той оговоркой, что демон пошлет systemd сигнал о своей готовности. Эталонная реализация данного уведомления представлена в libsystemd-daemon.so
  • Type=dbus: сервис считается находящимся в состоянии готовности, когда определенное BusName появляется в системной шине DBus
  • Type=idle: systemd задержит выполнение двоичного файла службы до тех пор, пока все задания отправляются. Кроме того, поведение очень похоже на Type=simple.

Редактирование предоставленных пакетами файлов юнитов

Есть два способа редактирования файлов юнита, предоставленного пакетом: заменить весь блок файла на новый или создать фрагмент кода, который применяется в верхней части существующего блока файла. В обоих методах, чтобы применить изменения, нужно перезагрузить юнит. Это может быть сделано либо путем редактирования блока с помощью Шаблон:Ic (которая автоматически загружает модуль) либо при перезагрузке всех юнитов:

# systemctl daemon-reload

Замена файлов юнита

Чтобы заменить файл юнита /usr/lib/systemd/system/юнит, создайте файл /etc/systemd/system/юнит и перезапустите юнит для обновления символьных ссылок:

# systemctl reenable юнит

В качестве альтернативы, можно выполнить:

# systemctl edit --full юнит

Эта команда откроет /etc/systemd/system/юнит в вашем текстовом редакторе (копирует установленную версию, если она еще не существует) и автоматически загружает её, когда вы закончите редактирование.

Drop-in snippets

Чтобы создать drop-in snippets для файла юнита /usr/lib/systemd/system/юнит, создайте каталог /etc/systemd/system/юнит.d/ и поместите файлы .conf там, чтобы отменять или добавлять новые опции. systemd будет анализировать эти файлы .conf и применять их поверх оригинального юнита.

Самый простой способ чтобы выполнить это, сделайте:

# systemctl edit юнит

Эта команда откроет /etc/systemd/system/юнит.d/override.conf (создаст его если это потребуется) в вашем текстовом редакторе и автоматически перезапустит юнит, когда вы закончите редактирование.

Примеры systemd Unit файлов

Рассмотрим следующий пример, — это написания systemd скрипта для запуска tomcat-а. Для этого, открываем файл:

# vim /etc/systemd/system/tomcat9.service

И записываем в него следующий код:

Description=Tomcat9
After=syslog.target network.target 


Type=forking
User=tomcat
Group=tomcat

Environment=CATALINA_PID=/usr/local/tomcat9/tomcat9.pid
Environment=TOMCAT_JAVA_HOME=/usr/bin/java
Environment=CATALINA_HOME=/usr/local/tomcat9
Environment=CATALINA_BASE=/usr/local/tomcat9
Environment=CATALINA_OPTS=
#Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment="JAVA_OPTS=-Dfile.encoding=UTF-8 -Dnet.sf.ehcache.skipUpdateCheck=true -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+UseParNewGC -XX:MaxPermSize=128m -Xms512m -Xmx512m"

ExecStart=/usr/local/tomcat9/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID


WantedBy=multi-user.target

Перезагрузим службу:

# systemctl daemon-reload

Добавим томкат в автозагрузку ОС:

# systemctl enable tomcat9

Перезапускаем томкат:

# systemctl restart tomcat9

Чтобы проверить статус, выполняем:

# systemctl status tomcat9
● tomcat9.service - Tomcat9
   Loaded: loaded (/etc/systemd/system/tomcat9.service; enabled)
   Active: active (running) since Tue 2017-05-09 22:04:58 EEST; 6s ago
  Process: 28528 ExecStop=/bin/kill -15 $MAINPID (code=exited, status=0/SUCCESS)
  Process: 28531 ExecStart=/usr/local/tomcat9/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 28541 (java)
   CGroup: /system.slice/tomcat9.service
           └─28541 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties -Djava.ut...

May 09 22:04:58 debian systemd: Starting Tomcat9...
May 09 22:04:58 debian startup.sh: Tomcat started.
May 09 22:04:58 debian systemd: Started Tomcat9.

Как видим, все четко работает. На этом, у меня все! Больше примеров будет дальше. Я буду добавлять их по мере необходимости. Но в основном, я использую шаблон что выше ( только немного его видоизменяю).

Статья «Пишем systemd Unit файл» завершена.

Создание Сервиса в Systemd

Создайте service-файл /etc/systemd/system/foo-daemon.service (замените foo-daemon на имя вашего сервиса):

$ sudo touch /etc/systemd/system/foo-daemon.service
$ sudo chmod 664 /etc/systemd/system/foo-daemon.service

1
2

$sudo touchetcsystemdsystemfoo-daemon.service

$sudo chmod664etcsystemdsystemfoo-daemon.service

Откройте файл foo-daemon.service и пропишите минимальные настройки, которые позволят управлять сервисом с помощью systemctl:

Description=Foo

ExecStart=/usr/sbin/foo-daemon

WantedBy=multi-user.target

1
2
3
4
5
6
7
8

Unit

Description=Foo

Service

ExecStart=usrsbinfoo-daemon

Install

WantedBy=multi-user.target

Путь К Демону: Если вы не знаете путь к демону, попробуйте which foo-daemon.

После создания нового service-файла необходимо перезапустить systemd:

$ sudo systemctl daemon-reload

1 $sudo systemctl daemon-reload

Теперь вы можете делать start, stop, restart и проверять status сервиса:

$ sudo systemctl start foo-daemon
$ sudo systemctl stop foo-daemon
$ sudo systemctl restart foo-daemon
$ systemctl status foo-daemon

1
2
3
4

$sudo systemctl start foo-daemon

$sudo systemctl stop foo-daemon

$sudo systemctl restart foo-daemon

$systemctl status foo-daemon

Чтобы добавить сервис в автозагрузку, необходимо активировать его:

$ sudo systemctl enable foo-daemon

1 $sudo systemctl enable foo-daemon

Чтобы проверить логи сервиса, выполните:

$ journalctl -u foo-daemon

1 $journalctl-ufoo-daemon

Уровни загрузки

Концепция systemd по сути схожа с уровнями выполнения (runlevel), но работающая немного по другому. Systemd использует понятие «целей» (target), каждая из которых имеет определенное имя и назначение, с возможностью одновременной работы с несколькими из них, например, для того, чтобы выяснить текущий уровень выполнения нужно выполнить:

$ systemctl list-units --type=target 

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

Уровень загрузки SysV Цель systemd Описание
runlevel0.target, poweroff.target Остановка системы
1, s, single runlevel1.target, rescue.target Однопользовательский режим (single user mode). Базовая система сконфигурирована, но демоны не запущены.
2 runlevel2.target,multi-user.target Пользовательский/Специфический уровень. Сконфигурирован также как уровень выполнения 3, но без поддержки сети
3 runlevel3.target,multi-user.target Многопользовательский режим (multiuser mode) с поддержкой сети
4 runlevel4.target,multi-user.target Не используется
5 runlevel5.target, graphical.target Многопользовательский графический режим с поддержкой сети
6 runlevel6.target, reboot.target Перезагрузка системы
emergency emergency.target Аварийный режим, который является аналогом 1-го уровня

Как уже отмечалось выше, в systemd уровни выполнения доступны через «целевые единицы«. Сменить текущий уровень выполнения можно с помощью следующей команды:

# systemctl isolate runlevel3.target 

Заметьте, что понятие уровней загрузки (runlevel) устарело, и, как правило, лучше воспользоваться современным именем, например:

# systemctl isolate multi-user.target 

Уровни выполнения (runlevel) эмулируются целевыми единицами (target), т.е. являются символическими ссылками, например, runlevel3.target -> multi-user.target.

Для изменения уровня загрузки по умолчанию, используйте символические ссылки или , например:

переключиться на 3-ий уровень выполнения:

# ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target 

или

# systemctl enable multi-user.target 

переключиться на 5-ый уровень выполнения:

# ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target 

или

# systemctl enable graphical.target

Метод изменения уровня загрузки с помощью systemctl возможен только, если целевой файл конфигурации содержит следующие строки:

Alias=default.target

В настоящий момент вышеприведенные строки присутствуют в нескольких файлах (целевых единиц): multi-user.target, graphical.target.

Обратите внимание, что systemd игнорирует файл .

Создание юнитов.

Очень часто может понадобится создание юнитов. Например если вы написали свое приложение на Python, и хотите описать его в виде сервиса для управления в systemd. Для примера создадим тестовый юнит test.service.

root@dedicated:~ mcedit /etc/systemd/system/test.service

Добавим в него содержимое:

Description=test service


Type=oneshot
ExecStart=/bin/echo "Hello World!"
RemainAfterExit=yes

Выполним переконфигурацию и запустим наш тестовый юнит

root@dedicated:~ systemctl daemon-reload
root@dedicated:~ systemctl start test.service
root@dedicated:~ systemctl status test.service

Умение создавать юниты может понадобится не только разработчикам, но и системным администраторам при установке различного программного обеспечения. Рандомно, для примера, обратимся к установке популярного брокера сообщений Apache Kafka. Для управления состоянием кластера и конфигурациями, Kafka использует службу zookiper. В руководстве будет предложено создать для него юнит. Или, например, вы устанавливаете Redmine с популярным web-сервером Puma для Ruby приложений. Для Puma так же нужно будет создать юнит. И так далее.

Work with systemd Timer Units

In this exercise, you build on the previous exercise to create and enable a timer unit to regularly run another systemd unit at a particular time or interval. Timer units can be defined at both the system level and the user level and can be used to define when systemd should run another unit. Timer units provide granular control over scheduled events and can act as an alternative to using the cron daemon to handle more subtle configurations.

Many system services include timer units to control when they run. A great example of a timer unit is included in the package that can be used to keep your system up to date when it performs regular dnf updates automatically. To see this in action at a system level, install the package and enable the timer unit:

You can view the unit file to see how this unit is configured:

Notable content in this unit, include a line that expects the to be met. The entry in the section of the configuration suggests that this action runs daily at 06h00. Also of interest is the entry, which can help prevent timer units from all firing at exactly the same time and pushing up system load suddenly.

The example provided here is part of a much more complex set of units. To better understand how timer units work, add a timer unit in user space to schedule the that you created in the previous exercise so that it runs at a regular interval.

  1. Create a timer unit file.

    This file specifies that the is required for this timer unit to run. This is a much stronger requirement than anything defined in a definition and the unit does not run if the requirement is not satisfied.

    The section defines that it loads the unit using an entry. The entry functions similarly to the options in a crontab definition but provides more granularity. In this case, the unit is defined to run every minute at 00 seconds.

  2. Since you have modified the systemd configuration, reload systemd daemons and restart the uptime service so that it can pick up the new timer unit:

  3. List the units to check that the and units are running.

  4. Monitor the log output in the journal to see the uptime output triggered by the uptime service running every minute.

    After a couple of minutes, several lines of output should have displayed.
    If you were paying close attention, you may notice that the uptime command does not always trigger exactly on the minute. This is an intentional feature within systemd timer functionality. Timer jobs are triggered with a randomizer that can allow a task to trigger with up to a minute in delay. This helps to prevent timers from all triggering at exactly the same time. You can force a timer to be incredibly accurate by setting the accuracy to within a nanosecond of the scheduled event, by adding the following configuration entry to the timer unit section:

    However, for most tasks, allowing for a degree of inaccuracy is sensible to prevent tasks from running too synchronously.

    You can use the Ctrl-C key combination to exit the journal when you have finished monitoring.

Что за шаблоны в юнит-файлах?

Шаблон в юнит-файле позволяет systemd работать с различными экземплярами юнитов при условии использования единственного юнит-файла. Для того, чтобы использоваться шаблоном из юнит-файла systemd, вы можете обратиться к этому юнит-файлу, используя специальный формат:

<имя_службы>@<аргумент>.service

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

В юнит-файлах systemd могут использоваться два идентификатора, которые позволяют осуществлять передачу аргумента экземпляру юнита.

  • Идентификатор позволяет осуществлять передачу аргумента, который будет особым образом отформатирован (из него будут убраны все спецсимволы)
  • Идентификатор позволяет осуществить передачу аргумента без какой-либо обработки.

Удаление спецсимволов из идентификатора перед его использованием осуществляется в соответствии со специальными правилами. При этом заменяются все символы, которые не могут использоваться в именах файлов.

Unit

Unit – это описание сервиса (в широком смысле этого слова). Unit-файл описывает все настройки сервиса, как его запускать, когда (очередность, зависимости) и что делать, если запуск не удался. Unit-ы, которые пишет пользователь руками – должны находится в и иметь окончание в названии. Юниты, которые устанавливают пакеты – находятся в ином месте. Если в нескольких папках лежит юнит с одним и тем же именем – применяется тот, что лежит в . Пример юнита:

Я специально взял юнит посложнее, чтобы пример был наглядным

На что обратить внимание:

  • Description – человеко-читаемое описание. Показывается по команде
  • After – начать загрузку после того, как начнется загрузка сервиса (или цели)
  • Wants – опциональная зависимость. Подробнее ниже, в разделе про зависимости
  • Environment – создать переменную окружения при запуске этого сервиса
  • WorkingDir – демон запускается из этой папки. Аналогично перед запуском
  • Type – тип сервиса. Подробнее ниже
  • User – имя пользователя, от которого будет запущен сервис
  • PermissionsStartOnly – используется, если перед стартом нужна какая-то специальная подготовка – создание папок, изменение прав и так далее. При эти действия будут выполнятся от root. Без – от имени User
  • ExecStart – что, собственно, запускать. Обязательно полный путь
  • RestartOn – при каких условиях перезапускать
  • WantedBy – в какой target должен быть установлен сервис. Подробнее – в разделе про target-ы

Виды Unit-ов

Systemd может обслуживать процессы с разным поведением. Тип описывает, как systemd будет с ним взаимодействовать. Есть следующие варианты:

  • – самый стандартный тип. Процесс остается в foreground, stdout перехватывается systemd. Это тип по умолчанию.
  • – прямая противоположность. Процесс должен форкнуться и отсоединится от foreground. Для этого типа юнитов должен быть указан pid через директиву .
  • – процесс, который успешно выполняется (не делая fork) и завершается. Пример – монтирование файловых систем. Рекомендуется добавить в юнит, чтобы результаты работы процесса остался в статусе юнита.
  • – аналог simple, но в этом случае сам процесс сообщит systemd о том, что он закончил загрузку и готов к работе.

Взаимодействие с unit-ами

После каждого изменения файла юнита (создание/изменение/удаление) – нужно перечитывать изменения, так как состояния юнитов systemd кеширует:

Запус, состояние, остановка:

Systemd имеет свою собственную реализацию логирования (хотя по умолчанию в syslog копию сообщения он тоже отправляет). Чтение сообщений от сервисов – командой journalctl. Команда очень мощная, умеет много. Ниже примеры

Управление зависимостями, очередность загрузки юнитов

Для управления зависимостями в unit есть ключевые слова , и :

  • – сервис начнет загрузку после того, как начнет загружаться сервис, указанный в .
  • – сервис начнет загрузку после того, как закончит загружаться сервис, указанный в . Статус загрузки этого сервиса не важен – даже если он упал и загрузится не смог – юнит попытается стартовать. То есть зависимость эта опциональная, и нужна она только для того, чтобы наш сервис начал загружаться не раньше, чем другой – закончит.
  • – сервис начнет загрузку после того, как сервис, указанный в закончит загрузку успешно. Если сервис-зависимость загрузится не смог – наш сервис так же упадет с ошибкой (точнее – он даже не будет стартовать).

Плюсы и минусы systemd

При старте запускает параллельно столько служб, сколько возможно в зависимости от стадии загрузки. Это заметно ускоряет запуск системы. Если замерить время от включения до входа, то использует его гораздо меньше, чем предшественники — например, .

— универсальный менеджер. Он управляет практически всей работающей системой. отвечает за работу запущенных служб и может рассказать все об их состоянии. Он также управляет монтированием файловой системы, аппаратной частью, процессами.

использует скомпилированные бинарные файлы. Все конфигурационные файлы открыты. Их можно менять через командную строку или . При необходимости можно добавить свои конфигурационные файлы.

Однако системные администраторы отмечают и минусы менеджера. Главный — он нарушает один из принципов философии — «Пишите программы, которые делают что-то одно и делают это хорошо». Принцип (акроним для «Keep it simple, stupid» — «Делай проще, тупица») требует максимальной простоты и самодостаточности от используемых инструментов, в этом плане — это скорее комплексный комбайн, который, помимо инициализации, выполняет еще огромное количество смежных функций. Из-за этого порой он нестабилен и без дополнительной тонкой настройки потребляет много ресурсов.

Завершение процессов пользователя при выходе из системы

Arch Linux создает пакет с помощью , устанавливая равным по умолчанию. Этот параметр предотвращает уничтожение пользовательских процессов, когда пользователь полностью выходит из системы. Чтобы изменить это поведение и убить все пользовательские процессы при выходе из системы, установите в .

Обратите внимание, что изменение этого параметра нарушает работу мультиплексоров терминала, таких как tmux и GNU Screen (Русский). Если вы измените этот параметр, вы все равно сможете использовать терминальный мультиплексор, используя следующим образом:

$ systemd-run --scope --user command args

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

$ systemd-run --scope --user screen -S foo

Запущенные с помощью процессы продолжат работу даже после выхода пользователя, если он залогинен в системе где-то ещё и служба всё ещё работает.

Изменение файлов юнитов

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

Для создания сниппета файла юнита (блок, который может использоваться для дополнения или замены параметров файла юнита по умолчанию) нужно воспользоваться опцией edit:

sudo systemctl edit nginx.service

Если нужно изменить все содержимое файла, а не создавать сниппет, воспользуйтесь флагом —full:

sudo systemctl edit --full nginx.service

После изменения файла юнита нужно перезагрузить сам процесс systemd для принятия изменений:

sudo systemctl daemon-reload

Основы управления сервисами (юнитами)

Базовый объект, с которым работает systemd, называется “юнитом” (unit). Есть много видов юнитов, но самым распространенным является служба (service, файл юнита заканчивается на .service). Основным инструментом для управления службами на сервере является команда systemctl.

У всех команд обычной системы инициализации есть эквиваленты в systemctl. В примерах мы будем использовать службу nginx.service. Если у вас её нет, установите ее при помощи менеджера пакетов.

Для запуска службы нужно ввести:

systemctl start nginx.service

Остановка осуществляется следующей командой:

systemctl stop nginx.service

Перезапуск службы:

systemctl restart nginx.service

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

systemctl reload nginx.service

Основные команды systemd

У есть несколько основных команд, которые быстро запоминаются при постоянном использовании менеджера.

systemctl start name.service — запустить сервис.

  • — остановить сервис.
  • — перезапустить сервис.
  • — узнать статус сервиса.
  • — добавить сервис в автозагрузку.
  • — удалить сервис из автозагрузки.
  • — проверить, находится ли сервис в списке автозагрузки.
  • — запретить запуск сервиса.
  • — разрешить запуск сервиса.
  • — показать службы, которые не запустились.
  • — показать страницу руководства сервиса.

systemctl daemon-reload — применить конфигурацию после изменения в описании сервиса.

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

Для удобства можно отсортировать службы по их текущему статусу. Есть четыре флага:

  1. — автозагрузка включена;
  2. — автозагрузка отключена;
  3. — служба скрыта;
  4. — служба в автозагрузке, вы не можете ей управлять.

Например, чтобы получить список всех служб, у которых отключена автоматическая загрузка, выполните команду

Посмотреть полную информацию о незагруженных юнитах:

С помощью также можно увидеть зависимости модуля. Например:

После выполнения команды в терминале отобразится список зависимостей службы :

sshd.service
├─system.slice
└─basic.target
  ├─microcode.service
  ├─rhel-autorelabel-mark.service
  ├─rhel-autorelabel.service
  ├─rhel-configure.service
  ├─rhel-dmesg.service
  ├─rhel-loadmodules.service
  ├─paths.target
  ├─slices.target

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

Вывод:

Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon

Если нужно отобразить одно свойства, добавьте в команду флаг -p с его именем. Например, посмотрите конфликты модуля :

Вывод:

Загрузите сайт на сервер

В качестве сайта выступит одиночный HTML-файлик. Зайдите на сервер с помощью ssh, перейдите в папку и скачайте заготовку сайта:

Почему /opt?

Куда класть код — это старый и холиварный вопрос. Столько времени прошло, сколько форумов исписано, а одного простого ответа так и нет…

Вам точно не стоит класть код в домашний каталог суперпользователя . Туда вы обычно попадаете, заходя на сервер по ssh. Если положите код в , то не избежите приключений с настройкой прав пользователей. Операционная система оберегает домашний каталог рута от посягательств других пользователей и запрещает им чтение файлов оттуда. Это станет проблемой при запуске Nginx, Gunicorn и других программ, часто работающих под другим пользователем.

Я советую класть код в папку . Это место специально выделено в ОС для программ, что собираются из исходников и живут обособлено от каталогов , и прочих.

Затем проверьте, что файлы скачались командой :

Уровни запуска и состояния

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

  • Однопользовательский режим
  • Многопользовательский режим без запуска сетевых сервисов
  • Многопользовательский режим с запуском сетевых сервисов
  • Остановка системы
  • Перезагрузка системы

Что касается меня, то я не вижу большой практической ценности в наличии нескольких уровней выполнения, но они есть. Вместо уровней запуска, systemd позволяет создавать различные состояния, предоставляя вам гибкий механизм создания различных конфигураций загрузки. Эти состояния формируются из нескольких юнит-файлов (unit files), объединенных в цели (targets). Целям присваиваются хорошие мнемонические имена, а не цифры. Эти юнит-файлы управляют сервисами, устройствами, сокетами и монтированием. Вы увидите, что это именно так, если посмотрите на предварительно подготовленные цели, которые идут вместе с systemd, например, в файле , используемые по умолчанию в CentOS 7:

Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
After=multi-user.target
Conflicts=rescue.target
Wants=display-manager.service
AllowIsolate=yes

Alias=default.target

А как выглядят юнит-файлы? Давайте заглянем в один из них. Юнит-файлы находятся в двух каталогах:

  • /etc/systemd/system/
  • /usr/lib/systemd/system/

Первый — тот, который мы можем использовать, а второй — этот тот, где юнит файлы устанавливают пакеты. Приоритет каталога выше приоритета каталога . Ура, у человека прав больше, чем у машины. Ниже показан юнит-файл для сервера Apache Web:

Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target

Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd/ $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
KillSignal=SIGCONT
PrivateTmp=true

WantedBy=multi.user.target

Такие файлы довольно понятны даже для новичков systemd, причем юнит-файлы немного проще, чем файл init для SysVInit. Ниже показан фрагмент из файла :

SCRIPTNAME="${0##*/}"
SCRIPTNAME="${SCRIPTNAME##}"
if  ; then
        if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
                DIR_SUFFIX="${APACHE_CONFDIR##/etc/apache2-}"
        else
                DIR_SUFFIX=

Весь файл размером в 410 строк.

Вы можете взглянуть на юнит-зависимости, и меня всегда удивляет, насколько они сложны:

$ systemctl list-dependencies httpd.service
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: