open atlas
↑ К треку
Linux: операционная система LIN · 03 · 01

Юниты и systemctl

systemd управляет всем через юниты — типизированные объекты с объявленными зависимостями. systemctl — инструмент для проверки, запуска, остановки, включения и отключения юнитов. Enabled означает запуск при загрузке; active — запущен прямо сейчас.

LIN Junior ◷ 20 min
Уровень
ОсновыJuniorMiddleSenior

Ты вводишь sudo systemctl restart nginx после изменения конфига, и сервис поднимается меньше чем за секунду — никаких shell-скриптов, охоты за PID-файлами, ручного /etc/init.d/nginx stop && sleep 2 && /etc/init.d/nginx start. Но когда сервер перезагружается и nginx непонятно почему не работает, ты вводишь systemctl status nginx и сразу видишь: он завершился с кодом 1 через три секунды после загрузки, потому что /var/log/nginx ещё не существовал. Ты узнал за десять секунд то, на что ушло бы десять минут архивного исследования логов до эпохи systemd. Именно такую скорость отладки даёт модель юнитов systemd.

Цель

После этого урока ты сможешь назвать шесть основных типов юнитов и что каждый из них управляет, использовать systemctl для запуска, остановки, включения, отключения и проверки юнитов, объяснить разницу между enabled и active, и читать вывод systemctl status для определения причины сбоя сервиса.

1

Всё, чем управляет systemd, является юнитом — типизированным объектом с именем, оканчивающимся на расширение типа. Шесть типов, которые ты встретишь чаще всего:

РасширениеЧто управляет
.serviceДемон или однократный процесс
.socketСетевой или IPC-сокет (для socket activation)
.timerЗапланированный триггер (замена cron)
.targetИменованная точка синхронизации или группа
.mountМонтирование файловой системы (автогенерируется из fstab)
.pathСлежение за путём в файловой системе

Имена юнитов следуют шаблону имя.тип: sshd.service, multi-user.target, apt-daily.timer. Тип сообщает systemd, какие ключи unit-файла допустимы и какую модель активации использовать.

# Список всех загруженных юнитов с их состоянием
systemctl list-units

# Только юниты типа service
systemctl list-units --type=service

# Все известные юниты, включая незагруженные
systemctl list-unit-files
2

systemctl status — первая команда, которую ты запускаешь при проблемах. Она сообщает много. Вывод насыщенный, но структурированный:

systemctl status nginx.service

Типичный вывод здорового сервиса:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-01-15 09:22:34 UTC; 3h 12min ago
       Docs: man:nginx(8)
   Main PID: 1234 (nginx)
      Tasks: 2 (limit: 4672)
     Memory: 5.8M
        CPU: 421ms
     CGroup: /system.slice/nginx.service
             ├─1234 "nginx: master process /usr/sbin/nginx -g daemon off;"
             └─1235 "nginx: worker process"

Jan 15 09:22:34 hostname systemd[1]: Starting A high performance web server...
Jan 15 09:22:34 hostname systemd[1]: Started A high performance web server.

Ключевые поля: Loaded показывает, разобрал ли systemd unit-файл и включён ли юнит. Active — состояние во время выполнения: active (running), active (exited), inactive (dead) или failed. Блок CGroup показывает точное дерево процессов. Хвост лога — последние записи журнала только для этого юнита.

3

Start, stop и restart управляют состоянием во время выполнения. Эти изменения действуют только до следующей перезагрузки — они не влияют на автозапуск юнита:

# Запустить остановленный юнит
sudo systemctl start nginx.service

# Остановить запущенный юнит (отправляет SIGTERM, затем SIGKILL по таймауту)
sudo systemctl stop nginx.service

# Перезапустить: стоп, затем старт (заменяет процесс)
sudo systemctl restart nginx.service

# Reload: отправить SIGHUP для перезагрузки конфига без остановки (если сервис поддерживает)
sudo systemctl reload nginx.service

# Reload-or-restart: предпочесть reload, откатиться на restart
sudo systemctl reload-or-restart nginx.service

Суффикс .service можно опустить при отсутствии неоднозначности — systemctl restart nginx работает так же, как systemctl restart nginx.service.

4

Enable и disable управляют тем, запускается ли юнит при загрузке — это отдельно от того, запущен ли он сейчас. Enable устанавливает симлинки в директорию target; disable их удаляет:

# Enable: создать симлинк для запуска при загрузке
sudo systemctl enable nginx.service

# Enable И запустить прямо сейчас (часто используется для новых сервисов)
sudo systemctl enable --now nginx.service

# Disable: удалить симлинк (не останавливает запущенный сервис)
sudo systemctl disable nginx.service

# Disable И остановить прямо сейчас
sudo systemctl disable --now nginx.service

После enable строка Loaded: в выводе systemctl status меняется с disabled на enabled. Теперь юнит подключён к multi-user.target (или к тому, что указано в WantedBy= в секции [Install]). После disable симлинк удаляется — юнит не запустится при следующей загрузке, но если он сейчас работает, то продолжает работать до остановки или перезагрузки.

5

Active vs enabled — самый частый источник путаницы у новых операторов. Это независимые оси:

Enabled (запускается при загрузке)Disabled (не запускается при загрузке)
Active (запущен сейчас)Нормальный production-сервисЗапущен вручную в этой сессии
Inactive (не запущен)Запустится при следующей загрузкеПолностью выключен

Сервис может быть запущен, но disabled (запустили вручную, не переживёт перезагрузку), или enabled, но не запущен (не смог запуститься). Используй is-active и is-enabled для скриптинга:

# Код выхода 0 если active, ненулевой если нет
systemctl is-active nginx.service

# Код выхода 0 если enabled, ненулевой если нет
systemctl is-enabled nginx.service

# Проверить оба условия
if systemctl is-active --quiet nginx && systemctl is-enabled --quiet nginx; then
  echo "nginx работает и будет стартовать при загрузке"
fi
Разбор примера

Диагностика сервиса, который работал вчера, но не работает сегодня.

После незапланированной перезагрузки разработчик сообщает, что их кастомный API-сервис не отвечает. Вот рабочий процесс оператора:

# Шаг 1: проверить текущее состояние
systemctl status myapi.service
# Вывод: Active: inactive (dead)
# Loaded: loaded (/etc/systemd/system/myapi.service; disabled; ...)

# Шаг 2: 'disabled' говорит всё
# Сервис был запущен вручную, но никогда не включался — не пережил перезагрузку.

# Шаг 3: исправить сейчас И для будущих загрузок
sudo systemctl enable --now myapi.service

# Шаг 4: проверить
systemctl status myapi.service
# Active: active (running)
# Loaded: loaded (...; enabled; ...)

Ошибка была в том, что тот, кто деплоил сервис, запустил systemctl start, но не systemctl enable. Сервис работал нормально до первой перезагрузки.

Почему это работает

macOS использует launchctl и plist-файлы launchd вместо unit-файлов systemd. Концепции совпадают: .plist в /Library/LaunchDaemons/ аналогичен .service-файлу с WantedBy=multi-user.target. launchctl load похож на systemctl enable --now. В launchd нет разделения на enabled и active — загрузка plist сразу регистрирует и запускает его.

Частая ошибка

Распространённая ошибка: редактировать /lib/systemd/system/nginx.service напрямую вместо создания переопределения в /etc/systemd/system/. Файлы в /lib/ принадлежат пакетному менеджеру и будут молча перезаписаны при следующем apt upgrade. Всегда помещай локальные настройки в /etc/systemd/system/ — либо полный файл замены, либо drop-in директорию (nginx.service.d/override.conf).

Проверь себя
Викторина

Ты запускаешь `systemctl enable myapp.service` без ошибок. Час спустя коллега проверяет и обнаруживает, что myapp не запущен. Что из следующего лучше всего объясняет это?

Итог

systemd моделирует всю систему как юниты — типизированные объекты (.service, .socket, .timer, .target, .mount, .path) с объявленными зависимостями. systemctl — CLI для управления ими. Самое важное концептуальное разделение: enabled (симлинк для загрузки установлен) не зависит от active (запущен прямо сейчас). systemctl start запускает что-то сейчас; systemctl enable обеспечивает выживание после перезагрузок. systemctl status показывает обе оси плюс хвост журнала — это первая команда при любых проблемах. Всегда помещай локальные кастомизации юнитов в /etc/systemd/system/, никогда в /lib/systemd/system/.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

Примени это

Примени этот урок в реальном проекте.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources1
expand
  1. 01

Trademarks belong to their respective owners. Editorial reference only.