Объяснение целей systemd: эффективное управление состояниями загрузки и уровнями выполнения

Поймите цели systemd, эквиваленты уровней выполнения, состояния загрузки по умолчанию, изоляцию, аварийный и графический режимы.

Объяснение целей systemd: эффективное управление состояниями загрузки и уровнями выполнения

Цели systemd — это именованные состояния системы. Цель может представлять обычную загрузку сервера, графический рабочий стол, аварийную оболочку, выключение или пользовательскую группу служб, которые вы хотите запустить вместе. Если вы перешли со старых систем Linux, цели являются заменой systemd для тех частей уровней выполнения, которые люди действительно использовали, но они более гибкие, поскольку построены на зависимостях, а не только на числах.

Обычно вы сталкиваетесь с целями, когда сервер загружается в неправильный режим, дисплейный менеджер рабочего стола не запускается или руководство по восстановлению предлагает вам войти в rescue.target. Знание нескольких команд делает такие ситуации гораздо менее загадочными.

Эволюция от уровней выполнения к целям systemd

Исторически системы Linux использовали концепцию, называемую уровнями выполнения, для определения состояния работы системы во время загрузки и во время выполнения. Уровень выполнения был числовым идентификатором (0-6), который определял, какие службы запускаются или останавливаются. Например, уровень выполнения 3 обычно означал многопользовательский текстовый режим, а уровень выполнения 5 указывал на графическую многопользовательскую среду. Эта система, хотя и была функциональной, имела ограничения:

  • Жесткость: Уровни выполнения часто определялись фиксированным или специфичным для дистрибутива образом, что затрудняло настройку точного набора служб, активных для данного состояния.
  • Неявные зависимости: Зависимости между службами часто управлялись косвенно через назначения уровней выполнения, что приводило к потенциальным конфликтам или пропущенным службам.
  • Отсутствие детализации: Числовая система не имела описательной ясности, что затрудняло понимание предполагаемого состояния системы.

Цели systemd устраняют эти ограничения, предоставляя более явный, управляемый зависимостями и описательный подход. Вместо абстрактных чисел цели имеют осмысленные имена (например, multi-user.target, graphical.target), которые четко указывают на предполагаемое состояние системы. Зависимости явно определены в файлах модулей, что гарантирует запуск всех необходимых компонентов в правильном порядке.

Примерное соответствие на многих системах systemd выглядит так:

Традиционный уровень выполнения Общий эквивалент systemd Значение
0 poweroff.target Выключение и отключение питания
1 rescue.target Однопользовательский аварийный режим
3 multi-user.target Многопользовательский текстовый/серверный режим
5 graphical.target Многопользовательский режим с графическим входом
6 reboot.target Перезагрузка

Относитесь к этому как к вспомогательному переводу, а не как к закону. Поведение уровней выполнения различалось в разных дистрибутивах, и цели systemd могут выражать отношения, которые старые уровни выполнения не могли.

Понимание целей systemd

Цель systemd сама по себе является типом модуля. Когда целевой модуль активируется, systemd пытается активировать все модули, перечисленные как зависимости в файле этой цели. Это создает каскадный эффект, гарантируя, что все необходимые службы, устройства и другие компоненты будут запущены для достижения желаемого состояния системы.

Ключевые характеристики целей systemd:

  • Управление зависимостями: Цели определяют, какие другие модули должны быть активны, чтобы цель считалась достигнутой. Это основа их мощности.
  • Точки синхронизации: Они действуют как точки синхронизации во время процесса загрузки. Система не перейдет к следующему этапу, пока текущая цель не будет полностью инициализирована.
  • Описательные имена: Цели названы описательно, что позволяет легко понять предполагаемое состояние системы (например, rescue.target, poweroff.target).

Цели обычно сами не выполняют долгоживущий код. Они группируют другие модули. Вы можете просмотреть эту группировку с помощью:

systemctl list-dependencies multi-user.target
systemctl list-dependencies graphical.target

Это хороший способ ответить на вопрос: "Почему эта служба запускается при загрузке?" Если модуль появляется в дереве зависимостей для цели по умолчанию, значит, он где-то подтягивается.

Общие цели systemd

Systemd поставляется с набором предопределенных целей, предназначенных для охвата общих состояний системы. Понимание их является ключом к управлению вашей системой.

multi-user.target

Это одна из самых фундаментальных целей. Она представляет полностью функциональную многопользовательскую систему с включенной сетью, но без графического менеджера входа или среды рабочего стола. Обычно это цель по умолчанию для серверов.

  • Назначение: Обеспечить стабильную среду для запуска служб и разрешить нескольким пользователям входить в систему через текстовые консоли или SSH.
  • Зависимости: Обычно включает модули для сети, системных служб и приглашений для входа в консоль.

Для безголовых серверов multi-user.target обычно является правильным выбором по умолчанию. Он предоставляет SSH и обычные службы без траты ресурсов на дисплейный менеджер.

graphical.target

Эта цель представляет полностью функциональную многопользовательскую систему с графической средой рабочего стола, готовой к взаимодействию с пользователем. Обычно она зависит от multi-user.target и добавляет необходимые компоненты для графического сеанса.

  • Назначение: Запустить графический дисплейный менеджер (например, GDM, LightDM, SDDM) и связанную среду рабочего стола.
  • Зависимости: Обычно подтягивает поведение multi-user.target и добавляет модули для дисплейного менеджера и компонентов графического сеанса.

Если рабочая станция загружается с черным экраном, но SSH все еще работает, сравните следующее:

systemctl get-default
systemctl status display-manager.service
journalctl -u display-manager.service -b

Цель по умолчанию говорит вам, чего система пыталась достичь. Журналы дисплейного менеджера говорят вам, почему графический слой не запустился.

rescue.target

Эта цель предоставляет минимальную однопользовательскую среду. Она в основном используется для обслуживания и восстановления системы. Она запускает базовую систему и корневую оболочку, но обычно не запускает сеть или многопользовательские службы.

  • Назначение: Обеспечить безопасную среду для системных администраторов для выполнения задач обслуживания без помех со стороны других служб.
  • Зависимости: Минимальный набор основных системных компонентов и корневая оболочка. Сеть часто недоступна, если вы не запустите ее вручную.

emergency.target

Это еще более минимально, чем rescue.target. Он поднимает систему до одной файловой системы только для чтения и корневой оболочки. Он предназначен для критических аварийных ситуаций, когда даже базовые службы могут быть проблематичными.

  • Назначение: Для критического восстановления системы, когда даже rescue.target может быть неуместен.
  • Зависимости: Только самые основные системные компоненты и корневая оболочка. Корневая файловая система может быть смонтирована только для чтения в зависимости от сбоя и дистрибутива.

reboot.target, poweroff.target, halt.target

Это специальные цели, используемые для выключения или перезагрузки системы. Когда systemd активирует одну из этих целей, он останавливает все работающие службы, а затем выполняет указанное действие (перезагрузка, выключение питания или остановка).

  • Назначение: Корректно выключить или перезагрузить систему.
  • Зависимости: Обычно они зависят от служб, которые необходимо остановить перед выключением системы.

Управление целями systemd

Systemd предоставляет несколько инструментов командной строки для взаимодействия с целями. Основным инструментом является systemctl.

Просмотр текущих целей и целей по умолчанию

Чтобы увидеть, какая цель в данный момент работает в системе и какая цель установлена по умолчанию при загрузке, используйте:

systemctl status

Эта команда предоставляет множество информации, включая активную цель. Чтобы конкретно запросить цель по умолчанию:

systemctl get-default

Чтобы увидеть все доступные цели:

systemctl list-unit-files --type=target

Чтобы увидеть активные целевые модули, используйте:

systemctl list-units --type=target

Разница такая же, как и со службами: list-unit-files показывает файлы целей, о которых знает systemd, а list-units показывает цели, загруженные или активные в работающей системе в данный момент.

Изменение цели по умолчанию

Если вы хотите, чтобы ваша система загружалась в другую цель по умолчанию (например, с графической на многопользовательскую или наоборот), вы можете использовать systemctl set-default:

Чтобы установить цель по умолчанию как graphical (обычно для настольных систем):

sudo systemctl set-default graphical.target

Чтобы установить цель по умолчанию как multi-user (обычно для серверов):

sudo systemctl set-default multi-user.target

Важно: Изменение цели по умолчанию вступит в силу только при следующей перезагрузке.

Под капотом это изменяет символическую ссылку default.target. Вы можете проверить это напрямую, если отлаживаете сломанный образ загрузки:

systemctl get-default
ls -l /etc/systemd/system/default.target

Переключение на цель (без перезагрузки)

Вы можете немедленно переключить систему на другую цель без перезагрузки. Это полезно для тестирования или временного изменения состояния системы. Используйте команду systemctl isolate:

Чтобы переключиться на графическую цель:

sudo systemctl isolate graphical.target

Чтобы переключиться на многопользовательскую цель:

sudo systemctl isolate multi-user.target

Предупреждение: systemctl isolate — это мощная команда. Изоляция до цели, такой как rescue.target или emergency.target, остановит большинство работающих служб. Убедитесь, что вы понимаете последствия, прежде чем использовать ее. Вы можете потерять сетевое подключение или графический сеанс.

На удаленном сервере будьте особенно осторожны с isolate rescue.target или isolate emergency.target. Вы можете потерять SSH и нуждаться в доступе к консоли через вашего облачного провайдера, гипервизор или физическую машину. Если вам нужно только остановить графический рабочий стол на рабочей станции, изоляция до multi-user.target менее радикальна, чем прыжок прямо в аварийный режим.

Как цели соотносятся с файлами модулей

Цели реализованы как файлы модулей, обычно расположенные в /usr/lib/systemd/system/ или /etc/systemd/system/. Файл целевого модуля (например, graphical.target) определяет зависимости от других модулей, включая другие цели и службы.

Типичный файл модуля graphical.target может выглядеть примерно так (упрощенно):

[Unit]
Description=Графическая многопользовательская система
Documentation=man:systemd.special(7)
# Эта цель предназначена для использования в качестве предварительного условия для графического менеджера входа.
# Это цель, в которую система будет загружаться, если не указано иное.
Wants=display-manager.service
Before=shutdown.target

[Install]
Alias=default.target

Здесь:

  • Wants=display-manager.service: Указывает, что display-manager.service (фактический менеджер входа, такой как GDM или LightDM) должен быть запущен, если это возможно. Это более слабая зависимость, чем Requires=.
  • Before=shutdown.target: Гарантирует, что графическая среда будет остановлена до того, как система войдет в процесс выключения.
  • Alias=default.target: Это делает graphical.target действующим как цель по умолчанию, если default.target связан с ней (что обычно так и есть для настольных систем).

Создание пользовательских целей

Хотя это менее распространено для повседневного использования, вы можете создавать свои собственные цели для определения конкретных состояний системы с уникальными наборами служб.

Шаги по созданию пользовательской цели:

  1. Создайте файл модуля .target: Поместите его в /etc/systemd/system/ (например, my-custom.target).
    [Unit]
    Description=Моя пользовательская цель
    
    [Install]
    WantedBy=multi-user.target # Или другая подходящая цель
    
  2. Создайте файлы .service или других модулей: Определите службы и другие модули, которые должны быть активны для вашей пользовательской цели.
  3. Добавьте зависимости: В файле модуля вашей пользовательской цели используйте Requires= или Wants=, чтобы указать, какие модули должны или могут быть запущены.
    [Unit]
    Description=Моя пользовательская цель
    Wants=service1.service
    Wants=service2.service
    After=service1.service service2.service
    
    [Install]
    WantedBy=multi-user.target
    
  4. Перезагрузите systemd:
    
    

sudo systemctl daemon-reload 5. **Включите/запустите вашу цель:** bash sudo systemctl start my-custom.target # Или чтобы сделать ее загружаемой sudo systemctl enable my-custom.target ```

Вариант использования: Представьте среду разработки, где вам нужны определенные серверы баз данных и приложений. Вы можете создать dev-env.target, который запускает эти службы.

Пользовательские цели также полезны для систем, похожих на приборы. Например, киоск-машина может иметь цель, которая запускает сеть, браузер, локальный сторожевой таймер и агент журналирования, но не остальную часть обычного сеанса рабочего стола. Лабораторный сервер может иметь отдельные цели для тестового стека и демонстрационного стека, чтобы операторы могли запускать известную группу служб вместе.

Лучшие практики и советы

  • Понимайте цель по умолчанию: Знайте цель по умолчанию вашей системы (graphical.target или multi-user.target), так как она определяет начальный опыт загрузки.
  • Используйте isolate с осторожностью: Будьте внимательны при использовании systemctl isolate, особенно на производственных системах, так как это может нарушить работу работающих служб.
  • Проверяйте зависимости: Если служба не запускается, изучите зависимости цели, с которой она связана, с помощью systemctl list-dependencies <имя_цели>.
  • Сервер против рабочего стола: На серверах multi-user.target почти всегда предпочтительнее для безопасности и эффективности ресурсов. На настольных компьютерах graphical.target является стандартным.
  • Обслуживание системы: Для задач, требующих минимального вмешательства, полезен rescue.target. Для критического восстановления доступен emergency.target.

Практический способ думать о целях

Для большинства административных задач вам нужна только короткая ментальная модель:

systemctl get-default
systemctl set-default multi-user.target
systemctl isolate graphical.target
systemctl list-dependencies graphical.target

get-default говорит вам, куда машина должна загружаться. set-default изменяет следующую загрузку. isolate изменяет текущее состояние и может остановить службы вне этого состояния. list-dependencies объясняет, что подтягивает цель.

Цели — это не просто переименованные уровни выполнения. Это группы зависимостей. Как только вы начнете относиться к ним таким образом, проблемы с загрузкой станет легче анализировать: найдите цель, которую система пыталась достичь, проверьте службы, которые она хотела, затем исправьте модуль или зависимость, которые не сработали.