Привет, Хабр! Systemd - скелет современного Linux. Он управляет не только службами, но и таймерами, монтированием, логированием... Понимать его = значительно повысить эффективность администрирования системы.
Данное руководство - исключительно технические аспекты: архитектура, юниты, cgroups, работа с журналами. Только команды и конфиги.
Введение
В мире Linux и Unix-подобных систем исторически доминировала система инициализации SysVinit. Её процесс загрузки был последовательным и понятным: она запускала скрипты (обычно расположенные в /etc/rc.d/
или /etc/init.d/
) по одному, в строгом порядке, определяемом симлинками в каталогах rcN.d
.
Но с развитием Linux и увеличением сложности систем - недостатки SysVinit стали вполне очевидны:
Последовательный запуск: скрипты выполнялись один за другим. Если служба не зависела от другой - она всё равно ждала своей очереди, что замедляло загрузку.
Отсутствие контроля за процессами. Init только запускал скрипты, но не мог отслеживать состояние запущенных служб (упала? требует перезагрузки?).
Разрозненность логирования. Каждая служба вела логи "по-своему" (в
/var/log/
), не было какого-то единого централизованного интерфейса для просмотра логов.
Полагаю, именно эти проблемы привели к появлению альтернатив (Upstart, OpenRC), но именно systemd, представленный Леннартом Поттерлингом в 2010 году, стал неким "де-факто" стандартом для множества крупных дистрибутивов (Fedora, Debian, Ubuntu, Arch и др.). Он был разработан как кардинально новое решение для преодоления ограничений.
Технические аспекты systemd
1. Архитектура и основные компоненты
Systemd - не единая бинарная программа, а набор связанных компонентов, образующих "каркас" системы. Его ядро - демон systemd
(PID 1), который является прямым потомком ядра и управляет всеми остальными процессами.
Ключевые технические компоненты:
systemd
(PID 1): главный демон. Отвечает за запуск и поддержание юнитов, отслеживание процессов (через cgroups), обработку сигналов от ядра.systemctl
: основной CLI-инструмент для взаимодействия с демоном. Не просто запускает скрипты, а отправляет D-Bus-сообщения демонуsystemd
, который выполняет запрошенные действия.journald
: демон журналирования. Интегрирован напрямую с демономsystemd
, что позволяет захватывать stdout/stderr каждого сервиса и "обогащать" записи лога метаданными (например,SYSTEMDUNIT=ssh.service
).udev
менеджер устройств. Управляет устройственными узлами в/dev
, загружает firmware и модули ядра. Тесно интегрирован с systemd для активации устройств.networkd
,timedated
,logind
: специализированные демоны для управления сетью, системным временем и сеансами пользователей (логином).
2. Юниты
Юниты - абстракции системных ресурсов. Их конфигурация описывается в декларативных файлах (обычно в /usr/lib/systemd/system/
, переопределяются в /etc/systemd/system/
).
Основные типы юнитов:
Service (
.service
): cамый распространённый тип. Описывает процесс (демон) и команды для управления им (ExecStart=
,ExecStop=
).Socket (
.socket
): описывает сокет (сетевой, IPC или FIFO). Механизм "socket-based activation" - ключевая особенность: демонsystemd
прослушивает сокет и запускает соответствующий сервис (.service
) только при поступлении первого подключения. Это экономит ресурсы для редко используемых служб.Timer (
.timer
): альтернатива cron. Позволяет планировать задачи на основе календарных выражений (OnCalendar=*-*-* 00:00:00
) или относительных интервалов (OnBootSec=
,OnUnitActiveSec=
). Главное преимущество - полная интеграция с зависимостями и журналированием, как у любого другого юнита.Mount (
.mount
) и Automount (.automount
): точки монтирования.Automount
обеспечивает отложенное монтирование в момент первого обращения к каталогу.Path (
.path
): активирует сервис при изменении файловой системы (например, появлении файла в определённом каталоге). Аналогincron
.Target (
.target
): аналог runlevel из SysVinit, но более гибкий. Это группа юнитов, которую нужно достичь (например,multi-user.target
— многопользовательский режим без GUI).
Структура файла юнита:
Каждый файл разбит на секции. [Unit]
содержит общие метаданные (описания, зависимости), а специализированная секция (например, [Service]
или [Timer]
) — параметры конкретного типа.
# Пример: /etc/systemd/system/app.service
[Unit]
Description=My Custom Application
After=network.target # Запускать после активации сети
Requires=postgresql.service # Жёсткая зависимость
Wants=redis.service # Мягкая зависимость
[Service]
Type=simple
ExecStart=/usr/bin/myapp --serve
Restart=on-failure # Автоматически перезапускать при падении
RestartSec=5
User=myappuser
Group=myappgroup
[Install]
WantedBy=multi-user.target
# |- В какой "уровень" включить этот юнит при активации через `systemctl enable`
Подробнее про Type
Один из самых важных параметров, определяющих, как systemd будет управлять процессом вашего сервиса. Неверный выбор типа - частая причина проблем с запуском и зависимостями.
Type=simple
- значение по умолчанию
Поведение: процесс, указанный в ExecStart
, считается главным. Systemd считает сервис запущенным (active
) и готовым к работе сразу после того, как породил (fork) этот процесс. Он не ждёт никаких подтверждений от самого процесса.
Когда использовать: для простых демонов, которые не превращаются сами в фоновый процесс. Лучше не использовать данный тип, если процесс "демонизируется" самостоятельно - systemd просто потеряет его из виду.
Type=forking
Поведение: классическая модель "демона". Процесс, указанный в ExecStart
, запускается, создает своего потомка (fork) и сразу завершается. Systemd отслеживает завершение этого родительского процесса и после этого считает запущенным именно дочерний процесс.
Обязательный параметр: почти всегда требуется указать PIDFile=...
(к примеру, PIDFile=/run/
nginx.pid
). Это необходимо, чтобы systemd точно знал, какой PID (идентификатор процесса) у главного дочернего процесса и, соответственно, мог его корректно перезапустить или остановить.
Когда использовать: для традиционных демонов, написанных под SysV init (к примеру, nginx, Apache, MySQL и прочие), которые самостоятельно отсоединяются от терминала.
Type=oneshot
Поведение: предназначен для скриптов, которые должны выполниться один раз и завершиться. Systemd будет терпеливо ожидать полного завершения процесса ExecStart
, и только после этого перейдет к запуску следующих юнитов, зависящих от этого сервиса.
Комбинация: часто используется с RemainAfterExit=yes
. Эта опция говорит systemd считать сервис активным даже после завершения его процесса. Это полезно для сервисов, которые подготавливают систему (к примеру, монтируют диски или настраивают сеть), но сами по себе не имеют постоянно работающего процесса.
Когда использовать: для запуска скриптов инициализации, разовых задач, которые должны быть выполнены для старта других сервисов.
Type=notify
Поведение: процесс сервиса должен самостоятельно отправить systemd уведомление (сигнал sd_notify
), когда он полностью проинициализировался и готов к работе. Systemd будет ждать этого уведомления, прежде чем считать сервис активным и запускать зависящие от него юниты.
Требования: приложение должно иметь поддержку API systemd для отправки уведомлений (через библиотеку libsystemd
или низкоуровневый сокет).
Когда использовать: для современных демонов, которые изначально разрабатываются для работы под systemd (например, systemd itself, sshd). Это обеспечивает точное управление зависимостями.
Type=dbus
- не самый распорстраненный
Поведение: сервис считается готовым, когда он регистрирует определенное имя на системной шине D-Bus.
Когда использовать: для сервисов, которые предоставляют интерфейс через D-Bus.
Пример конфигурации для forking-домена (например, веб-сервера):
[Unit]
Description=My Forking Web Service
[Service]
Type=forking
PIDFile=/run/my-webservice.pid
ExecStart=/usr/bin/my-webservice --daemon --pid-file=/run/my-webservice.pid
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
3. Зависимости и порядок запуска
Systemd строит ориентированный граф зависимостей между юнитами. Анализируя директивы After
, Before
, Requires
, Wants
, он вычисляет оптимальный порядок активации, позволяя запускать максимальное количество независимых юнитов параллельно. Не слепой параллелизм, а управляемое распараллеливание на основе явно заданных правил.
4. Cgroups и отслеживание процессов
Это фундаментальное техническое отличие от SysVinit. Systemd помещает каждый запущенный сервис в свою собственную cgroup (control group). Это позволяет:
Точно отслеживать все процессы службы: даже если главный процесс (
ExecStart
) породил множество дочерних процессов (fork), они все останутся внутри cgroup. Командаsystemctl status
точно покажет все процессы, принадлежащие сервису.Изолировать и ограничивать ресурсы: через директивы юнита (
MemoryMax=
,CPUQuota=
) можно легко установить лимиты на потребление памяти, CPU, I/O сервисом.Гарантированно завершать все процессы службы: при остановке сервиса systemd гарантированно завершает все процессы в его cgroup, устраняя проблему "зомби"-процессов.
Теория реализуется на практике с помощью двух инструментов (systemd-cgls
и systemd-cgtop
), которые предоставляет systemd для визуализации и мониторинга контрольных групп.
Практическое использование: инструменты systemd-cgls
и systemd-cgtop
.
Systemd-cgls
- показывает иерархическое дерево всех существующих cgroup в системе, аналогично тому, какls
показывает файлы. Это лучший способ понять и увидеть структуру, которую создаёт systemd. Посмотрим на примере:
# Показать всё древо cgroup для сервиса nginx
systemd-cgls /system.slice/nginx.service
# Будут показаны все процессы в данной cgroup:
# |-1234 /usr/sbin/nginx -g daemon off:
# |-1235 nginx: worker process
# |-1236 nginx: cache loader process
systemd-cgtop
- показывает потребление ресурсов (CPU, память, ввод/вывод) всеми cgroup в реальном времени, аналогично тому, какtop
показывает это для процессов. Посмотрим пример вывода:
Control Group Tasks %CPU Memory Input/s Output/s
/ 257 15.8 3.9G 0B 0B
/system.slice/nginx.service 3 0.1 30.0M 0B 0B
/system.slice/mysql.service 45 12.5 1.1G 0B 0B
/user.slice/user-1000.slice 120 3.2 800.0M 0B 0B
5. Журналирование (journald)
Бинарный формат логов: в отличие от текстовых файлов
syslog
,journald
по умолчанию использует структурированный бинарный формат для хранения логов (обычно в/var/log/journal/
). Это позволяет эффективно индексировать и запрашивать логи по метаданным.Метаданные: каждая запись в журнале содержит не только сообщение, но и массу системной информации:
PID
,UID
,SYSTEMDUNIT
,EXE
,CMDLINE
,_HOSTNAME
и т.д.Запросы: инструмент
journalctl
позволяет строить сложные запросы, используя эти метаданные как поля для фильтрации:
# Логи для nginx с PID 1234 и логи для php-fpm
journalctl _SYSTEMD_UNIT=nginx.service _PID=1234 + _SYSTEMD_UNIT=php-fpm.service
6. D-Bus
Взаимодействие между systemctl
, другими утилитами (journalctl
, hostnamectl
) и демоном systemd
происходит через D-Bus (системную шину сообщений). Это обеспечивает стандартизированный, безопасный и гибкий IPC-механизм. Например, когда вы выполняете systemctl start nginx
, systemctl
отправляет D-Bus-сообщение методу StartUnit
на системную шину, которое перехватывает и обрабатывает демон systemd
.
Подробнее про D-Bus
D-Bus или Desktop Bus - система обмена сообщениями между программами в LInux, некий "посредник" для общения.
Понимаю, что кому-то может быть непонятно (когда-то в попытках разобраться - чуток утонул в официальном Wiki), поэтому приведу простую аналогию:
D-Bsu - диспетчер в такси. Человек (systemctl
) звонит диспетчеру со словами: "Запустите службу nginx". Диспетчер (D-Bus) передаёт команду водителю (systemd
), который её выполняет.
То есть, на практике:
# Используется команда
systemctl start nginx
# systemctl через D-Bus отправляет сообщение: "Запусти nginx"
# systemd через D-Bus получает это сообщение
# systemd запускает службу и через D-Bus возвращает статус
Практическое применение
Теория - всегда хорошо, но куда без практики? Далее рассмотрим практические примеры применения "всего и вся".
1. Управление состоянием службы: запуск, остановка, перезагрузка
Данные команды управляют текущим, активным состоянием службы. Действуют немедленно, не влияют на автозагрузку при следующей перезагрузке.
# Запускает службу немедленно
systemctl start <service_name>
# Например:
sudo systemctl start nginx
# Останавливает службу немедленно
systemclt stop <service_name>
# Например:
sudo systemctl stop sshd
# Полная перезагрузка службы. Последовательно выполнит stop, затем start
# Применяется, когда необходима загрузка с "чистого" состояния
systemctl restart <service_name>
# Например:
sudo systemctl restart apache2
# Перезагружает конфигурацию службы без остановки основного процесса
# Важно! Это не перезапускает дочерние службы. Сервис продолжает работать и обрабатывать запросы, лишь обновляя свои настройки
# Применяется, когда необходимо внести изменения в конфиг для минимизации простоев
systemctl reload <service_name>
# Например:
sudo systemctl reload nginx # обновится конфиг без разрыва соединений
# Показывает подробный статус службы:
# активен/неактивен, добавлен ли в автозагрузку, последние записи в лог, а также инфо о процессе
systemctl status <service_name>
Например:
systemctl status cron
2. Управление автозагрузкой
Данные команды управляют тем, будет ли служба запущена автоматически при загрузке системы или при определенной цели (target
). Не запускают и не останавливают службу немедленно.
# Включает автозагрузку службы при старте системы
systemctl enable <service_name>
Что она делает? Создает символические ссылки (симлинки) из юнит-файла службы (обычно в /usr/lib/systemd/system/
) в соответствующие каталоги .wants/
для целей (например, multi-user.target.wants/
или graphical.target.wants
). При запуске цели система видит эти ссылки и запускает все необходимые службы.
# Отключает автозагрузку службы
systemctl disable <service_name>
Что делает? Удаляет символические ссылки, тем самым исключая саму службу из процесса автозагрузки.
# Показывает статус автозагрузки службы
# Например: enabled, disabled, static, masked
systemctl is-enabled <service_name>
Использование в скрипте, как пример: if ! systemctl is-enabled --quiet nginx; then sudo systemctl enable nginx; fi
Также, хочу упомянуть про "масикровку", которая является "абсолютным запретом". Это альтернатива disable
. Disable
лишь убирает симлинки, но сервис все еще можно запустить вручную через start
. Mask
создает симлинк на /dev/null
, что делает запуск сервиса невозможным в принципе. Это критически важно для сервисов, которые конфликтуют между собой (например, разные сетевые менеджеры NetworkManager
и systemd-networkd
).
# Полностью запрещает запуск службы (любым способом)
sudo systemctl mask <service_name>
# Разрешает запуск службы (обратное действие)
sudo systemctl unmask <service_name>
# Например: если Вы используете networkd, стоит замаскировать NetworkManager
sudo systemctl mask NetworkManager.service
3. Просмотр состояния системы и служб
Эти команды помогают получить общую картину о состоянии всех служб в системе.
# Показывает краткий обзор состояния системы:
# список загруженных юнитов, состояние по умолчанию, журналы...
systemctl status # без аргументов
# Возвращает состояние службы (active, inactive, activating, failed)
# Вывод краткий, подходит для скриптов
systemctl is-active <service_name>
# Например:
systemctl is-active docker # вернет active или inactive
# Проверяет, находится ли служюа в состоянии сбоя
# Возвращает failed (если не запустилась) или active/inactive иначе
# Полезно для автоматического оповещения
systemctl is-failed <service_name>
# Показывает все запущенные в данный момент сервисы
# Полезная команда для получения списка того, что работает на сервере
systemctl list-units --type=service --state=running
Альтернативный короткий синтаксис:
systemctl --type=service --state=running
# Покажет все доступные сервисы и статус их автозагрузки (enabled, disabled, static, masked)
# Команда показывает, будет ли запущена служба при загрузке, а не в данный момент
systemclt list-unit-files --type=service
Альтернативный короткий синтаксис:
systemctl --type=service --all
Статус static
означает, что юнит-файл не имеет секции [Install]
, поэтому его нельзя "enable
". Обычно запускается как зависимость другого сервиса.
Далее, в этом же блоке, стоит обратить внимание на возможность просмотра зависимостей:
# Показывает, от каких юнитов зависит данный сервис
systemctl list-dependencies <service_name>
# Показывает, какие юниты зависят от данного сервиса (кто его требует)
systemctl list-dependencies --reverse <service_name>
# Показывает дерево зависимостей в виде древовидной структуры
systemctl list-dependencies --tree <service_name>
# Например:
systemctl list-dependencies graphical.target --tree | head -20
# А также:
# --all - показать все зависимости (включая неактивные)
# --reverse или -r - показать, какие юниты зависят от указанного (кто использует эту службу)
# --before / --after - показать юниты, которые запускаются "до или после" указанного
Приведу конкретный пример для лучшего понимания. Например, необходимо проверить, какие службы зависят от сетевого менеджера:
systemctl list-dependencies --reverse NetworkManager.service
Это поможет понять, какие службы перестанут работать корректно, если остановить NetworkManager
.
4. Просмотр логов конкретной службы
Основной инструмент для работы с журналами в systemd - journalctl
. Все команды обычно требуют sudo
для просмотра полного лога.
# Показывает все записи в журнале (логи) для указанной службы за всё доступное время
journalclt -u <service_name>
# Показывает логи службы с указанного времени
journalctl -u <service_name> --since today
# Например:
sudo journalctl -u sshd --since "1 hour ago" # что происходило с SSH за последний час?
Фильтрация по времени позволяет сузить ввод, дабы не листать массивные файлы журналов. Вместо today
можно использовать yesterday
, "2025-01-01 00:00:00"
и тд.
# "Режим" реального времени (follow). Команда выводит текущие логи
# и продолжает показывать новые записи по мере их появления
journalctl -u <service_name> -f
# Например:
sudo journalctl -u apache2 -f # наблюдать за логами Apache в реальном времени
5. Поиск причин проблем с загрузкой
Эти команды помогают быстро найти службы, которые не смогли запуститься, и понять общую картину здоровья системы.
# Быстрый просмотр всех юнитов (не только служб), которые находятся в failed
systemctl --failed
# Покажет сообщения журнала с уровнем важности "ошибка" и выше (crit, alert...)
journalctl -p err..alert
# Показывает все логи с момента последней загрузки системы
# Полезно для анализа проблем, которые могли возникнуть в момент старта системы
journalclt -b
# Например:
sudo journalctl -b -1 # Что привело к падению системы в прошлый раз?
6. Анализ времени загрузки
Следующий блок - инструменты для анализа производительности и поиска "узких мест" в процессе загрузки.
# Показывает общее время, затраченное на загрузку ядра и пользовательского пространства
# Полезно для формирования общего представления о скорости загрузки
systemd-analyze
# Пример вывода:
Startup finished in 4.567s (kernel) + 1min 12.345s (userspace) = 1min 16.912s
# Демонстрирует скисок всех сервисов, которые дольше всего грузились
# Сортирует по времени их инициализации
systemd-analyze blame
Команда очень полезная, тк позволяет сразу увидеть, какая служба задерживает старт системы (к примеру, медленный сервис или антивирус). Помогает в оптимизации времени загрузки.
# Визуализирует цепочку запуска для конкретного сервиса
systemd-analyze critical-chain <service_name>
# Например:
systemd-analyze critical-chain graphical.targer # Почему граф. интерфейс так долго грузится?
Данная команда показывает зависимости: какие службы должны были запуститься до него, сколько времени занял каждый шаг. Выделяет "узкие места", задерживающие старт целевой службы.
Краткая шпаргалка для анализа:
Задача |
Команда |
---|---|
Посмотреть логи службы |
|
Логи в реальном времени |
|
Кто не запустился? |
|
Критические ошибки |
|
Логи прошлой загрузки |
|
Что грузилось дольше всех? |
|
Почему грузился X? |
|
Разбор примеров
1. Создание и настройка простого сервиса
Итак, задача следующая: создать службу, которая запускает простой эхо-сервер на Python и гарантирует его работу (рестартит после падения).
Создаем скрипт сервиса (/usr/local/bin/echo-server.py
):
#!/usr/bin/env python3
import socket
HOST = '0.0.0.0'
PORT = 12345
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen()
print(f"Echo server listening on {HOST}:{PORT}")
while True:
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
Создаем юнит-файл (/etc/systemd/system/echo.service
):
[Unit]
Description=Simple Echo Server
Documentation=https://example.com
# Запускаться после того, как сеть будет готова
After=network.target
[Service]
Type=simple
# Указываем полный путь к интерпретатору и скрипту
ExecStart=/usr/bin/python3 /usr/local/bin/echo-server.py
# Перезапускать сервис всегда, если он завершился не так, как ожидалось
Restart=on-failure
# Ждать 5 секунд перед перезапуском
RestartSec=5
# Запускать от имени непривилегированного пользователя для безопасности
User=nobody
Group=nogroup
# Важные настройки безопасности для изоляции сервиса
# Запрещаем любые права root
NoNewPrivileges=yes
# Ограничиваем возможности процесса
CapabilityBoundingSet=
# Запрещаем запись в большинство файловых систем
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
Применяем конфигурацию и управляем сервисом:
# Перезагружаем конфигурацию systemd для чтения нового юнита
sudo systemctl daemon-reload
# Включаем автозагрузку сервиса
sudo systemctl enable echo.service
# Запускаем сервис
sudo systemctl start echo.service
# Проверяем статус и логи
sudo systemctl status echo.service
journalctl -u echo.service -f
# Тестируем работу эхо-сервера
echo "Hello, Habr!" | nc localhost 12345
# Проверяем, что сервис перезапускается. Симулируем падение:
sudo kill -TERM $(systemctl show echo.service --property=MainPID --value)
# Через 5 секунд проверяем статус снова - сервис должен быть активен
sudo systemctl status echo.service
В данном примере я продемонстрировал создание сервиса с нуля, настройку политик, перезапуск и некоторые настройки безопасности, которые следует использовать по умолчанию.
2. Ограничение ресурсов сервиса с помощью cgroups
Задача: необходимо ограничить потребление памяти эхо-сервером до 50МБ и ограничить использование CPU, к примеру, до 50% одного ядра.
Модифицируем юнит-файл сервиса (/etc/systemd/system/echo.service
), добавляя в секцию [Service]
:
[Service]
...
# Memory Limits
# Жесткий лимит памяти. Процесс будет убит (OOM Killer), если превысит его.
MemoryMax=50M
# Мягкий лимит. Systemd начнет агрессивно пытаться освободить память (например, сбрасывая кеши),
# если процесс превысит этот лимит, но не убьет его сразу.
MemoryHigh=40M
# CPU Limits
# Ограничивает использование CPU до 50% одного ядра.
CPUQuota=50%
...
# После изменения файла не забываем
sudo systemctl daemon-reload
sudo systemctl restart echo.service
Проверяем ограничения:
# Смотрим, в какую cgroup помещен наш сервис
systemd-cgls /system.slice/echo.service
# Мониторим потребление ресурсов этой cgroup в реальном времени
systemd-cgtop -p /system.slice/echo.service
# Можно посмотреть параметры cgroup напрямую
cat /sys/fs/cgroup/system.slice/echo.service/memory.max
# Должно быть: 52428800 (50 МБ в байтах)
3. Поиск и устранение проблемы с помощью journalctl
Задача: найти причину падения службы my-app.service
(запускается, но сразу падает).
# 1. Смотрим статус - видим, что сервис в состоянии failed
sudo systemctl status my-app.service
# В выводе часто уже есть последняя строка ошибки
# 2. Смотрим логи службы за последний запуск
journalctl -u my-app.service -n 20 --no-pager
# 3. Если лога нет или его недостаточно, смотрим логи с момента последней загрузки с подробным выводом
journalctl -u my-app.service --since "10 min ago" -o verbose
# Ключ `-o verbose` покажет все метаданные (например, UID, GID, командную строку),
# что может быть критически важно для диагностики
# 4. Допустим, в логах видна ошибка подключения к порту 5432.
# Ищем, что происходило с PostgreSQL (который должен предоставлять этот порт) в то же время
journalctl -u postgresql.service --since "10 min ago" | tail -20
# 5. Или ищем все сообщения об ошибках (уровень ERR и выше) в системе за этот период
journalctl -p err..alert --since "10 min ago"
# 6. Если проблема в разрешении зависимостей, смотрим, что мешает запуску
# Включаем подробный вывод systemd при запуске сервиса
sudo systemctl status my-app.service -l --no-pager
# Или пытаемся запустить вручную с выводом в консоль
sudo systemctl start my-app.service
Journalctl
с правильными ключами фильтрации (-u
, -p
, -since
, -o
) - главный и невероятно полезный инструмент диагностики проблем со службами.
Заключение
Systemd - комплексная, глубоко интегрированная система инициализации и управления, которая стала неотъемлемым скелетом современных дистрибутивов Linux. Её архитектура, построенная вокруг концепции юнитов, cgroups и централизованного журналирования, кардинально меняет подход к администрированию системы.
В данном руководстве я постарался охватить все основные и ключевые технические аспекты и, что для меня лично являлось приоритетом, по возможности собрать всё воедино, без воды. Надеюсь, получилось.
Данная статья является продолжением статьи по cron
, так как systemd был затронут, но не раскрыт.
P.S. В моей группе в Телеграмм разбираем практические кейсы: скрипты (Python/Bash/PowerShell), тонкости ОС и инструменты для эффективной работы.
vviz
"Systemd - комплексная, глубоко интегрированная система инициализации и управления, которая..." превращает управление сервером в общение с "черным ящиком".
Для домохозяек с десктопом - самое то. Но сервер... Я на 100% должен контролировать его состояние, а не кланятся systrmd с просьбой сказать мне, зачем он 100 раз перегрузил упавший демон, а потом "ой, всё". Бездумно перегружать, надеясь, что все чудесным образом исправится - это подход Microsoft... ИМХО.
Мой выбор - Devuan
DikSoft
1) У MS это настраивается, один, два или более раз рестартануть нужно/можно. )
MS way
2) Если бы только их..., как работают контейнеры в K8S вы наверняка знаете?
ReadOnlySadUser
А что в контейнерах-то особо сложного? Сами контейнеры - это сахар над cgroups, namespaces и capabilities (и ещё парой плюшек безопасности в Linux). Машинерия сложная, но в целом мне понятная. А ведь даже не админ)