Learning Platform
Глоссарий Troubleshooting
Урок 16.01 · 22 мин
Начальный
systemdinitPID 1unitsservicetimertargetcgroups

Что такое init system

Когда Linux загружается, после kernel initialization запускается первый процессPID 1. Этот процесс отвечает за: монтирование оставшихся ФС, запуск всех остальных сервисов в правильном порядке, обработку сигналов (что делать когда ctrl+alt+del, что делать при shutdown), reap-инг zombie-процессов, перезапуск упавших сервисов.

PID 1 называется init system. Без него Linux загрузится до командной строки и зависнет — ему некому делегировать дальнейшую работу.

На современных дистрибутивах (Ubuntu 26.04 LTS, Debian 13 Trixie, RHEL 9/10, Fedora) init system — это systemd. Версия 257+ как раз в наших целевых OS. До 2014-2016 годов был SysV init или Upstart. Переход на systemd был долгим и спорным, но к 2026 году systemd — фактический стандарт.

Почему systemd, а не старый SysV init

SysV init — это набор /etc/init.d/* shell-скриптов, запускаемых последовательно при boot. Каждый скрипт выглядел примерно так:

#!/bin/sh
# /etc/init.d/apache
case "$1" in
    start) ... ;;
    stop)  ... ;;
    restart) ... ;;
esac

Проблемы такого подхода:

Почему SysV init заменили на systemd

Каждая проблема SysV — это feature systemd.

SysV: sequential bootвсё ждёт всё, медленно
systemd: parallel + depsпараллельно, быстро
SysV: нет respawnнужны monit/supervisord
systemd: Restart=on-failureвстроенный supervisor
SysV: разрозненные логикаждый сервис свой формат
systemd: journalединый поиск, structured
SysV: cgroups вручнуюмного setup
systemd: resource limitsMemoryMax=, CPUQuota=

systemd взял на себя то, что раньше делали разные инструменты: init + cron + inetd + supervisord + syslog + udev + automount. Это и его плюс (всё в одном, согласованный API), и минус (огромный monolithic компонент, критикуемый за «нарушение Unix-философии»).

Для Junior DE: systemd — это данность. На любой современной production-VM ты будешь работать с systemd. SysV скрипты иногда встретятся как legacy /etc/init.d/* — systemd их умеет запускать через compatibility layer.

PID 1: что значит

$ ps -p 1
    PID TTY          TIME CMD
      1 ?        00:00:42 systemd

$ readlink /proc/1/exe
/usr/lib/systemd/systemd

PID 1 — это /usr/lib/systemd/systemd. Если он упадёт — kernel panic, перезагрузка. Поэтому код systemd очень аккуратный, на C, с десятилетиями полировки.

PID 1 особенный: ему ядро не доставляет сигналы, которые не обработаны. Это значит — kill 1 без обработчика не убьёт init. Зато systemctl reboot / systemctl poweroff — это API через D-Bus, который systemd слушает.

Юниты: всё это units

systemd оперирует абстракцией unit — описание того, чем нужно управлять. Юниты бывают разных типов:

Типы systemd units

Каждый тип отвечает за свой класс сущностей. Расширение файла указывает тип.

.serviceсервисы (демоны)
.timerрасписание, замена cron
.socketsocket activation
.mountмонтирование ФС (как fstab)
.automountlazy mount при доступе
.targetгруппа units (runlevel)
.deviceустройство (udev)
.pathтриггер на файл
.slicecgroup группировка
.scoperuntime cgroup

Для DE на повседневной работе важны: .service, .timer, .target. Остальные — изредка, в специфических случаях.

Где живут unit-файлы

Поиск идёт в нескольких директориях по приоритету:

/etc/systemd/system/        # высший приоритет — admin override
/run/systemd/system/        # runtime (создаётся при работе)
/usr/lib/systemd/system/    # пакетные unit-файлы (postgres, nginx)

Когда устанавливаешь пакет (apt install postgresql), его unit-файл попадает в /usr/lib/systemd/system/postgresql.service. Если хочешь его изменить — не редактируй там, потому что apt upgrade перезапишет. Правильный способ — override:

$ sudo systemctl edit postgresql

Эта команда создаст /etc/systemd/system/postgresql.service.d/override.conf, который дополнит базовый unit. Тут можно переопределить ExecStart, добавить Environment=, изменить Restart=.

# Просмотр всех unit-директорий с приоритетом:
$ systemctl --no-pager show -p UnitPath
UnitPath=/etc/systemd/system.control /run/systemd/system.control /run/systemd/transient /etc/systemd/system /run/systemd/system /usr/lib/systemd/system ...

User-level units

systemd умеет запускать unit-ы от имени пользователя, без root. Они живут в ~/.config/systemd/user/:

# Запустить как user (не системный)
$ systemctl --user start my-etl.service

Это полезно для DE: тестовый ETL-скрипт можно запустить как user, без sudo. Подробнее в уроке 04-writing-service-unit.

Targets вместо runlevels

В SysV было 7 runlevels (0-6): single-user, multi-user, graphical, reboot, halt. systemd использует targets — гибче, потому что target может зависеть от любого набора units.

$ systemctl get-default
multi-user.target

$ systemctl list-units --type=target --state=active
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION
basic.target           loaded active active Basic System
graphical.target       loaded active active Graphical Interface
multi-user.target      loaded active active Multi-User System
network-online.target  loaded active active Network is Online
network.target         loaded active active Network
remote-fs.target       loaded active active Remote File Systems
sysinit.target         loaded active active System Initialization
timers.target          loaded active active Timers
...

Стандартные targets:

  • default.target — что boot-ит по умолчанию. Обычно symlink на multi-user.target (для server) или graphical.target (для desktop).
  • multi-user.target — все системные сервисы, network up, но без GUI.
  • graphical.target — multi-user + display manager.
  • rescue.target — single-user, minimal system для recovery.
  • emergency.target — даже меньше, только root shell без mounts.
  • network-online.target — сеть готова и есть DNS.

DE-юниты обычно указывают WantedBy=multi-user.target в [Install] — это значит «при boot до multi-user меня тоже запусти».

systemd как init: загрузка системы шаг за шагом Этапы загрузки Linux: от BIOS до PID 1

Что systemd делает под капотом

Когда ты делаешь systemctl start nginx.service, происходит много всего:

Что происходит при systemctl start

systemd не просто 'запускает binary' — он выстраивает целое окружение для процесса.

1. Resolve depsзапустить After=/Requires=
2. Create cgroupсистема отслеживания процессов
3. Apply limitsMemoryMax, CPUQuota, TasksMax
4. Setup namespacesPrivateNetwork, PrivateTmp
5. Fork + setuid + execзапуск процесса
6. Route I/O to journalstructured logging
7. Monitor + restartsupervisor поведение

Эта последовательность объясняет, почему systemctl status показывает столько метаданных и почему systemd-юниты по умолчанию надёжнее, чем nohup python my_script.py & в shell.

Куда дальше

В следующих уроках:

  • 02-systemctl-basics — основные команды для управления сервисами.
  • 03-journalctl-logsjournalctl для чтения логов.
  • 04-writing-service-unit — создаём свой .service для custom DE-задачи.

Cron — в модуле 15-cron-scheduling. Bash-скрипты для запуска через systemd — в модуле 16-bash-scripting-basics.

Проверь установку systemd

# Запустился ли systemd как PID 1
$ ps -p 1 -o comm=
systemd

# Версия systemd
$ systemctl --version
systemd 257 (257.1-1ubuntu1)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP ...

# Текущий default target
$ systemctl get-default
multi-user.target

# Какие unit-файлы есть для одного из сервисов
$ systemctl list-unit-files | grep ssh
ssh.service                          enabled  enabled
sshd.service                         enabled  enabled

Попробуй сам

  1. Что у тебя PID 1?
    ps -p 1 -o comm=
  2. Какая версия systemd?
    systemctl --version | head -1
  3. Сколько units сейчас активных?
    systemctl list-units --state=active | wc -l
  4. Какие targets активны?
    systemctl list-units --type=target --state=active
  5. Default target:
    systemctl get-default
  6. Посмотри один из системных unit-файлов:
    systemctl cat ssh.service

macOS-различия

  • На macOS init system — launchd, не systemd. Файлы .plist в /Library/LaunchDaemons/ или ~/Library/LaunchAgents/. Управление: launchctl load/unload/start/stop.
  • Командой brew services Homebrew абстрагирует это для брю-пакетов (brew services start postgresql).
  • Для DE на macOS обычно Docker Desktop или OrbStack, и внутри VM уже systemd. Так что systemd-команды релевантны при ssh на production Linux.

Главное

  • systemd — init system, PID 1, на современных Ubuntu/Debian/RHEL/Fedora.
  • Заменил SysV init: parallel boot, deps между units, встроенный supervisor (Restart=), journal, cgroups.
  • Управляет всем: services, timers, mounts, sockets, paths, targets.
  • Unit — описание управляемой сущности. Типы: .service, .timer, .target, .mount, .socket, .path, …
  • Unit-файлы: /usr/lib/systemd/system/ (пакеты), /etc/systemd/system/ (admin override).
  • User-units: ~/.config/systemd/user/ — без root.
  • Target — группа units, заменили runlevels. multi-user.target — стандарт для server.
  • При systemctl start: deps -> cgroup -> limits -> namespaces -> fork+exec -> route I/O в journal -> monitor.
  • Для DE: понимать systemd обязательно — каждый production-VM на нём.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Что такое PID 1 на современном Linux (Ubuntu 26.04 LTS)?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4