Применение systemd: только самое главное
Systemd
— это менеджер системы и служб Linux. Он инициализирует другие демоны в системе при загрузке. Основная цель systemd
— полный контроль над запуском и выполнением процессов, описанных в его конфигурации. Какая у менеджера архитектура и как его применять — узнаете из этой обзорной статьи.
Содержание:
1. Плюсы и минусы systemd
2. Архитектура systemd
3. Возможности systemd
4. Юниты systemd
5. Структура юнита systemd
6. Редактирование юнитов
7. Создание юнитов
8. Анализ ошибок с помощью journalctl
9. Интерфейс для systemd
10. Основные команды systemd
Итоги
1. Плюсы и минусы systemd
При старте Systemd
запускает параллельно столько служб, сколько возможно в зависимости от стадии загрузки. Это заметно ускоряет запуск системы. Если замерить время от включения до входа, то systemd
использует его гораздо меньше, чем предшественники — например, SystemV
.
Systemd
— универсальный менеджер. Он управляет практически всей работающей системой. Systemd
отвечает за работу запущенных служб и может рассказать все об их состоянии. Он также управляет монтированием файловой системы, аппаратной частью, процессами.
Systemd
использует скомпилированные бинарные файлы. Все конфигурационные файлы открыты. Их можно менять через командную строку или GUI
. При необходимости можно добавить свои конфигурационные файлы.
Однако системные администраторы отмечают и минусы менеджера. Главный — он нарушает один из принципов философии UNIX
— «Пишите программы, которые делают что-то одно и делают это хорошо». Принцип KISS
(акроним для «Keep it simple, stupid» — «Делай проще, тупица») требует максимальной простоты и самодостаточности от используемых инструментов, в этом плане Systemd
— это скорее комплексный комбайн, который, помимо инициализации, выполняет еще огромное количество смежных функций. Из-за этого порой он нестабилен и без дополнительной тонкой настройки потребляет много ресурсов.
2. Архитектура systemd
На этой схеме изображены компоненты, которые входят в systemd
. Это упрощенное представление, которое показывает только основную архитектуру. В нем размещены не все файлы и службы. Здесь также нет информации о сложном потоке данных.
Описание и изучение всех возможностей systemd займет много времени. Но у вас нет необходимости помнить их все. Достаточно знать о компонентах и программах, которые управляют системой и службами. Другую информацию всегда можно уточнить в документации или встроенной справке (man
).
3. Возможности systemd
В зависимости от используемых при компиляции параметров systemd включает до 69 файлов. С их помощью выполняются следующие задачи:
Systemd
какPID 1
осуществляет запуск стольких служб в параллельном режиме, сколько ему нужно. Благодаря этому загрузка ускоряется.Systemd
создает журналы для хранения системных логов и дает инструменты для управления записями.Systemctl
дает пользовательский интерфейс для управления службами.- Обеспечивается обратная совместимость благодаря поддержке
SystemV
иLSB
. - Управление службами и логи дают информацию о состоянии служб.
- Можно управлять сокетами.
- Таймеры предоставляют расширенные возможности для планирования, включая запуск скриптов по времени от старта системы.
- Можно монтировать и размонтировать файловые системы с иерархическим уведомлением для безопасного каскадирования.
- Можно создавать временные файлы и управлять ими, в том числе удалять.
- Можно запускать скрипты при подключении или отключении устройств.
- Можно через анализ последовательности загрузки найти службы, запуск которых отнимает больше всего ресурсов или вызывает сбои.
Эти и другие задачи решаются различными демонами, которые управляют программами и конфигурационными файлами в составе пакета systemd.
4. Юниты systemd
Юнит — это описание сервиса в текстовом виде. В нем указаны операции, которые выполняются до и после запуска службы. По сути, это описание параметров инициализации.
Все юниты разложены по трем каталогам:
- /
usr
/lib
/systemd
/system
/ — юниты из установленных пакетов RPM. Например, Nginx, MySQL, Apache. - /
run
/systemd
/system
/ — юниты, созданные в рантайме. - /
etc
/systemd
/system
/ — юниты, созданные системными администраторами.
Посмотреть список всех запущенных юнитов можно командой:
systemctl
В терминале отобразится также статус каждой службы. Основные параметры:
UNIT
— название юнита.LOAD
— информация об успешной загрузке конфигурации.ACTIVE
— сообщение о статусе. Может быть такжеINACTIVE
,LOADED
и другие.SUB
— детальная системная информация об юните.DESCRIPTION
— краткое описание юнита.
Юниты бывают разных типов. Например, юнит службы имеет тип *.service
. Все виды:
Тип | Что делает |
.service |
Описывает, как управлять службой или приложением на сервере. |
.socket |
Описывает сетевой, IPC-сокет или FIFO-буфер, который используется для активации сокета. |
.device |
Описывает устройство, указанное как необходимое для управления systemd с помощью udev или файловой системы sysfs . |
.mount |
Определяет точку монтирования в системе, которой управляет systemd . |
.automount |
Настраивает точку монтирования, которая будет автоматически установлена. |
.swap |
Описывает пространство подкачки в системе (swap-файл). |
.target |
Обеспечивает точки синхронизации для других устройств при загрузке или изменении состояний. |
.path |
Определяет путь, который может использоваться для активации на основе пути. |
.timer |
Определяет таймер, который управляется systemd для задержки или активации по плану. |
.snapshot |
Позволяет восстановить текущее состояние системы после изменений. |
.slice |
Связан с узлами группы управления Linux, что позволяет ограничить ресурсы или назначить их для любых процессов, связанных с slice . |
.scope |
Создается автоматически systemd из информации, которую получил от интерфейса шины. |
В этой статье мы будем работать с юнитами *.service
. Чтобы отфильтровать их, выполните команду:
systemctl list-units --type=service
Также можно выбрать только неактивные юниты служб:
systemctl list-units --all --state=inactive
Можно использовать другие статусы: active
, inactive
, running
, exited
, dead
, loaded
, not-found
, plugged
, mounted
, waiting
, listening
.
5. Структура юнита systemd
Структура может показаться сложной. Но на самом деле она строгая и очень логичная. Каждый юнит представляет собой текстовый файл. Внутри него — обязательные секции и переменные.
Для наглядности посмотрите на пример юнита sshd:
[Unit] Description=OpenSSH server daemon Documentation=man:sshd(8) man:sshd_config(5) After=network.target sshd-keygen.target Wants=sshd-keygen.target [Service] Type=notify EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config EnvironmentFile=-/etc/sysconfig/sshd ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target
Давайте разберем все секции.
Unit
Первая обязательная секция, в которой описываются метаданные службы и правила взаимодействия с другими службами. В ней доступны следующие переменные:
Description
— короткое описание демона.Documentation
— страница man, на которой расписан порядок взаимодействия со службой.After
— указание на то, после каких демонов и событий демон запускается. Например, юнитNginx
поднимается после запуска сетевых интерфейсов. Можно указать целую группу других сервисов.Requires
— какой сервис необходим для запуска юнита.Wants
— какой сервис желательно запустить перед стартом юнита.
Если указать сервис в Requires
, но не прописать его в After
, то он будет запущен параллельно с юнитом, который вы настраиваете.
Пример оформления секции Unit
:
[Unit] Description=MyUnit After=syslog.target After=network.target After=nginx.service After=mysql.service Requires=mysql.service Wants=redis.service
Service
Вторая обязательная секция для описания конфигурации. Здесь вы указываете, какими командами и под каким пользователем запускать сервис.
Type
— описывает, как запустится демон. Есть несколько вариантов:simple
(по умолчанию) —systemd
ожидает, что служба запустится незамедлительно. Процесс не должен разветвляться.forking
— после запуска демон ответвляется (делает форк), родительский процесс завершается. Такой подход используется для запуска классических демонов.one-shot
— одноразовое выполнение. Используется для скриптов, которые запускаются и завершаются после выполнения.notify
— аналогsimple
, но в этом случае сам процесс сообщит systemd о том, что он закончил загрузку и готов к работе.PIDFile
— ссылка на основной процесс, который отслеживает systemd.WorkingDirectory
— рабочая директория. Становится текущей перед запуском стартап команд.User
— пользователь, под которым надо запускать сервис.Group
— группа, под которой надо запускать сервис.Environment
— переменная окружения.OOMScoreAdjust
— запрет на убийство сервиса из-за нехватки памяти или срабатывания механизма OOM (-1000 — полный запрет).ExecStart
— команда для старта сервиса.ExecReload
— команда для перезапуска сервиса.ExecStop
— команда для остановки сервиса.TimeoutSec
— время в секундах, которое сервис ожидает отработки старт- или стоп-команд.Restart
— настройки перезапуска.
Пример оформления секции Service
:
[Service] Type=forking PIDFile=/work/www/myunit/shared/tmp/pids/service.pid WorkingDirectory=/work/www/myunit/current User=myunit Group=myunit Environment=RACK_ENV=production OOMScoreAdjust=-1000 ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart TimeoutSec=300
Install
Третья обязательная секция. В ней описывается на каком уровне запуска стартует настраиваемый сервис.
Переменная WantedBy
сообщает, как устройство включится. Например, multi-user.target
означает, что при запуске в директории /etc
/systemd
/system
появится каталог multi-user.target.wants
. В нем будет ссылка на службу, которая удалится после остановки службы.
Пример оформления секции Install
:
[Install] WantedBy=multi-user.target
Перечень доступных параметров указан в руководстве. Вызвать его можно командой:
man systemd.unit
Для определения того, какие сервисы и в каком порядке будут загружены, используется Target
. Его основные виды:
poweroff
– отключение системы;rescue
– режим восстановления, однопользовательский (init 1);multi-user
– сетевой режим без графической оболочки, (init 3);graphical
– сетевой режим с графической оболочкой (init 5);reboot
– перезагрузка;emergency
– аварийная командная строка, минимальный функционал.
Цели могут наследоваться. Пример взаимодействия с ними:
#список целей systemctl list-units --type=target #перейти в нужную цель (например – загрузится из сетевого режима в графический) systemctl isolate graphical.target #выбрать target по умолчанию systemctl set-default multi-user.target
6. Редактирование юнитов
Юниты нельзя редактировать напрямую. Для этого используется команда edit
:
systemctl edit --full nginx.service
Теперь можно добавить в описание юнита несколько переменных. Например, измените секцию Service
. Добавьте в нее два параметра:
Restart=on-failure RestartSec=60s
Чтобы применить изменения, перезагрузите службу:
systemctl daemon-reload
Убедитесь, что конфигурация обновилась. Сначала узнайте PID процесса:
systemctl status nginx.service | grep PID Main PID: 12567 (nginx)
Затем завершите его:
kill -9 12567
Проверьте статус службы:
systemctl status nginx.service
Служба должна находиться в стадии автозапуска. Через 60 секунд (указали именно столько в параметрах юнита) статус изменится на active
(running
).
7. Создание юнитов
Вы также можете создавать свои юниты. Например, вы написали приложение на Python и хотите добавить его в виде сервиса, которым будете управлять через systemd
. В качестве примера создайте юнит item.service
:
mcedit /etc/systemd/system/test.service
В описании юнита добавьте обязательные секции:
[Unit] Description=test service [Service] Type=oneshot ExecStart=/bin/echo "Hello World!" RemainAfterExit=yes [Install] WantedBy=multi-user.target
Теперь нужно применить изменения в конфигурации:
systemctl daemon-reload
Следующий шаг — запуск юнита:
systemctl start test.service
Напоследок проверьте его статус:
systemctl status test.service
Навык создания юнитов пригодится и разработчикам, и системным администраторам для установки ПО. Например, в Apache Kafka для управления состоянием кластера и конфигурациями используется служба zookiper
. Для нее нужно создавать юнит. И подобные задачи возникают достаточно часто.
В зависимости от задач можно создавать и редактировать юниты, указывать порядок загрузки, настраивать зависимости между разными службами. Например, у вас есть критически важный сервис. В конфигурации можно установить принудительную перезагрузку, если он долго не отвечает. Там же можно добавить отправку уведомления на почту администратора. Это сильно упрощает мониторинг и помогает быстрее реагировать на инциденты.
8. Анализ ошибок с помощью journalctl
Еще одна полезная возможность — логирование запущенных юнитов. При первом запуске сервиса в командной строке отображается очень много информации. В этом «полотне» можно обнаружить ошибки, которые следует исправить. Хороший тон — смотреть логи после каждой перезагрузки сервиса.
Чтобы посмотреть логи последней загрузки, выполните команду:
journalctl -b
Чтобы посмотреть логи всех загрузок:
journalctl
Чтобы увидеть список всех загрузок:
journalctl --list-boots
Если хотите посмотреть лог загрузки за конкретную дату, используйте значение boot_id
. Оно отображается после выполнения предыдущей команды. Boot-id добавляется в качестве аргумента:
journalctl -b 9e8736b29ad549ab97923baf470382d6
Можно также посмотреть все загрузки определенного сервиса. Например, проанализируйте работу Nginx
:
journalctl -b -u nginx
Чтобы понимать логи, полезно знать уровни ошибок. Всего их восемь:
0 — EMERG
(самая критическая ошибка, служба неработоспособна);1 — ALERT
(требует вмешательства);2 — CRIT
(критическая ошибка);3 — ERR
(ошибка);4 — WARNING
(предупреждение);5 — NOTICE
(следует обратить внимание);6 — INFO
(информационное сообщение);7 — DEBUG
.
Используя номера уровней, можно фильтровать логи. Например, получите только ERR
:
journalctl -p 3 -b
Посмотрите последние пять записей:
journalctl -n 5
В реальном времени:
journalctl -f
В качестве примера сломаем службу Nginx
:
systemctl status nginx.service mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.default systemctl stop nginx.service systemctl start nginx.service
Сначала мы проверили статус сервиса, затем переименовали конфигурационный файл, остановили и заново стартовали юнит. В результате вылетела ошибка —
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
В логах ошибка тоже отмечена:
journalctl -xe
Если проверить статус, то тоже появится сообщение об ошибке:
systemctl status nginx.service
Чтобы исправить ошибку, переименуйте файл обратно.
9. Интерфейс для systemd
Вы можете установить удобную утилиту для управления юнитами systemd — Chkservice
. В Debian 10, например, она поставляется в репозитории. Установить ее можно командой:
apt install chkservice
Если в репозитории вашего дистрибутива нет Chkservice
, установите утилиту этой командой:
add-apt-repository ppa:linuxenko/chkservice apt-get update apt-get install chkservice
Интерфейс запускается командой:
chkservice
Для управления используются клавиши вверх и вниз. Запуск юнита — клавиша R, остановка — клавиша S. После нажатия на клавишу сигнал отправляется без уведомлений. Учитывайте это при работе с юнитами.
10. Основные команды systemd
У systemd
есть несколько основных команд, которые быстро запоминаются при постоянном использовании менеджера.
systemctl start name.service
— запустить сервис.
systemctl stop name.service
— остановить сервис.systemctl restart name.service
— перезапустить сервис.systemctl status name.service
— узнать статус сервиса.systemctl enable name.service
— добавить сервис в автозагрузку.systemctl disable name.service
— удалить сервис из автозагрузки.systemctl is-enabled name.service
— проверить, находится ли сервис в списке автозагрузки.systemctl mask name.service
— запретить запуск сервиса.systemctl umask name.service
— разрешить запуск сервиса.systemctl --state=failed
— показать службы, которые не запустились.systemctl help name.service
— показать страницу руководства сервиса.
systemctl daemon-reload
— применить конфигурацию после изменения в описании сервиса.
Systemd
помогает настроить автоматическую загрузку служб при запуске системы. Чтобы посмотреть полный список автозагрузки, выполните команду:
systemctl list-unit-files
Для удобства можно отсортировать службы по их текущему статусу. Есть четыре флага:
enabled
— автозагрузка включена;disabled
— автозагрузка отключена;masked
— служба скрыта;static
— служба в автозагрузке, вы не можете ей управлять.
Например, чтобы получить список всех служб, у которых отключена автоматическая загрузка, выполните команду
systemctl list-unit-files --state disabled
Посмотреть полную информацию о незагруженных юнитах:
systemctl list-units --all
С помощью systemctl
также можно увидеть зависимости модуля. Например:
systemctl show sshd.service
После выполнения команды в терминале отобразится список зависимостей службы sshd
:
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
Вы также можете посмотреть свойства любого юнита. Используйте команду:
systemctl show sshd.service
Вывод:
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 с его именем. Например, посмотрите конфликты модуля sshd
:
systemctl show sshd.service -p Conflicts
Вывод:
Conflicts=shutdown.target
Итоги
Споры о плюсах и минусах systemd
и сравнения с другими менеджерами продолжаются. Но в пользу этой популярной системы говорит то, что во многих дистрибутивах она используется по умолчанию. Среди них Debian GNU/Linux 8+, Ubuntu 15.10+, CentOS 7+, RHEL 7+ и другие. Без systemd
поставляются форки Debian и Arch, Gentoo, Void Linux, *BSD системы.
Если хотите еще больше узнать о systemd, посмотрите это на редкость информативное видео:
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: