В Linux существуют специальные службы — демоны — работающие в фоновом режиме и обслуживающие другие программы. Инициализация и управление демонами происходит с помощью специального процесса инициализации. Ядро, сразу после своей загрузки, запускает процесс инициализации, который приводит к запуску всех необходимых служб и программ. Для этого считывается соответствующий файл конфигурации и на основе описанных в нем параметров начинается запуск системы. Данный процесс инициализации является главным (или «родительським») процессом, который переводит систему из состояния «ядро запущено» к состоянию «система готова к работе».
Примечание: В системе инициализации SysV главным процессом является процесс init, а в системе инициализации systemd — (одноименный) процесс systemd.
С течением времени в Linux появилось большое разнообразие систем инициализации. В данной статье мы рассмотрим наиболее популярные из них, а также сравним SysV и systemd.
Спор вокруг систем инициализации в Linux
System V init (или просто «SysV») — это система инициализации, которая существует со времен операционной системы System V, которая была выпущена в 1983 году. SysV оставалась системой инициализации в течение почти трех десятилетий (за некоторыми исключениями). Многие IT-специалисты и программисты в силу своей привычки не хотели отказываться от SysV, да и к тому же она была очень простой для понимания.
Проблема с SysV заключалась в том, что в её основе лежали концепции, существовавшие много лет назад. SysV не хватало возможности нативно обрабатывать многие вещи, такие как: обнаружение съемных носителей, корректное обнаружение аппаратного обеспечения и загрузка встроенного ПО, загрузка различных модулей и пр. Кроме того, при использовании данной системы, инициализация процессов происходит последовательно, т.е. одна задача запускается только после успешного завершения предыдущей. Часто это приводило к задержке и длительному времени загрузки. Задачи, подобные монтированию файловых систем, выполняются один раз во время загрузки, после чего «забываются». Но такого подхода недостаточно для автоматизированного управления сервисами, требующими к себе постоянного внимания.
В попытке привнести больше возможностей в процесс инициализации Linux-систем, компания Canonical в 2006 году вместе с релизом Ubuntu 6.10 (Edgy Eft) выпускает систему инициализации Upstart, которая с самого начала разрабатывалась с учетом обратной совместимости. Она может запускать демоны без каких-либо изменений в их скриптах запуска.
Другой системой инициализации, восходящей своими корнями к операционной системе 4.4BSD, является rc.init. Она применяется в таких дистрибутивах, как: FreeBSD, NetBSD и Slackware. В 2007 году разработчики Gentoo выпустили улучшенный вариант данной системы инициализации, сделав её модульной и назвав OpenRC. Большинство других дистрибутивов Linux исторически продолжало использовать SysV.
В 2010 году инженеры компании Red Hat Леннарт Пёттеринг и Кей Сиверс приступили к разработке новой системы инициализации — systemd, которая разрабатывалась с учетом недостатков, имеющихся в SysV. В состав systemd, помимо прочего, также входят и различные пакеты, утилиты и библиотеки, позволяющие производить параллельный запуск процессов, сокращая тем самым время загрузки системы и количество необходимых вычислений. Весной того же года Fedora 15 стала первым дистрибутивом, в котором по умолчанию использовалась система инициализации systemd. После чего, на протяжении следующих трех лет, большинство дистрибутивов массово перешли на systemd.
Но, если все остальные дистрибутивы отдают предпочтение systemd и считают её лучшей системой инициализации, как для предприятий, так и для любителей, почему так много споров вокруг нее?
systemd, по сравнению с SysV и Upstart, содержит большое количество различных улучшений, а также предлагает и другие компоненты, имеющие более тесную интеграцию с системой, с помощью которых разработчики могут уменьшить объем выполняемой работы. Что в этом плохого? Ну, поскольку разработчики создают программное обеспечение, которое зависит от systemd и/или от любой из её многочисленных служб (journald, udevd, consoled, logind или networkd), то такое ПО становится менее совместимым с системами, в которых systemd не применяется. По мере того, как количество служб, предоставляемых проектом systemd, продолжает расти, systemd сама становится все более зависимой от них.
В результате systemd становится самостоятельной платформой, и её повсеместное распространение непреднамеренно препятствует разработке программного обеспечения, которое является переносимым и совместимым с операционными системами, не поддерживающими systemd. Но действительно ли всё так печально? Конечно, нет. Прежде всего, это проект с открытым исходным кодом, и у людей есть выбор: использовать его или нет. Пользователи и разработчики могут извлечь выгоду из наличия нескольких конкурирующих систем инициализации, и нет вины systemd в том, что основные дистрибутивы переключились на нее из-за её плюсов.
Системы инициализации Linux
SysV
System V init (или просто «SysV») — это система инициализации, которая существует со времен операционной системы System V.
Примечание: System V — это первая коммерческая UNIX-подобная операционная система, которая была выпущена в 1983 году.
Процесс init (от англ. «initialization») — это первый запускаемый в системе процесс (не считая загрузки ядра), который является родителем (прямым или косвенным) всех других запущенных процессов, и которому присваивается PID=1.
Если процесс init по каким-либо причинам не смог стартовать, то не произойдет запуска последующих процессов и система перейдет в особое (вызванное появлением критической ошибки) состояние ядра, называемое Kernel Panic.
В SysV имеется шесть состояний системы, известных как уровни выполнения (runlevels), и всем процессам и службам сопоставляется определенный уровень выполнения. Данная система инициализации также предлагает простые в использовании команды и методы для управления уровнями выполнения и связанными с ними службами.
Runlevel 0 — завершает работу системы.
Runlevel 1 — однопользовательский режим работы. Чаще всего используется в целях обслуживания и выполнения других административных задач. Этот уровень также может называться Runlevel S (от англ. «Single-user»). Если вам когда-либо приходилось сбрасывать пароль на Linux, то вы вероятно уже пользовались этим режимом.
Runlevel 2 — многопользовательский режим работы (англ. «multi-user») без поддержки сетевых служб.
Runlevel 3 — многопользовательский режим с поддержкой сети, но без графического интерфейса. Чаще всего серверные версии Linux работают именно на этом уровне выполнения.
Runlevel 4 — не используется. Пользователь может настраивать этот уровень исходя из его целей.
Runlevel 5 — схож с режимом 3, но здесь запускается графический интерфейс. В этом режиме работают десктопные версии Linux.
Runlevel 6 — перезагружает систему.
Значения для каждого уровня выполнения варьируются в зависимости от вашего дистрибутива Linux. Есть дистрибутивы (например, Ubuntu), которые используют Runlevel 2 для многопользовательского графического режима с поддержкой сети, другие дистрибутивы (например, Fedora) для того же самого используют Runlevel 5.
В операционной системе, использующей SysV, ядро запускает файл /sbin/init, который, в свою очередь, загружает параметры и выполняет директивы, определенные в файле конфигурации — /etc/inittab. Этот файл задает уровни выполнения для всей системы, определяет, для каких терминалов следует создавать getty (процессы инициализации терминала), запускает процессы входа в терминал, запускает скрипт /etc/init.d/rcS, а также влияет на порядок выполнения других runlevel-скриптов.
Запуск служб происходит в заранее определенной последовательности. Следующий скрипт в цепочке запуска выполняется только в том случае, если был выполнен предыдущий скрипт. Если во время своего выполнения скрипт зависнет, то следующему скрипту придется ждать, пока у текущего не истечет время ожидания. Данная непредвиденная задержка исполнения скрипта делает весь процесс инициализации системы менее эффективным и, в конечном счете, более медленным.
Кроме этого, у SysV есть проблемы с т.н. «hot-plug» подключением устройств: если операционная система уже загрузилась и находится в рабочем состоянии, и вы подключаете к ней USB-устройство, то SysV не распознает данное USB-устройство.
В ОС, использующей систему инициализации SysV, обычно присутствует специальная программа, используемая для управления службами во время работы системы. Вы можете проверить состояние службы или всех служб, а также запустить или остановить службу при помощи следующих команд:
# service <имя_службы> status
(отображение статуса конкретной службы)
# service --status–all
(отображение статуса всех служб)
# service <имя_службы> start|stop
(запуск/остановка конкретной службы)
systemd
systemd — это относительно новая система инициализации Linux, представляющая собой набор утилит для запуска и управления всеми типами процессов и служб (а также устройствами, сокетами, точками монтирования, областью подкачки, модулями и пр.).
Основные цели проектирования данной системы инициализации, по словам Леннарта Пёттеринга, ведущего разработчика systemd, заключаются в том, чтобы «запускать меньше, распараллеливать больше». Это означает, что вы запускаете только те процессы, которые сто процентов необходимы для приведения системы в рабочее состояние, и одновременно выполняете как можно больше таких задач. Все вызовы, которые раньше (при использовании SysV) были «размазаны» по множеству различных скриптов, теперь выполняются одним файлом — lib/systemd/systemd. Первоначально systemd выпускалась под лицензией GNU GPL, но в дальнейшем её сменили на GNU LGPL.
Процесс systemd (от англ. «system management daemon») — это системный демон, который (подобно процессу init) является родителем (прямым или косвенным) всех других процессов, и имеет PID=1
. Вместе с systemd были введены и новые понятия:
Unit — это модуль, отвечающий за отдельно взятую службу, точку монтирования, подключаемое устройство, файл подкачки, виртуальную машину и тому подобные ресурсы.
Target — это аналог уровней выполнения из SysV, состоящий из нескольких unit-ов.
systemd выполняет unit для достижения target. Инструкции для каждого устройства находятся в каталоге /lib/systemd/system/.
Для управления службами в systemd применяется специальная утилита — systemctl. Например:
# systemctl enable sshd
(включение sshd)
# systemctl start sshd
(запуск sshd)
# systemctl stop sshd
(остановка sshd)
# systemctl status sshd
(отображение состояния sshd)
# systemctl list-units
(отображение списка модулей)
Еще одной важной программой в наборе инструментов systemd является утилита journalctl. Она позволяет просматривать и управлять демоном логов journald. Лог-файл systemd является двоичным файлом, и использование journalctl сильно упрощает работу с ним. Вот несколько примеров:
# journalctl –all
(отображение содержимого всего лог-файла)
# journalctl -b
(отображение данных лог-файла с момента последней загрузки)
# journalctl -b -p err
(отображение ошибок при последней загрузке)
Плюсы системы инициализации systemd:
Новый, современный и эффективный дизайн.
Более простой процесс загрузки.
Параллельная обработка задач при загрузке системы.
Улучшенный API.
Простой синтаксис unit-файлов.
Возможность удаления дополнительных компонентов.
Низкий уровень потребления ресурсов.
Улучшен механизм зависимостей.
Инструкция инициализации процессов хранится в файле конфигурации, а не в скрипте оболочки.
Планирование задач с использованием systemd Calendar Timers.
Ведение лог-файла с помощью службы journald.
Лог-файлы хранятся в двоичных файлах.
Состояние systemd может быть сохранено для последующего вызова в будущем.
Отслеживание исполняемого процесса через механизм контейнеризации cgroup.
Вход пользователей в систему управляется с помощью systemd-logind.
Улучшенная интеграция с GNOME для обеспечения совместимости.
Минусы системы инициализации systemd:
Всё собрано в одном месте.
Не соответствует стандартам POSIX.
Отсутствие кроссплатформенности.
Дистрибутивы Linux | Интеграция |
Fedora | Да (это первый дистрибутив, перешедший на systemd). |
Arch | Да. |
RHEL | Да. |
CentOS | Да. |
Debian | Да, начиная с 8-й версии. |
OpenSUSE | Да. |
Slackware | Нет. |
Ubuntu | Да. |
Upstart
Upstart — это гибридная система инициализации (могут использоваться как скрипты запуска SysV, так и сценарии systemd), созданная разработчиками дистрибутива Ubuntu в качестве замены системы инициализации SysV. В отличие от SysV, которая создавалась для работы в статическом окружении, Upstart предназначалась для работы в более гибком окружении.
По сравнению с SysV, в Upstart можно выделить три основных преимущества, а именно: управление службами на основе событий (вместо уровней выполнения), асинхронный запуск служб и автоматический перезапуск аварийно завершенных служб.
Основное отличие от SysV заключается в том, что Upstart реализует управляемую событиями модель, которая позволяет асинхронно реагировать на основные этапы запуска служб по мере их достижения. Для этого в Upstart существуют задания, прописанные в файлах в /etc/init/*.conf, целью которых является выполнение секции скрипта, ответственной за создание процесса. Таким образом, инициализация системы может быть выражена в виде последовательного набора правил «создавать процесс X при наступлении события Y».
Когда происходит какое-либо событие, Upstart обнаруживает это событие и вносит необходимые изменения. Событием может быть всё, что связано с различными состояниями системы, например: USB-накопитель подключается/извлекается из системы или запускается/останавливается служба.
Но и у данной системы инициализации есть свои минусы. Так как в её основе заложена событийная модель реагирования, то вместо выполнения абсолютного минимального объема работы, необходимого для приведения системы в рабочее состояние, при срабатывании события Upstart выполняет все задания, которые могут последовать за ним. Например, если запустилась сеть, это еще не значит, что NFS (сокр. от «Network File System») также должна запуститься. На самом деле, корректная последовательность является противоположной: когда пользователь запрашивает доступ к общему ресурсу NFS, система должна проверить, что сеть запущена и работает.
Для управления уровнем запуска различных служб в Upstart применяется специальная утилита — initctl, например:
$ initctl status <job>
(отображение состояния службы)
$ initctl list
(отображение списка служб)
# initctl start|stop <job>
(запуск/остановка службы)
OpenRC
OpenRC — это кроссплатформенная система инициализации на основе зависимостей, которая совместима с SysV. Несмотря на то, что OpenRC вносит некоторые улучшения в SysV, она не является её абсолютной заменой.
Особенности OpenRC:
Может работать во многих дистрибутивах Linux, включая Gentoo.
Скрипты инициализации с отслеживанием состояния.
Ограничение ресурсов для каждой службы.
Загрузка на основе зависимостей.
Запускается в виде демона.
Параллельный запуск служб и многое другое.
runit
runit — также кроссплатформенная система инициализации, которая может работать на Solaris, операционных системах семейства BSD и macOS. В целом очень похожа на SysV. Может использоваться сама по себе или же в качестве альтернативы для SysV, systemd, а также в сочетании с OpenRC.
К основным преимуществам runit относятся:
Быстрая загрузка и выключение системы.
Логирование вывода процесса и ротация логов.
Автоматическое выключение и запуск сервисов при появлении новых сервисов в списке, либо удалении старых из списка.
Возможность ведения нескольких независимых списков сервисов одновременно (например, для каждого пользователя отдельно и для системы в целом).
Переносимость.
Сравнение SysV и systemd
Функции | SysV | systemd |
Зависимость D-Bus | Нет | Да |
Управление устройствами с помощью udev | Нет | Да |
Активация по таймеру | cron/at | Проприетарная |
Управление квотами | Нет | Да |
Автоматическая обработка зависимостей служб | Нет | Да |
Завершение процессов пользователей при выходе из системы | Нет | Да |
Управление пространством подкачки | Нет | Да |
Интеграция SELinux | Нет | Да |
Поддержка шифрованных HDD | Нет | Да |
Загрузка статических модулей ядра | Нет | Да |
Графический интерфейс пользователя (GUI) | Нет | Да |
Перечисление всех дочерних процессов | Нет | Да |
Совместимость с SysV | Да | Да |
Интерактивная загрузка | Нет | Да |
Переносимость на отличную от x86 архитектуру процессора | Да | Нет |
Параллельный запуск служб | Нет | Да |
Ограничение ресурсов для каждой службы | Нет | Да |
Легко расширяемый скрипт автозагрузки | Да | Нет |
Раздельные код и файл конфигурации | Да | Нет |
Автоматический расчет зависимостей | Нет | Да |
Подробный вывод отладочной информации | Да | Нет |
Количество файлов | 75 файлов | 900 файлов + Glib + D-Bus |
Как определить какая система инициализации у меня?
Способ №1: Команда ps
С помощью команды ps мы можем отобразить информацию об активном процессе, а с помощью команды grep указать необходимые фильтры для определения текущей системы инициализации:
# ps -p1 | grep "init\|upstart\|systemd"
Debian 11 (Testing)
Fedora 34 Workstation
Как вы можете видеть, в Debian и Fedora используется система инициализации systemd.
В случае использования системы инициализации SysV, вывод команды будет следующий:
MX Linux 19.4
Если же у вас используется система инициализации Upstart, то вы увидите:
# ps -p1 | grep "init\|upstart\|systemd"
1 ? 00:00:00 upstart
Способ №2: Команда rpm
rpm (сокр. от «Red Hat Package Manager») — это мощная консольная утилита управления пакетами в дистрибутивах RHEL, CentOS, Fedora, openSUSE и Mageia. Команда rpm
позволяет устанавливать, обновлять, удалять, запрашивать и проверять программное обеспечение.
Чтобы узнать, какая система инициализации установлена, нужно выполнить следующую команду:
# rpm -qf /sbin/init
Примечание: /usr/sbin/init или /sbin/init — это исполняемый файл, запускающий систему инициализации SysV. По соображениям совместимости при установке systemd файл /sbin/init является псевдонимом (или символьной ссылкой) исполняемого файла системы инициализации systemd.
Fedora 34 Workstation
В случае использования системы инициализации SysV, вывод будет следующий:
# rpm -qf /sbin/init
SysVinit-2.86-17.el5
В случае использования системы инициализации Upstart, вывод будет следующий:
# rpm -qf /sbin/init
upstart-0.6.5-16.el6.x86_64
Важное примечание
Может случиться так, что, используя ОС с systemd в качестве системы инициализации и набрав в терминале команды pidof init
и pidof systemd
, мы увидим следующий результат:
Debian 11 (Testing)
То есть PID=1
назначен процессу init, а процесс systemd имеет PID=909
. Получается, что у нас используется SysV? Но мы ведь уверены в том, что устанавливали дистрибутив (Debian) с системой инициализации systemd! Это можно проверить с помощью следующей команды:
$ sudo ps -p1 | grep "init\|upstart\|systemd"
Debian 11 (Testing)
Так почему же возникла путаница с pidof
? Если мы проверим тип файла /sbin/init (который является файлом, запускающим систему инициализации SysV), то увидим, что в нашем случае /sbin/init является символьной ссылкой на /lib/systemd/systemd (главный файл системы инициализации systemd):
Debian 11 (Testing)
Таким образом, в нашей ОС используется именно systemd.
Статейка супер. В своем роде лучшее, что я находил.
Я обновил у себя систему Debian 6.0.3 — через 7.11 — и до 8.11.
Система инициализации осталась старая — sysvinit.
Каким образом можно теперь корректно перейти на новую — systemd?