что такое systemd в линукс
Управление службами Linux
В операционной системе linux, так же как и в Windows, кроме обычных программ, которые могут взаимодействовать с пользователем есть еще один вид программ. Это работающие в фоне службы. Важность служб тяжело переоценить, они следят за состоянием системы, обеспечивают автоматическое подключение внешних устройств и сети, позволяют процессам взаимодействовать с оборудованием (dbus), а также в виде служб реализованы различные веб-серверы и серверы баз данных. В отличие от пользовательских программ, службы выполняются в фоне, и пользователь не имеет к ним прямого доступа. Пользователь еще не вошел в систему, только началась загрузка а основные службы уже запущенны и работают.
В этой статье мы рассмотрим управление службами Linux. Мы не будем трогать уже устаревшие системы, такие как SysVinit, сосредоточимся только на Systemd. Вы узнаете, как посмотреть запущенные службы linux, а также останавливать и запускать их самому.
Немного теории
Но потом на смену этому методу пришла новая модель и система инициализации systemd. Система инициализации запускается сразу после загрузки ядра и начинает инициализировать службы, теперь появилась возможность параллельной инициализации, а также зависимостей между службами. Таким образом, теперь можно определить сложное дерево порядка запуска служб. Но мы не будем вникать в подробности создания служб, нас интересует только сам процесс запуска. После запуска systemd собирает весь вывод службы в лог, и следит за ее работой, если служба аварийно завершилась, то автоматически ее перезапускает.
Служба в Systemd описывается файлом юнита, в нем описано что с ней нужно делать и как себя вести. Существуют такие типы служб:
Нас будут интересовать только service, и совсем немного target, но мы рассмотрели все остальные, чтобы вы смогли взглянуть на картину немного шире. Основы рассмотрели, теперь будет настройка служб LInux.
Утилита systemctl
$ systemctl опции команда служба служба.
Рассмотрим все по порядку. Опции очень сильно зависят от команд, поэтому рассмотрим их позже, а пока пройдемся по командах:
А теперь основные опции:
Как видите, опции будут мало полезны и лучше обратить больше внимания на команды, с помощью них выполняются все действия.
Управление службами Linux
Теперь, когда вы уже знаете все основы, команды и параметры можно переходить к делу. Со всеми остальными тонкостями разберемся по пути. Сначала давайте посмотрим запущенные службы linux. Нас будут интересовать только программы, а не все эти дополнительные компоненты, поэтому воспользуемся опцией type:
Следующая команда позволяет получить список служб linux, в который входят все службы, даже не запущенные, те, которые не запускались, но известны systemd, но это еще не все службы в системе:
Дальше больше. Вы можете отсортировать список служб systemctl по состоянию. Например, только выполняющиеся:
Или те, которые завершились с ошибкой:
Для фильтрации можно брать любой показатель состояния из любой колонки. Другой командой мы можем посмотреть все файлы конфигурации служб на диске. Тут не будем фильтровать по типу, пусть программа покажет все:
Теперь отфильтруем только службы linux:
Здесь вы тоже можете использовать фильтры по состоянию. Теперь вы знаете как посмотреть запущенные службы linux, идем дальше.
Чтобы запустить службу используется команда start, например:
sudo systemctl start application.service
Причем расширение service можно опустить, оно и так подставляется по умолчанию. Если запуск прошел хорошо, программа ничего не выведет.
Остановить службу linux можно командой:
sudo systemctl stop application
Посмотреть состояние службы позволяет команда status:
sudo systemctl status application
Здесь вы можете видеть, состояние running, exited, dead, failed и т д. А также несколько последних строчек вывода программы, которые очень помогут решить проблему с запуском если она возникнет.
Автозагрузка служб в systemd
Как вы знаете, systemd позволяет автоматически загружать службы при запуске системы по мере их надобности. Команда list-unit-files показывает добавлена ли служба в автозагрузку.
Поэтому чтобы получить список служб linux, запускаемых автоматически достаточно отфильтровать ее вывод по состоянию:
Все службы, запускаемые по умолчанию. Можете также посмотреть службы static. Чтобы добавить службу в автозагрузку linux используйте команду enable:
sudo systemctl enable application
А для того чтобы убрать ее из автозагрузки:
sudo systemctl disable applciation
Также, вы можете посмотреть разрешена ли сейчас автозагрзука для службы:
sudo systemctl is-enabled application
Утилита просто выведет состояние enabled, disabled или static.
Выводы
Systemd за пять минут
Наша компания занимается администрированием веб-серверов на базе CentOS. Довольно часто наши клиенты используют веб-приложения на базе python, ruby или java. Для автозапуска подобных приложений есть готовые шаблоны для написания стартап-скриптов. Но прогресс не стоит на месте, вышел уже второй релиз CentOS 7 и, следуя старой традиции «не ставить dot-zero релизы на продакшен», мы начинаем предлагать клиентам сервера на базе CentOS 7.1 (1503).
В CentOS7, так же как и в его родителе RHEL7, используется systemd — менеджер системы и служб для Linux, совместимый со скриптами инициализации SysV и LSB. systemd обеспечивает возможности агрессивной параллелизации и много всего прочего.
Огромный монстр с множеством возможностей, гибкими настройками и мегабайтами документации…
Но что делать, если стоит задача быстро-быстро, вот прямо вчера, сделать автозапуск некоего сервиса?
Давайте выжмем из документации минимально необходимый набор информации для создания простых старт-стоп скриптов.
Systemd запускает сервисы описанные в его конфигурации.
Конфигурация состоит из множества файлов, которые по-модному называют юнитами.
Все эти юниты разложены в трех каталогах:
/usr/lib/systemd/system/ – юниты из установленных пакетов RPM — всякие nginx, apache, mysql и прочее
/run/systemd/system/ — юниты, созданные в рантайме — тоже, наверное, нужная штука
/etc/systemd/system/ — юниты, созданные системным администратором — а вот сюда мы и положим свой юнит.
[Название секции в квадратных скобках]
имя_переменной = значение
Для создания простейшего юнита надо описать три секции: [Unit], [Service], [Install]
В секции Unit описываем, что это за юнит:
Названия переменных достаточно говорящие:
Далее следует блок переменных, которые влияют на порядок загрузки сервисов:
Запускать юнит после какого-либо сервиса или группы сервисов (например network.target):
After=syslog.target
After=network.target
After=nginx.service
After=mysql.service
В итоге переменная Wants получается чисто описательной.
Если сервис есть в Requires, но нет в After, то наш сервис будет запущен параллельно с требуемым сервисом, а не после успешной загрузки требуемого сервиса
В секции Service указываем какими командами и под каким пользователем надо запускать сервис:
(по умолчанию): systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы.
systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. Данный тип используется для запуска классических демонов.
Также следует определить PIDFile=, чтобы systemd могла отслеживать основной процесс:
Команды на старт/стоп и релоад сервиса
Тут есть тонкость — systemd настаивает, чтобы команда указывала на конкретный исполняемый файл. Надо указывать полный путь.
Таймаут в секундах, сколько ждать system отработки старт/стоп команд.
Попросим systemd автоматически рестартовать наш сервис, если он вдруг перестанет работать.
Контроль ведется по наличию процесса из PID файла
В секции [Install] опишем, в каком уровне запуска должен стартовать сервис
multi-user.target или runlevel3.target соответствует нашему привычному runlevel=3 «Многопользовательский режим без графики. Пользователи, как правило, входят в систему при помощи множества консолей или через сеть»
Вот и готов простейший стартап скрипт, он же unit для systemd:
myunit.service
Кладем этот файл в каталог /etc/systemd/system/
Смотрим его статус systemctl status myunit
Если нет никаких ошибок в юните — то вывод будет вот такой:
Как полюбить systemd
Авторизуйтесь
Как полюбить systemd
Руководитель разработки в MyResume
Systemd — прародитель всех процессов, ответственный за поднятие Linux хоста.
Сегодня мы поговорим про systemd — подсистему управления службами в Linux, заменившую классический init и SystemV. И замена эта, надо сказать, достойная. Как и для большинства разработчиков, связанных с Linux, для меня init и SystemV — это, в первую очередь, запуск служб и загрузка системы, а уже потом — управление запущенными процессами.
Как и init, systemd — прародитель всех процессов, так сказать, демон инициализации демонов, ответственный за поднятие хоста в рабочее состояние.
Некоторые функции, реализуемые systemd, используются для управления системой, например, для монтирования файловых систем, управления устройствами, таймерами, а также запуска и управления системными службами для запуска системы.
В этой статье мы рассмотрим базовые функции systemd, которые используются как для запуска системы, так и после него.
Загрузка Linux
Хотя загрузка Linux – сложный и многоэтапный процесс, здесь нет никакой «магии». Перед тем как вдаваться в детали, предлагаю пройтись по процессам, которые происходят с момента включения машины до момента входа в систему.
Как правило, процесс загрузки воспринимают как нечто цельное, но это неправильно.
Загрузка состоит из, как минимум, трех разных этапов:
Запуск Линукса начинается после того, как ядро запустило либо init, либо systemd — в зависимости от того, что используется в дистрибутиве. Демоны init и systemd запускают и управляют всеми другими процессами, поэтому их часто называют прародителем всех процессов.
Важно четко понимать различия между аппаратной загрузкой, загрузкой Linux и запуском рабочей среды. Если вы понимаете, где заканчивается один процесс и начинается другой, а также какую роль играет каждый из них в запуске системы до рабочего состояния, вы с легкостью найдете, в каком конкретно месте «загрузки» возникает проблема.
Запуск Linux — последний этап процесса загрузки. Именно он позволяет вывести систему в рабочее состояние, когда вы можете работать с ней. Запуск начинается тогда, когда ядро передает управление systemd.
Что не так с systemd
Systemd вызывает довольно противоречивые реакции у системных администраторов и технических специалистов. Тот факт, что systemd ответственен за такое большое число разных задач и процессов, привел к тому, что многие разработчики и системные администраторы высказываются резко против этого демона, отказываясь от его использования в пользу классических решений.
SystemV и systemd — это два разных метода запуска Линукса. Сценарии запуска SystemV и демона init — это старый метод. А юниты target в systemd — более современный. Хотя большинство современных дистрибутивов используют для запуска, завершения работы и управления процессами systemd, есть те, что это не делают. Одна из причин — некоторые создатели дистрибутивов и системные администраторы предпочитают старый SystemV.
Однако я считаю, что у обоих методов свои преимущества.
Чем хорош SystemV
Кроме самого init, все эти скрипты и демоны — открыты и легко читаемы. Не составит никакого труда изучить эти скрипты и понять, как работает каждый из них и что конкретно происходит во время запуска системы. Однако я не думаю, что кто-то из системных администраторов часто этим занимается. Каждый запускаемый скрипт нумерован таким образом, чтобы запускать соответствующую службу в определенной последовательности. Службы запускаются последовательно и по одной за раз.
Systemd обязан своим появлением сотрудникам Red Hat — Леннарту Пёттерингу и Кэю Сиверсу. Фактически, это комплексная система больших, скомпилированных исполняемых файлов, логику которых не понять без доступа к исходному коду. Но поскольку systemd — open-source проект, проблем с «доступом к исходному коду» не возникает, просто это не очень удобно.
Однако своим появлением systemd значительно опровергает базовые принципы философии Linux. Как бинарный файл, systemd закрыт от прямого редактирования или просмотра системными администраторами. При этом он пытается «делать всё». Например, управлять запущенными службами. С другой стороны, он дает гораздо больше информации о состоянии, чем SystemV.
Systemd также управляет аппаратной частью, процессами и группами процессов, монтированием файловых систем и многим другим. Systemd присутствует практически в каждом аспекте современного Linux, что делает его универсальным инструментом управления системой. Всё это — нарушения главного принципа, который гласит, что все программы должны быть небольшими, а каждая программа должна делать что-то одно, но делать это хорошо.
Чем хорош systemd
Systemd параллельно запускает столько служб, сколько возможно, в зависимости от текущей стадии запуска системы. Естественно, это существенно ускоряет запуск. Времени от включения до экрана входа в систему тратиться гораздо меньше, чем в случае с SystemV.
Systemd управляет практически каждым аспектом работающей системы. Он может управлять запущенными службами, предоставляя значительно больше информации о состоянии, чем SystemV. Он также управляет аппаратной частью, процессами и группами процессов, монтированием файловых систем и многим другим (звучит знакомо, не правда ли?).
Инструментарий systemd — компилированные бинарные файлы, но набор инструментов открыт, потому что все конфигурационные файлы — это ASCII текст. Конфигурацию запуска можно менять через различные инструменты командной строки или GUI. Также можно менять или добавлять различные конфигурационные файлы, при необходимости.
Муки выбора
Зачем выбирать что-то одно, если можно работать с обеими подсистемами?
Я считаю, что причина всех противоречий между SystemV и systemd в том, что между ними нельзя выбирать на уровне системного администрирования. Выбор уже сделан за вас дистрибутивами и упаковщиками, но не без веских на то оснований: у замены init из-за его чрезмерно инвазивной природы, слишком много сложностей и последствий, с которыми было бы крайне сложно справиться вне создания дистрибутива.
Хотя в этом вопросе выбор уже сделан за меня, мои хосты в любом случае загружаются и работают, что все-таки, главное. Как конечный пользователь и системный администратор, мне нужно, чтобы я мог выполнять свои задачи, например, писать статьи вроде этой, устанавливать обновления, или писать скрипты, чтобы автоматизировать все, что можно и что нельзя. До тех пор, пока я могу выполнять всю работу, я не особо задумываюсь о порядке запуска, который вшит в моем дистрибутиве.
А вот о чем я думаю, так это об исправлении ошибок во время запуска или при управлении службами. Вне зависимости от используемой подсистемы, я знаю достаточно, чтобы восстановить последовательность действий при загрузке и отследить ошибки, исправив их.
Чем заменить SystemV
В прошлом уже предпринималось несколько попыток заменить SystemV чем-то более современным. Примерно два релиза подряд Fedora использовала Upstart, призванный заменить устаревающий SystemV, но Upstart не заменял init и не вносил значимых изменений в запуск. Поскольку Upstart практически не решал проблем SystemV, все усилия, связанные с его разработкой, были быстро заброшены в пользу systemd.
Несмотря на то что большинство разработчиков Linux согласны, что заменить устаревший SystemV – хорошая идея, именно за это systemd так не любят многие системные администраторы и разработчики. Вместо того чтобы пересказывать все так называемые проблемы, с которыми сталкиваются или сталкивались пользователи systemd, я лучше дам ссылку на две хороших, по моему мнению, статьи, которые ответят на все возможные вопросы по этой теме:
Линус Торвальдс, создатель ядра Линукса, кажется, не заинтересован в systemd. В 2014 году в статье ZDNet он четко высказался по этому поводу:
На самом деле, у меня нет какого-то особого мнения насчет systemd. Да, у меня были проблемы с некоторыми разработчиками, которые, как мне кажется, слишком легкомысленно относятся к ошибкам и совместимости и я думаю, некоторые решения просто безумны (например, мне не нравятся бинарные логи), но это все детали, а не фундаментальные проблемы.
Если вы вдруг не знаете манеры разговора Линуса, я напомню: если ему что-то не нравится, он очень откровенен, резок и прямолинеен в своих высказываниях. Можно сказать, его полюбили именно за его манеру высказываться о том, что ему не нравится.
В 2013 Пёттеринг написал пост в своем блоге, где развенчал мифы о systemd, попутно рассказав о цели его создания.
Задачи systemd
В зависимости от параметров, используемых при компиляции (о которых мы здесь не говорим) у systemd включает до 69 исполняемых файлов, которые выполняют, кроме прочего, следующие задачи:
Архитектура
Эти и другие задачи решаются различными демонами, управляющими программами и конфигурационными файлами. На рисунке показано, сколько компонентов входит в systemd. Это упрощенная, обзорная схема, показывающая основную архитектуру — в ней указаны не все файлы или службы. Кроме того, здесь нет никакой информации о потоке данных, который настолько сложный, что рассказывать о нем в контексте подобной обзорной статьи не имеет никакого смысла.
Архитектура systemd, автор Shmuel Csaba Otto Traian (CC BY-SA 3.0)
Если описывать все функции systemd, это заняло бы целую книгу. Но вам необязательно понимать, как компоненты systemd взаимодействуют друг с другом. Достаточно знать о компонентах и программах, управляющих различными службами Linux и позволяющих работать с логами и журналами. Но уже сейчас очевидно, что systemd это не какое-то монолитное чудовище, каким его считают некоторые критики.
systemd как PID 1
Systemd это PID 1. Некоторые функции, потенциал которых гораздо более обширный, чем в SystemV3 init, позволяют управлять многими аспектами Linux, включая монтирование файловых систем и запуск служб. Любых задач, не связанных с последовательностью запуска системы в этой статье мы не касаемся.
default.target — это символичная ссылка на настоящий target. Для настольного ПК, это, как правило, graphical.target, что эквивалентно runlevel 5 в SystemV. Для серверных решений по умолчанию стоит multi-user.target, эквивалентный runlevel 3 в SystemV. emergency.target аналогичен однопользовательскому режиму. Target’ы и службы в systemd называются юнитами.
В таблице я сравниваю target systemd со старой системой запуска runlevel в SystemV. systemd предоставляет target псевдонимы (алиасы) для обеспечения обратной совместимости. Алиасы позволяют скриптам — и системным администаторам — использовать команды SystemV, как init 3 для смены runlevel. Естественно, команды SystemV передаются в systemd для интерпретации и выполнения.
Сравнение runlevel SystemV с target systemd и некоторые алиасы target’ов
В конфигурационных файлах каждого target расписан набор зависимостей. Systemd запускает требуемые службы для запуска хоста на определенном уровне функциональности. Когда все зависимые объекты запущены, система работает на соответствующем уровне target. В таблице юниты с максимальной функциональностью указаны в верхних строках, к последним строкам их функциональность снижается.
Systemd также просматривает старые каталоги SystemV init для поиска каких-либо файлов запуска. И если подсистема их находит, она использует их в качестве конфигурационных файлов для запуска служб, описанных этими файлами. Устаревшая сетевая служба –— хороший пример той, что все еще использует файлы запуска SystemV в Fedora.
Схема 3 скопирована со страницы описания процесса загрузки проекта man-pages. В ней указана общая последовательность событий во время запуска system и основные требования по порядку загрузки.
Карта запуска systemd
Юниты sysinit.target и basic.target считаются контрольными точками в процессе запуска. Хотя одна из главных целей systemd — параллельный запуск служб, некоторые демоны и юниты должны запускаться первыми. Такие контрольные точки нельзя пропустить до тех пор, пока все необходимые службы и юниты, установленные в рамках этой контрольной точки, не будут запущены.
Sysinit.target завершается, когда все юниты, от которых он зависит, выполнены. Все эти юниты, монтирование файловой системы, настройка файла подкачки, запуск udev, установка генератора случайных чисел, инициализация низкоуровневых служб и настройка криптографических служб (если одна или несколько файловых систем зашифрованы) должны быть завершены для выполнения sysinit.target. А внутри самого sysinit.target, все процессы могут выполняться параллельно.
Юнит sysinit.target запускает все низкоуровневые службы и юниты, необходимые для достижения системой минимальной функциональности. Без их загрузки система не может перейти к basic.target.
После выполнения sysinit.target, systemd запускает все требуемые для нового target юниты. Basic.target обеспечивает дополнительную функциональность, запуская юниты, которые нужны для всех остальных target’ов. Сюда входят такие вещи, как установка путей к рабочим директориям, сокеты и таймеры.
Наконец, инициализируются target пользовательского уровня: multi-user.target или graphical.target. multi-user.target должен быть выполнен до того, как будут достигнуты зависимости graphical.target. Указанные на схеме 3 target’ы — это обычные юниты запуска. Как только один из них выполнен, запуск завершен. Если по умолчанию установлен multi-user.target, вы попадете на текстовый вариант логина в консоли. Если установлен graphical.target вы увидите графический интерфейс входа в систему; конкретный интерфейс логина GUI, который вы видите, зависит от настроек.
В мануале man-pages подробно описана последовательность и карта загрузки на начальный RAM диск (initrd), а также процесс завершения работы systemd.
В systemd также есть инструмент для вывода зависимостей всей загрузки целиком или конкретного юнита. Юнит — это контролируемый systemd блок, который может быть как каким-то конкретным демоном, например, httpd или sshd, так и таймером, монтированием, сокетом или чем-то другим. Попробуйте, введите следующую команду и посмотрите на результат:
systemctl list-dependencies graphical.target
Обратите внимание, что это команда полностью раскрывает юниты верхнего уровня, необходимые для запуска системы в GUI. Используйте — all, чтобы развернуть все остальные юниты.
Вы можете искать строки, например, «target,» «slice,» и «socket», используя инструменты поиска команды less. Теперь попробуйте.
systemctl list-dependencies multi-user.target
systemctl list-dependencies rescue.target
systemctl list-dependencies local-fs.target
systemctl list-dependencies dbus.service
Этот инструмент помогает мне визуализировать специфику зависимостей запуска хоста, на котором я работаю. Попробуйте немного изучить древо запуска для одного или нескольких ваших Linux хостов. Но будьте осторожны: как написано в руководстве man-page:
Обратите внимание, эта команда лишь выводит юниты, загруженные в текущий момент в память менеджером служб. В частности, эта команда не подходит для получения полного списка всех обратных зависимостей конкретного юнита, поскольку она не покажет зависимостей незагруженных юнитов.
Пост скриптум
Даже касаясь systemd лишь поверхностно, очевидно, что это мощный, но сложный инструмент. Также очевидно, что systemd не является монолитным, огромным или непонятным исполняемым файлом. Скорее, это большое число небольших компонентов и подкоманд, созданных для выполнения конкретных задач.
В следующей статье мы детально коснемся загрузки systemd, конфигурационных файлов, смены target по умолчанию, а также поговорим о том, как создать простой юнит.