В этой статье мы рассмотрим систему инициализации Systemd, позволяющую гибко управлять демонами, являющуюся удобным инструментом, облегчающим администрирование операционных систем Linux. Основная цель Systemd — иметь полный контроль над процессами во время их запуска и выполнения. Systemd имеет простую и эффективную логику. Она поддерживает параллельную загрузку служб с заданными зависимостями, имеет собственную систему журналирования событий, имеет встроенные таймеры выполнения задач. Начиная с CentOS7, Debian8, Ubuntu 15.04, Fedora15, система инициализации Systemd установлена по умолчанию.
Как это работает: При запуске сервера запускается ядро, это является первым процессом, он имеет идентификатор «0». После того как процесс инициализировался, запускается процесс init с идентификатором «1». Init выполняет инициализацию системы, которую берет из рабочий директорий. В частности, в каталоге /sbin/init мы можем увидеть линк на /lib/systemd/systemd. Он уже в сою очередь, согласно своим параметрам запускает в фоновом режиме службы (демоны), которые находятся в каталоге /etc/init.d/
Systemd представляет собой описание конфигурации сервисов в виде юнитов, которые имеют следующую структуру каталогов:
/usr/lib/systemd/system/ - расположены юниты, которые созданы из установленных пакетов
/run/systemd/system/ - юниты, которые созданы во время выполнения программного обеспечения (в run-time)
/etc/systemd/system/ - юниты, которые создал администратор сервера. Так же здесь расположены юниты, которые отредактированы вручную.
Оглавление
- Юниты systemd
- Структура юнита systemd
- Редактирование юнитов
- Создание юнитов
- Анализ ошибок с помощью journalctl
- Интерфейс для systemd (опционально)
- Основные команды systemd
- Заключение
1. Юниты systemd.
Прежде всего, нужно разобраться что такое юнит, что означают его статус, и как их фильтровать. Unit - это описание сервиса в текстовом виде, где указаны операции, которые должны быть выполнены до и после запуска службы. Юнит — это описание параметров системы инициализации.
Наиболее часто, управление демонами происходит командами start|stop|reload|status|enable|disable. Для примера, мы можем проверить статус демона как каноничной подсистемы инициализации init (он же System V или SysV):
root@dedicated:~ /etc/init.d/nginx status
Общая команда будет иметь следующий вид:
root@dedicated:~ sudo service nginx status
...или выполнить тоже самое с помощью systemd:
root@dedicated:~ systemctl status nginx.service
Посмотреть список всех запущенных юнитов можно командой:
root@dedicated:~ systemctl
Мы увидим список всех запущенных юнитов, а так же их статус.
UNIT — имя юнита
LOAD — информирует нас о успешной загрузке конфигурации.
ACTIVE — Активный ли юнит.
SUB — более детальная системная информация о юните.
DESCRIPTION — краткое описание.
На скриншотах выше, в колонке UNIT, после префикса, указан тип юнита. Например *.service указывает, что юнит указывает на службу (nginx, apache и т.д.). Существует несколько возможных видов юнитов (socket, device, mount, swap, automount, target, snapshot, timer и другие). На данный момент многие из них нам не пригодятся, потому рассмотрим базовый *.service, на которые стоит обратить внимание. Задача на данный момент - указать путь, а не запутать читателя. Ссылка на руководство по углубленному изучению будет предоставлена в конце статьи.
Отфильтруем только службы:
root@dedicated:~ systemctl list-units --type=service
Отфильтруем неактивные юниты:
root@dedicated:~ systemctl list-units --all --state=inactive
Существуют следующие статусы: active, inactive, running, exited, dead, loaded, not-found, plugged, mounted, waiting, listening.
Посмотреть самую полную информацию, включая юниты, которые система по какой-то причине не загрузила:
root@dedicated:~ systemctl list-units --all
Отобразить список зависимостей определенного юнита
root@dedicated:~ systemctl list-dependencies nginx.service
Используя флаги, одной только командой systemctl вы можете получить представление о системе для анализа ее работы. Так же опытный администратор может отключить необязательные службы с автозагрузки, тем самым выполнив оптимизацию загрузки сервера.
2. Структура юнита systemd
Давайте рассмотрим файл юнита Nginx, и из чего он состоит. На первый взгляд, эта информация может показаться запутанной, но она вполне логична и обязательна для понимания.
root@dedicated:~ systemctl cat nginx.service
[Unit] — Обычно здесь описаны метаданные службы и её взаимодействие с другими службами.
Description — краткое описание демона
Documentation — страница man, где описана работа со службой, в данном случае Nginx
After — Дословно означает «После». Поле указывает, после каких демонов или событий данный юнит будет запущен. На нашем примере, юнит Nginx будет запущен после того, как поднимутся сетевые интерфейсы.
[Service] — Описывает конфигурацию. Применяется только для юнитов служб.
Type — Важный параметр. Описывает, каким образом демон будет запущен. В нашем варианте это forking, но вы можете столкнуться и с другими:
forking — после запуска демон ответвляется (fork), завершая родительский процесс;
simple — при запуске, демон переходит в режим ожидания, в своем первоначальном виде;
one-shot — одноразовое выполнение. Данный тип используется для скриптов, которые должны запуститься, и завершиться после выполнения.
PIDFile — указывает на основной процесс, который отслеживает systemd
ExecStartPre — основной путь и аргументы, с которыми будет запущена команда ДО запуска основного процесса
ExecStart — основной путь и аргументы, с которым будет запущен Nginx
ExecReload — указывает команду для перезапуска службы
ExecStop — команда для остановки службы
TimeoutStopSec — Указывает, что система будет ждать 5 секунд остановки службы, прежде чем остановить её принудительно
[Install] — описывает поведение юнита.
WantedBy — описывает как именно устройство будет включено. multi-user.target означает, что при запуске, в каталоге /etc/systemd/system будет создан каталог multi-user.target.wants, в котором будет создана символическая ссылка на службу. Это параметр зависимости с текущим блоком, когда вы остановите службу, эта ссылка будет удалена.
С доступным перечнем параметров вы можете ознакомится обратившись к руководству:
root@dedicated:~ man systemd.unit
А теперь в двух словах, чем нам может быть полезна эта информация. В зависимости от задач, мы эти юниты можем создавать, редактировать и настраивать их поведение. Мы можем указать порядок загрузки той или иной службы, настраивать зависимости между службами. Например, у нас имеется сервер с критической службой, которая всегда должна быть активна. Мы можем выставить параметр принудительно перезагрузки, если по каким-то причинам она не отвечает. Так же укажем информирование по e-mail об инциденте. В случае если «упал» Apache, он будет автоматически перезагружен без участия администратора. Администратор получит уведомление на e-mail и оказавшись у терминала, приступит к анализу, почему это произошло.
3. Редактирование юнитов
Напрямую юниты не редактируются. Для редактирования существует команда edit:
root@dedicated:~ systemctl edit --full nginx.service
Выше мы говорили про автоматический перезапуск служб. Давайте рассмотрим этот пример. Добавим в секции [Service] два параметра
Restart=on-failure RestartSec=60s
Чтобы изменения вступили в силу, перезапустим конфигурацию:
root@dedicated:~ systemctl daemon-reload
Проверим, что у нас получилось. Узнаем PID процесса:
root@dedicated:~ systemctl status nginx.service | grep PID Main PID: 12567 (nginx)
Завершим его:
root@dedicated:~ kill -9 12567
Известной уже командой проверим его статус
root@dedicated:~ systemctl status nginx.service
...ждем 60 секунд. И проверяем снова:
4. Создание юнитов.
Очень часто может понадобится создание юнитов. Например если вы написали свое приложение на Python, и хотите описать его в виде сервиса для управления в systemd. Для примера создадим тестовый юнит test.service.
root@dedicated:~ mcedit /etc/systemd/system/test.service
Добавим в него содержимое:
[Unit] Description=test service [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 так же нужно будет создать юнит. И так далее.
5. Анализ ошибок с помощью journalctl
Еще одна важная полезность — логи запущенных юнитов. Давайте вспомним первоначальный запуск сервера, когда на мониторе при запуске быстро бежит полотно информации. Иногда там можно увидеть ошибки запуска служб, на которые стоит обратить внимание. Если же вы перезагружаете сервер удаленно, то эту информацию вы не увидите вовсе. После загрузки Linux, мы всегда её можем отобразить для анализа. Хорошим тоном является анализировать логи после каждой перезагрузки сервера.
Для просмотра логов последней загрузки:
root@dedicated:~ journalctl -b
Логи всех загрузок
root@dedicated:~ journalctl
Отобразить список последних загрузок:
root@dedicated:~ journalctl --list-boots
Если мы хотим посмотреть лог загрузки за определенную дату, мы можем это сделать по boot_id, которые отображены в предыдущей команде:
root@dedicated:~ journalctl -b 9e8736b29ad549ab97923baf470382d6
Посмотреть все логи загрузки определённой службы:
root@dedicated:~ journalctl -u nginx
Посмотреть логи загрузки определённой службы в текущей загрузке:
root@dedicated:~ journalctl -b -u nginx
Будет полезна фильтрация логов по уровню ошибок. Всего существует 8 уровней:
0 — EMERG (самая критическая ошибка, служба неработоспособна);
1 — ALERT (требует вмешательства);
2 — CRIT (критическая ошибка);
3 — ERR (ошибка);
4 — WARNING (предупреждение);
5 — NOTICE (следует обратить внимание);
6 — INFO (информационное сообщение);
7 — DEBUG
Отобразим все сообщения WARNING по идентификатору «4»:
root@dedicated:~ journalctl -p 4 -b
Посмотреть последние 10 записей:
root@dedicated:~ journalctl -n 10
В реальном времени:
root@dedicated:~ journalctl -f
Для наглядности, предлагаю «помучить» наш Nginx. Для этого убедимся, что служба работоспособна, затем преднамеренно её поломаем, изменив название главного конфигурационного файла и перезапустим Nginx.
root@dedicated:~ systemctl status nginx.service root@dedicated:~ mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.default root@dedicated:~ systemctl stop nginx.service root@dedicated:~ systemctl start nginx.service
Ожидаемо, мы получим сообщение об ошибке. Без nginx.conf служба не может быть запущена:
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
Обратимся к логам:
root@dedicated:~ journalctl -xe
root@dedicated:~ systemctl status nginx.service
6. Интерфейс для systemd (опционально)
Chkservice — удобная утилита для управления юнитами systemd. В Debian 10 она доступна прямо из репозитория:
root@dedicated:~ apt install chkservice
Если в репозиториях вашего дистрибутива она отсутствует, установку можно выполнить с доступного PPA разработчиков:
root@dedicated:~ add-apt-repository ppa:linuxenko/chkservice root@dedicated:~ apt-get update root@dedicated:~ apt-get install chkservice
Запустить интерфейс:
root@dedicated:~ chkservice
Управление выполняется следующим образом, стрелками «вверх» и «вниз». Запустить юнит — клавиша «r», остановить — клавиша «s». Будьте осторожны, после нажатия клавиши, сигнал немедленно отправляет команду на выполнения без предупреждений.
7. Основные команды 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
Запретить запуск сервиса ( при котором "service name-app start" не отработает). И разрешить:
systemctl mask name.service systemctl umask name.service
Отобразить службы, которые не смогли запуститься:
systemctl --state=failed
Отобразить страницу руководства:
systemctl help name.service
Применить конфигурацию после внесения изменений в описание юнита:
systemctl daemon-reload
8. Заключение
Уже много лет не утихают споры, нужен ли systemd как замена init. Доводы двух сторон имеют право на существование, однако они всё дальше уходят от конкретики в дебри философии Linux. Systemd многие популярные дистрибутивы сделали системой инициализации по умолчанию, это уже та причина-минимум, почему стоит её освоить. Фактически она стала стандартом. В рамках одной статьи невозможно сполна раскрыть тему, потому мы старались своими словами и доступно объяснить читателю азы, которые уже можно применить на практике и которые поспособствуют старту к углубленному изучению systemd. Залог стабильной работы сервера — глубокое понимание работы его служб, их взаимодействия и тонкая конфигурация под свои задачи. Для более глубокого изучения, мы рекомендуем прочитать замечательный перевод книги Леннарта Пёттеринга, разработчика systemd.
В дата-центре FREEhost.UA Вы можете арендовать выделенный сервер или виртуальный сервер с OS семейства Linux или FreeBSD. Сервер Вы получаете полностью настроенным и готовым к работе. Если в процессе использования услуги у Вас возникнут вопросы, мы будем рады на них ответить.
Дата: 06.03.2020 Автор: Евгений
|
|
Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:
comments powered by Disqus