- systemd: зависимости и порядок запуска юнитов
- Зависимости юнитов
- Порядок запуска юнитов
- Уменьшение времени загрузки системы
- Как изменить порядок запуска / загрузки служб Linux?
- 6 шагов загрузки Linux на пальцах
- 1. BIOS
- 2. MBR
- 3. GRUB
- 4. Ядро или Kernel
- 5. Init
- 6. Уровень выполнения программ (Runlevel)
- Дополнения, исправления, уточнения
- Управление службами Linux
- Немного теории
- Утилита systemctl
- Управление службами Linux
- Автозагрузка служб в systemd
- Выводы
systemd: зависимости и порядок запуска юнитов
Оригинал: systemd: Unit dependencies and order
Автор: Paul W. Frields
Дата публикации: 25 ноября 2015 г.
Перевод: А. Панин
Дата перевода: 22 декабря 2015 г.
И снова добро пожаловать в нашу серию статей о возможностях системы инициализации systemd. Как вы уже наверняка догадались, прочитав предыдущие статьи серии, systemd является мощной и гибкой системой инициализации, позволяющей использовать новые механизмы для запуска системных служб и управления ими. Одно из наиболее важных отличий systemd от устаревшей системы инициализации SysVinit заключается в механизме запуска юнитов.
Вы могли слышать от обычных пользователей о том, что systemd запускает все системные службы одновременно. Некоторые люди считают это утверждение истинным и используют его в качестве обоснования более быстрой загрузки системы. Но в реальности все не так просто. Давайте рассмотрим более глубоко механизм определения отношений юнитов, использующийся в systemd.
Зависимости юнитов
Юнит-файлы позволяют описывать зависимости юнитов . В юнит-файле каждого юнита могут использоваться списки нужных и необходимых юнитов, которые должны быть запущены перед запуском данного юнита. Для объявления данных списков используются директивы Wants и Requires , а сами списки позволяют сформировать список зависимостей юнита. Разница между двумя упомянутыми директивами достаточно проста:
- Если в юнит-файле юнита unit1 для описания зависимостей используется директива Wants=unit2 , при запуске юнита unit1 будет автоматически запущен unit2. Но при этом результат запуска юнита unit2 ни коим образом не будет влиять на результат запуска юнита unit1.
- Если в юнит-файле юнита unit1 для описания зависимостей используется директива Requires=unit2 , то, как и в прошлый раз, будут запущены оба юнита, но в том случае, если юнит unit2 не будет успешно запущен, юнит unit1 будет автоматически деактивирован. Это произойдет вне зависимости от того, корректно ли будет функционировать процесс, соответствующий юниту unit1.
Вы не заметили каких-либо странностей в данном описании? Да, в нем не говорится ни слова о порядке запуска юнитов. В момент загрузки системы systemd загружает все юнит-файлы и составляет дерево зависимостей на основе описанных правил. В данных примерах при запуске юнита unit1 происходит одновременный запуск юнита unit2. Важно знать, что зависимости и порядок запуска юнитов являются двумя отдельными концепциями в рамках systemd.
А это пример описания зависимостей юнита в рамках юнит-файла sshd.service :
В соответствии с ним, при запуске юнита sshd.service также будет запущен юнит sshd-keygen.service . Однако, для успешного запуска юнита sshd.service не требуется обязательного успешного запуска юнита sshd-keygen.service .
Для чего же существуют подобные зависимости? В данном случае юнит sshd-keygen.service создает новые ключи SSH для сервера, если их не было создано заблаговременно. Наличие этих ключей следует проверять при каждом запуске сервера. Если они уже существуют, этот вспомогательный юнит завершит свою работу с возвратом информации о соответствующей ошибке. Но и вы этом случае сервер SSH будет запущен в обычном режиме.
Порядок запуска юнитов
Все описанное выше абсолютно не значит, что вы не сможете установить порядок запуска юнитов самостоятельно. При отсутствии каких-либо дополнительных инструкций, systemd действительно будет запускать группы юнитов одновременно. Скорее всего, именно по этой причине некоторые люди уверены в том, что systemd запускает все системные службы одновременно (или в «параллельном режиме»). Но, разумеется, иногда необходимо запускать процессы в определенном порядке.
К счастью, systemd также поддерживает директивы, предназначенные для решения подобных задач, а именно, Before и After . Эти директивы работают так, как вы можете предположить:
- Если юнит-файл юнита unit1 содержит директиву Before=unit2 , то при запуске обоих юнитов юнит unit1 будет запущен до момента запуска юнита unit2.
- Если юнит-файл юнита unit1 содержит директиву After=unit2 , то при запуске обоих юнитов процесс запуска юнита unit2 будет полностью завершен перед запуском юнита unit1.
И снова обратите внимание на то, что порядок запуска юнитов никак не влияет на зависимости юнитов. Ведь с помощью описанных в данном разделе директив ни в каком из случаев не будет осуществляться запуск юнита unit2. Давайте снова рассмотрим юнит-файл sshd.service :
Директива After , регламентирующая порядок запуска юнитов, позволяет гарантированно запустить сервер SSH только после того, как окончит свою работу юнит генерации ключей для узла и будет установлено сетевое соединение. (Юнит network.target позволяет осуществить гарантированный запуск юнитов, необходимых для организации сетевого соединения.) Директивы зависимостей Wants и Requires обычно используются вместе с директивой After для корректного описания как зависимостей юнитов, так и порядка их запуска.
Уменьшение времени загрузки системы
Если вы читали одну из предыдущих статей серии, вы наверняка помните о том, что SysVinit запускает каждую из служб последовательно на основании ее нумерации. Однако, systemd автоматически обрабатывает юнит-файлы, читая информацию о зависимостях и порядке запуска юнитов. Впоследствии эта информация используется для одновременного запуска служб с учетом порядка их запуска при необходимости.
Данный механизм обработки информации о юнитах является одной из причин ускорения загрузки системы при использовании systemd. Уменьшение времени загрузки системы не являлось основной целью разработки systemd, но является одним из преимуществ ее механизма обработки информации о юнитах.
Источник
Как изменить порядок запуска / загрузки служб Linux?
Как видно из названия, как изменить порядок запуска / загрузки служб Linux?
Вы можете изменить порядок, переименовав символические ссылки в /etc/rcX.d/, где x будет вашим уровнем выполнения.
Вы увидите кучу файлов, начинающихся с Sxx или Kxx. S-ссылки отслеживаются во время запуска, а K-ссылки анализируются на отключение. Хх здесь представляет порядок.
Но этот порядок установлен по причине, поэтому будьте осторожны при их изменении. Например. ntpd должен запускаться только после инициализации сетевой подсистемы.
Вместо того, чтобы делать это вручную, как предложено в других ответах, вы также можете изменить скрипт инициализации. Просто добавьте такую строку в шапку:
Это даст указание chkconfig добавить службу к уровням выполнения 3 и 5 с начальной позицией 90 и позицией уничтожения 10.
Вы хотите прочитать немного о своих уровнях запуска и каталогах rc.d. Внутри каталогов rc.d вы можете найти ссылки S и K, например, S20apache K10apache, который в основном определяет порядок запуска / выключения скриптов.
В эту архитектуру вносятся некоторые изменения, но большинство linux до сих пор ее используют.
Если вы прибыли сюда, скорее всего, у вас есть две службы, одна из которых зависит от другой, но, поскольку они запускаются в неправильном порядке, служба с зависимостью не запускается. Предложения по редактированию символических ссылок являются информативными, с точки зрения иллюстрации того, как выполняется последовательность запуска, и будут работать нормально, пока кто-то не выполнит «chkconfig on» в вашем сервисе, после чего символические ссылки будут воссозданы в том виде, в котором они были изначально. На самом деле, вы хотите решить проблему на уровне сценария инициализации, что на самом деле гораздо менее грязно. Он также будет одинаковым для разных уровней выполнения. Вероятно, вам не нужно добавлять строку «# chkconfig», как предложено в ответе 4, поскольку там, вероятно, уже будет аналогичная строка.
Я буду использовать пример сервера под управлением Openldap (slapd) с базой данных MySQL (mysqld). Конфигурирование этой пары, и почему вы можете захотеть, это совсем другая история.
При загрузке Openldap не запускается, потому что это зависит от MySQL, и последовательность запуска пытается запустить его раньше — slapd имеет позицию 27, а mysqld — позицию 64
Соответствующие символические ссылки в /etc/rc3.d/
Я ищу значения, установленные в двух сценариях инициализации:
Я редактирую строку chkconfig в /etc/rc.d/init.d/slapd, чтобы иметь стартовую позицию выше, чем в /etc/rc.d/init.d/mysqld (я выбрал 85)
Я делаю «chkconfig slapd on» и перепроверяю символические ссылки
Теперь, когда этот сервер запускается, mysqld запускается до slapd, и с миром все в порядке.
Источник
6 шагов загрузки Linux на пальцах
Нажмите кнопку включения питания на вашем системнике, и спустя несколько секунд вы увидите окно входа в систему.
Посмею предположить, что каждого интересовало хоть когда-либо то, что происходит за занавесом заставок и загрузочных экранов с момента включения питания компьютера к моменту, когда предлагается войти в систему.
Я предлагаю вам познакомиться со следующими уровнями типичной загрузки Linux:
1. BIOS
2. MBR
3. GRUB
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-194.el5PAE)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/
initrd /boot/initrd-2.6.18-194.el5PAE.img
4. Ядро или Kernel
5. Init
6. Уровень выполнения программ (Runlevel)
- Когда Линукс выполняет свою загрузку, вы можете наблюдать загрузку различных служб. К примеру, это могут быть сообщения типа «starting Postfix … OK» (запускается Postfix). Эти службы — и называются программами уровня выполнения, выполняемые из директории, которая соответствует нужному уровню выполнения.
- Исходя из настроек по умолчанию, система будет выполнять файлы в соответствии с нижеприведенными директориями.
- Выполнение уровня 0 – /etc/rc.d/rc0.d/
- Выполнение уровня 1 – /etc/rc.d/rc1.d/
- Выполнение уровня 2 – /etc/rc.d/rc2.d/
- Выполнение уровня 3 – /etc/rc.d/rc3.d/
- Выполнение уровня 4 – /etc/rc.d/rc4.d/
- Выполнение уровня 5 – /etc/rc.d/rc5.d/
- Выполнение уровня 6 – /etc/rc.d/rc6.d/
- Но имейте ввиду, что еще в каталоге /etc могут быть символические ссылки. Например, /etc/rc0.d залинкован на /etc/rc.d/rc0.d.
- В каталогах /etc/rc.d/rc*.d/ вы можете увидеть список программ, имя которых начинается из букв S и K.
- Программы, начинающиеся на S используются для запуска. S, потому что startup.
- Программы, которые начинаются с литеры K используются — правильно — для завершения работы. K, потому что kill.
- Еще есть номера рядом с буквами S и K в именах программ. Эти номера используются для определения порядка запуска этих программ.
- К примеру, S12syslog предназначен для запуска демона syslog, его порядковый номер 12. S80sendmail — для запуска демона sendmail, имеющего порядковый номер 80. Таким образом, программа syslog будет запущена перед sendmail.
Вот и все. Возможно, некоторым из вас это не ново и особого интереса не было при чтении статью, поскольку она более ориентирована на начально-средний уровень знакомства з Линуксом.
В таком случае могу лишь сказать, что «повторение — мать учения» (с).
Дополнения, исправления, уточнения
В комментариях неоднократно было апеллировано к тексту статьи, поэтому, думаю, стоит учесть некоторые важные комментарии хабрасообщества. (спасибо artemlight, 3al, Tishka17, HhyperH, Next_Alex, Ilya_Shmelykh, Aux, soomrack, Xpeh )
- artemlight:: «Ну скажем прямо — так грузятся далеко не все дистры». С ним согласилось большинство, отмечая и bsd-style init, u-boot, и хоть initrd в статье пропущен, стоить заметить, что он нужен ядру не во всех дистрибутивах. Также отмечено, что в slackware поддержка rc.d осуществляется только в качестве совместимости, а встраиваемые системы грузятся иначе. На декстопах иногда бывает EFI, а кроме того Linux популярен в мире embedded и там ещё куча разных платформ. Линукс в телефоне вообще иначе грузится.
- soomrack, ссылая на википедию: Еще хочется сделать замечание по поводу MBR, первого сектора и пр. Все несколько усложнилось за последние годы. Сейчас уместней говорить о EFI.
Источник
Управление службами Linux
В операционной системе linux, так же как и в Windows, кроме обычных программ, которые могут взаимодействовать с пользователем есть еще один вид программ. Это работающие в фоне службы. Важность служб тяжело переоценить, они следят за состоянием системы, обеспечивают автоматическое подключение внешних устройств и сети, позволяют процессам взаимодействовать с оборудованием (dbus), а также в виде служб реализованы различные веб-серверы и серверы баз данных. В отличие от пользовательских программ, службы выполняются в фоне, и пользователь не имеет к ним прямого доступа. Пользователь еще не вошел в систему, только началась загрузка а основные службы уже запущенны и работают.
В этой статье мы рассмотрим управление службами Linux. Мы не будем трогать уже устаревшие системы, такие как SysVinit, сосредоточимся только на Systemd. Вы узнаете, как посмотреть запущенные службы linux, а также останавливать и запускать их самому.
Немного теории
Чтобы всем этим управлять нужна основная служба — система инициализации, которая будет запускать службы linux в нужный момент, следить чтобы они нормально работали, записывать сообщения логов, и самое главное позволять останавливать службы. Раньше, для управления службами использовались скрипты. Я уже говорил, что можно запустить службу из терминала, так вот, каждая служба запускалась в фоновом режиме одна за другой, без возможности параллельного запуска и возвращала свой PID процесса скрипту инициализации, он сохранялся и потом с помощью этого PID можно было проверить работает ли служба и остановить службу linux если это нужно. Все это можно сделать и вручную.
Но потом на смену этому методу пришла новая модель и система инициализации systemd. Система инициализации запускается сразу после загрузки ядра и начинает инициализировать службы, теперь появилась возможность параллельной инициализации, а также зависимостей между службами. Таким образом, теперь можно определить сложное дерево порядка запуска служб. Но мы не будем вникать в подробности создания служб, нас интересует только сам процесс запуска. После запуска systemd собирает весь вывод службы в лог, и следит за ее работой, если служба аварийно завершилась, то автоматически ее перезапускает.
Служба в Systemd описывается файлом юнита, в нем описано что с ней нужно делать и как себя вести. Существуют такие типы служб:
- service — обычная служба, программа
- target — группа служб
- automount — точка автоматического монтирования
- device — файл устройства, генерируется на этапе загрузки
- mount — точка монтирования
- path — файл или папка
- scope — процесс
- slice — группа системных служб systemd
- snapshot — сохраненное состояние запущенных служб
- socket — сокет для взаимодействия между процессами.
Нас будут интересовать только service, и совсем немного target, но мы рассмотрели все остальные, чтобы вы смогли взглянуть на картину немного шире. Основы рассмотрели, теперь будет настройка служб LInux.
Утилита systemctl
В Systemd есть специальный инструмент для управления службами в Linux — systemctl. Эта утилита позволяет делать очень много вещей, начиная от перезапуска службы linux и проверки ее состояния, до анализа эффективности загрузки службы. Синтаксис у утилиты такой:
$ systemctl опции команда служба служба.
Опции настраивают поведение программы, подробность вывода, команда — указывает что нужно сделать со службой, а служба, это та самая служба, которой мы собираемся управлять. В некоторых случаях утилита может использоваться без указания команды и службы.
Рассмотрим все по порядку. Опции очень сильно зависят от команд, поэтому рассмотрим их позже, а пока пройдемся по командах:
- list-units — посмотреть все службы (юниты), аналог опции -t
- list-sockets — посмотреть все службы сокетов
- start — запустить службу linux
- stop — остановить службу linux
- reload — обновить конфигурацию службы из файла юнита
- restart — перезапустить службу
- try-restart — перезапустить службу, только если она запущена
- reload-or-restart — обновить конфигурацию затем выполнить перезапуск службы linux, если не поддерживается — только перезапустить
- isolate — запустить только одну службу вместе с ее зависимостями, все остальные остановить
- kill — отправить сигнал завершения процессу используется вместе с опциями —signal и —kill-who
- is-active — проверить запущена ли служба linux
- is-failed — проверить не завершилась ли служба с ошибкой
- status — посмотреть состояние и вывод службы
- show — посмотреть параметры управления службой в Linux
- reset-failed — перезапустить службы linux, завершившиеся с ошибкой
- list-dependencies — посмотреть зависимости службы linux
- list-unit-files — вывести все установленные файлы служб
- enable — добавить службу в автозагрузку
- disable — удалить службу из автозагрузки
- is-enabled — проверить если ли уже служба в автозагрузке
- reenable — сначала выполнить disable потом enable для службы
- list-jobs — все запущенные службы linux независимо от типа
- snapsot — сохранить состояние служб, чтобы потом восстановить
- daemon-reload — обновить конфигурацию всех служб
- mask — сделать юнит недоступным
- unmask — вернуть файл службы linux
А теперь основные опции:
- -t, —type — тип служб для вывода
- -a, —all — показать все известные службы, даже не запущенные
- -q — минимальный вывод
- —version — версия программы
- —no-pager — не использовать постраничную навигацию
- —no-legend — не выводить подробное описание
- -f — принудительное выполнение команды
- —runtime — не сохранять вносимые изменения после перезагрузки
- -n — количество строк вывода лога для команды status
- —plain — использовать обычный текстовый режим вместо деревьев
- —kill-who — задать процесс, которому нужно отправить сигнал
- —signal — сигнал, который нужно отправить.
- —state — отфильтровать список служб по состоянию.
Как видите, опции будут мало полезны и лучше обратить больше внимания на команды, с помощью них выполняются все действия.
Управление службами Linux
Теперь, когда вы уже знаете все основы, команды и параметры можно переходить к делу. Со всеми остальными тонкостями разберемся по пути. Сначала давайте посмотрим запущенные службы linux. Нас будут интересовать только программы, а не все эти дополнительные компоненты, поэтому воспользуемся опцией type:
systemctl list-units —type service
Команда отобразила все службы, которые известны systemd, они сейчас запущены или были запущены. Программа не пересматривает все файлы, поэтому будут показаны только те службы, к которым уже обращались. Состояние loaded — означает, что конфигурационный файл был успешно загружен, следующая колонка active — служба была запущена, а running или exited значит выполняется ли сейчас служба или она успешно завершила свою работу. Листать список можно кнопками вверх/вниз.
Следующая команда позволяет получить список служб linux, в который входят все службы, даже не запущенные, те, которые не запускались, но известны systemd, но это еще не все службы в системе:
systemctl list-units —type service -all
Дальше больше. Вы можете отсортировать список служб systemctl по состоянию. Например, только выполняющиеся:
systemctl list-units —type service —state running
Или те, которые завершились с ошибкой:
systemctl list-units —type service —state failed
Для фильтрации можно брать любой показатель состояния из любой колонки. Другой командой мы можем посмотреть все файлы конфигурации служб на диске. Тут не будем фильтровать по типу, пусть программа покажет все:
Теперь отфильтруем только службы linux:
systemctl list-unit-files —type service
Здесь вы тоже можете использовать фильтры по состоянию. Теперь вы знаете как посмотреть запущенные службы 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 показывает добавлена ли служба в автозагрузку.
Вообще, здесь может быть несколько состояний — enabled — в автозагрузке, disabled — автозагрузка отключена, masked — служба скрыта и static — значит что служба в автозагрузке, но вы не можете ее отключить.
Поэтому чтобы получить список служб linux, запускаемых автоматически достаточно отфильтровать ее вывод по состоянию:
systemctl list-unit-files —state enabled
Все службы, запускаемые по умолчанию. Можете также посмотреть службы static. Чтобы добавить службу в автозагрузку linux используйте команду enable:
sudo systemctl enable application
А для того чтобы убрать ее из автозагрузки:
sudo systemctl disable applciation
Также, вы можете посмотреть разрешена ли сейчас автозагрзука для службы:
sudo systemctl is-enabled application
Утилита просто выведет состояние enabled, disabled или static.
Выводы
Теперь настройка служб Linux не вызовет у вас проблем. Много чего мы упустили, systemd — очень большая, сложная и многофункциональная система, которую не охватить в одной статье. Но и также очень сложно понять. Но я думаю, что все, что касается управления службами Linux мы разобрали. Если у вас остались вопросы, спрашивайте в комментариях!
Источник