Compare commits

...

3 Commits
v13.3 ... v14.1

Author SHA1 Message Date
nnz1024
93782fa4ec Version v14.1 (2013-01-21 04:31) [AUTO] 2017-08-17 23:05:40 +03:00
nnz1024
57b51c4e30 Version v14.0 (2013-01-20 06:01) [AUTO] 2017-08-17 23:05:40 +03:00
nnz1024
97fae68e02 Version v13.4 (2013-01-20 04:30) [AUTO] 2017-08-17 23:05:40 +03:00

337
s4a.tex
View File

@@ -1117,6 +1117,7 @@ Apache, crond, atd, которые по роду служебной деятел
+ln+.
\section{Смена корня}
\label{sec:chroots}
Практически все администраторы и разработчики рано или поздно встречаются с
\href{http://linux.die.net/man/1/chroot}{chroot-окружениями}. Системный вызов
@@ -2612,6 +2613,7 @@ systemd. Но, конечно, будет лучше, если этим займ
приложения, или сопровождающие вашего дистрибутива.
\section{К вопросу о безопасности}
\label{sec:security}
Одно из важнейших достоинств Unix-систем~--- концепция разделения привилегий
между различными компонентами ОС. В частности, службы обычно работают от имени
@@ -3337,42 +3339,44 @@ StartLimitAction=reboot-force
для краткости изложения, при переводе используется не~вполне корректный, но
хорошо знакомый администраторам жаргонизм <<последовательная консоль>>. Также
отметим, что в данном документе термины <<консоль>> и <<терминал>> используются
как синонимы.} достаточно добавить параметр ядра \verb+console=ttyS0+, и systemd
автоматически запустит getty на этом терминале.}
как синонимы.} достаточно указать в загрузчике параметр ядра
\verb+console=ttyS0+, и systemd автоматически запустит getty на этом терминале.}
Физический последовательный порт
\href{https://ru.wikipedia.org/wiki/RS-232}{RS-232}, хотя уже и стал редкостью
на современных настольных компьютерах, тем не~менее, продолжает играть
важную роль на современных серверах и встраиваемых системах. Он предоставляет
простой и надежный доступ к управлению системой, даже когда сеть упала, а
основной интерфейс управления завис. Кроме того, эмуляция последовательной
консоли часто используется при управлении виртуальными машинами.
на современных настольных компьютерах, тем не~менее, продолжает играть важную
роль как на серверах, так и во встраиваемых системах. Он предоставляет простой и
надежный доступ к управлению системой, даже когда сеть упала, а основной
интерфейс управления завис. Кроме того, эмуляция последовательной консоли часто
используется при управлении виртуальными машинами.
Разумеется, в Linux уже давно реализована поддержка работы с последовательными
консолями, однако при разработке
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} мы постарались
консолями но, при разработке
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}, мы постарались
сделать работу с ними еще проще. В этой статье я хочу рассказать о том, как в
systemd реализован запуск \href{https://ru.wikipedia.org/wiki/Getty}{getty} на
терминалах различных типов.
Для начала, хотелось бы отметить следующий момент: в большинстве случаев, чтобы
Для начала, хотелось бы отметить один важный момент: в большинстве случаев, чтобы
получить приглашение к логину на последовательном терминале, вам не~нужно
совершать никаких дополнительных действий: systemd сам проверит настройки ядра,
определит их них используемую ядром консоль, и автоматически запустит на ней
getty. Таким образом, вам достаточно лишь правильно указать ядру соответствующую
консоль (например, добавив к параметрам ядра в загрузчик +console=ttyS0+).
Тем не~менее, для общего образования мы все же рассмотрим некоторые тонкости
запуска getty в systemd. Эта задача решается двумя шаблонами
Тем не~менее, для общего образования все же стоит рассмотреть некоторые
тонкости запуска getty в systemd. Эта задача решается двумя шаблонами
юнитов\footnote{Прим. перев.: Принципы работы с шаблонами и экземплярами служб
изложены в главе~\ref{sec:instances}. Для лучшего понимания нижеприведенного
материала, рекомендуется перечитать эту главу, если вы ее подзабыли.}:
материала, рекомендуется перечитать эту главу, если вы успели ее подзабыть.}:
\begin{itemize}
\item +getty@.service+ отвечает за
\href{https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C}%
{виртуальные консоли} (+/dev/tty1+ и т.д.)~--- их можно увидеть
безо всякого дополнительного оборудования, просто переключившись
на них из графического сеанса.
{виртуальные консоли} (virtual terminals, VT, известные в
системе под именами +/dev/tty1+, +/dev/tty2+ и т.д.)~--- те,
которые вы можете увидеть безо всякого дополнительного
оборудования, просто переключившись на них из графического
сеанса.
\item +serial-getty@.service+ обеспечивает поддержку всех прочих
разновидностей терминалов, в том числе, подключаемых к
@@ -3380,7 +3384,7 @@ getty. Таким образом, вам достаточно лишь прав
ряд отличий от +getty@.service+, в частности, переменная \verb+$TERM+
в нем устанавливается в значение +vt102+ (должно хорошо работать
на большинстве физических терминалов), а не~+linux+ (которое
работаеть правильно только на виртуальных консолях), а также
работает правильно только на виртуальных консолях), а также
пропущены настройки, касающиеся очистки буфера прокрутки (и
поэтому имеющие смысл только на VT).
\end{itemize}
@@ -3399,18 +3403,18 @@ getty. Таким образом, вам достаточно лишь прав
как вы переключитесь на вторую виртуальную консоль. Отказавшись от
обязательного запуска нескольких экземпляров getty, мы сэкономили немного
системных ресурсов, а также сделали загрузку системы чуть-чуть быстрее. При
этом, с точки зрения пользователя, все очень просто: как только он переключается
на виртуальную консоль, на ней запускается getty, которая выводит приглашение к
логину. Пользователь может и не~подозревать о том, что до момента переключения
ничего этого не~было. Тем не~менее, если он войдет в систему и выполнит команду
+ps+, он увидит, что getty запущены только на тех консолях, на которых он уже
побывал.
этом, с точки зрения пользователя, все осталось так же просто: как только он
переключается на виртуальную консоль, на ней запускается getty, которая выводит
приглашение к логину. Пользователь может и не~подозревать о том, что до момента
переключения приглашения не~было. Тем не~менее, если он войдет в систему и
выполнит команду +ps+, он увидит, что getty запущены только на тех консолях, на
которых он уже побывал.
По умолчанию, автоматический запуск getty производится на виртуальных консолях с
первой по шестую (чтобы свести к минимуму отличия от привычной
конфигурации)\footnote{Тем не~менее, это поведение можно легко изменить,
задавая параметр +NAutoVTs=+ в файле
\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.}
\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.}.
Отметим, что автоматический запуск getty на конкретной консоли производится
только при условии, что эта консоль не~занята другой программой. В частности,
при интенсивном использовании механизма
@@ -3429,9 +3433,9 @@ getty. Таким образом, вам достаточно лишь прав
Что касается +tty6+, то она используется исключительно для автоматического
запуска getty, и недоступна другим подсистемам, в частности, графическому
серверу\footnote{При необходимости, вы можете легко поменять резервируемую
консоль, используя параметр +ReserveVT=+ в файле
\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.}
серверу\footnote{При необходимости, вы можете легко поменять номер резервируемой
консоли (или отключить резервирование), используя параметр +ReserveVT=+ в файле
\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.}.
Мы сделали так специально, чтобы гарантировать возможность входа в систему в
текстовом режиме, даже если графический сервер займет более пяти консолей.
@@ -3446,7 +3450,7 @@ getty. Таким образом, вам достаточно лишь прав
Консолью ядра~--- это та консоль, на которую выводятся сообщения ядра. Обычно
она настраивается в загрузчике, путем добавления к параметрам ядра аргумента
наподобие +console=ttyS0+\footnote{Подробнее об этой опции см. в файле
\href{https://www.kernel.org/doc/Documentation/kernel-parameters.txt}{kernel-parameters.txt}.}
\href{https://www.kernel.org/doc/Documentation/kernel-parameters.txt}{kernel-parameters.txt}.}.
Таким образом, если пользователь перенаправил вывод ядра на последовательную
консоль, то по завершении загрузки он увидит на этой консоли приглашение для
логина\footnote{Отметим, что getty, а точнее, +agetty+ на такой консоли
@@ -3459,7 +3463,7 @@ getty. Таким образом, вам достаточно лишь прав
\href{http://www.freedesktop.org/wiki/Software/systemd/Generators}{программой-генератором}~---
\href{http://www.freedesktop.org/software/systemd/man/systemd-getty-generator.html}{systemd-getty-generator}.
Генераторы запускаются в самом начале загрузки и автоматически настраивают
различные службы в зависимости от различных факторов.
различные службы в зависимости от соответствующих факторов.
В большинстве случаев, вышеописанного механизма автоматической настройки должно
быть достаточно, чтобы получить приглашение логина там, где нужно~--- без
@@ -3483,9 +3487,9 @@ daemon-reload}.}:
указанных последовательных портов при всех последующих загрузках.
В некоторых ситуациях может возникнуть необходимость в тонкой настройке
параметров getty (например, настроенная для ядра символьная скорость непригодна
для интерактивного сеанса). Тогда просто скопируйте штатный шаблон юнита в
каталог +/etc/systemd/system+ и отредактируйте полученную копию:
параметров getty (например, заданная для вывода сообщений ядра символьная
скорость непригодна для интерактивного сеанса). Тогда просто скопируйте штатный
шаблон юнита в каталог +/etc/systemd/system+ и отредактируйте полученную копию:
\begin{Verbatim}
# cp /usr/lib/systemd/system/serial-getty@.service /etc/systemd/system/serial-getty@ttyS2.service
# vi /etc/systemd/system/serial-getty@ttyS2.service
@@ -3496,7 +3500,7 @@ daemon-reload}.}:
\end{Verbatim}
В приведенном примере создает файл настроек, определяющий запуск getty на порту
+ttyS2+ (это определяется именем, под которым мы скопировали файл~---
+serial-getty@ttyS2.service+). Все изменения настроек, сделанные в этом файле,
+serial-getty@ttyS2.service+). Все изменения настроек, сделанные в данном файле,
будут распространяться только на этот порт.
Собственно, это все, что я хотел рассказать о последовательных портах,
@@ -3523,7 +3527,9 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
удобный механизм работы с системным журналом. Однако, и в~F17, и в~F18 journal
по умолчанию сохраняет информацию только в небольшой кольцевой буфер в каталоге
+/run/log/journal+. Как и все содержимое каталога +/run+, эта информация
теряется при перезагрузке. Такой подход сильно ограничивает использование
теряется при перезагрузке\footnote{Прим. перев.: Разумеется, это никак
не~относится к традиционному демону системного лога, даже если он работает
поверх journal.}. Такой подход сильно ограничивает использование
полезных возможностей journal, однако вполне достаточен для вывода актуальных
сообщений от служб в +systemctl status+. Начиная с Fedora~19, мы собираемся
включить сохранение логов на диск, в каталог +/var/log/journal+. При этом,
@@ -3544,8 +3550,8 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
\begin{Verbatim}
# mkdir -p /var/log/journal
\end{Verbatim}
После этого рекомендуется перезагрузить систему, чтобы заполнить журнал овыми
записями.
После этого рекомендуется перезагрузить систему, чтобы заполнить журнал новыми
записями.
Так как теперь у вас есть journal, syslog вам больше не~нужен (кроме ситуаций,
когда вам совершенно необходимо иметь +/var/log/messages+ в текстовом виде), и
@@ -3557,8 +3563,8 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
\subsection{Основы}
Итак, приступим. Нижеприведенный текст демонстрирует возможности systemd~195,
входящего в Fedora~18\footnote{Обновление со 195-й версией systemd в настоящее
время находится
входящего в Fedora~18\footnote{Обновление со 195-й версией systemd на момент
написания этих строк находится
\href{https://admin.fedoraproject.org/updates/FEDORA-2012-16709/systemd-195-1.fc18}{на
тестировании} и вскоре будет включено в состав Fedora~18.}, так что, если
некоторые из описанных трюков не~сработают в F17~--- пожалуйста, дождитесь F18.
@@ -3571,14 +3577,22 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
\end{Verbatim}
Если вы выполнили эту команду с полномочиями root, вы увидите все
журнальные сообщения, включая исходящие как от системных компонентов, так и от
залогиненных пользователей. Вывод этой команды форматируется в стиле
+/var/log/messages+, однако в нем добавлены кое-какие улучшения:
залогиненных пользователей\footnote{Прим. перев.: А если вы выполнили эту
команду от имени непривилегированного пользователя, не~входящего в группу
+adm+, и при этом не~включили сохранение логов на диск, то вы не~увидите
ничего~--- без специальных полномочий пользователь может просматривать только
собственный лог, а он по умолчанию ведется только если логи записываются на
диск.}. Вывод этой команды форматируется в стиле
+/var/log/messages+, но при этом добавлены кое-какие улучшения:
\begin{itemize}
\item Строки с приоритетом error и выше подсвечены красным.
\item Строки с приоритетом notice и warning выделены жирным шрифтом.
\item Все отметки времени сформированы с учетом вашего часового пояса.
\item Для навигации по тексту используется просмотрщик (pager), по
умолчанию +less+.
умолчанию +less+\footnote{Прим. перев.: В инструментах systemd,
включая journalctl, просмотрщик включается только при прямом
выводе на экран, и отключается при перенаправлении вывода в файл
или передаче его по каналу (shell pipe).}.
\item Выводятся \emph{все} доступные данные, включая информацию из
файлов, прошедших ротацию (rotated logs).
\item Загрузка системы отмечается специальной строкой, отделяющей
@@ -3587,7 +3601,8 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
Отметим, что в данной статье не~приводятся примеры такого вывода~--- прежде
всего, для краткости изложения, но также и для того, чтобы дать вам повод
поскорее попробовать Fedora~18 с systemd~195. Надеюсь, вы поймете суть и так.
поскорее попробовать Fedora~18 с systemd~195. Надеюсь, отсутствие таких примеров
не~помешает вам уловить суть.
\subsection{Контроль доступа}
@@ -3620,10 +3635,10 @@ $ journalctl
\subsection{Отслеживание логов в реальном времени}
Когда вы запускаете программу +journalctl+ без параметров, она выводит все
сообщения, сгенерированные на текущий момент. Однако, иногда бывает полезно
отслеживать их появление в режиме реального времени. В классической реализации
syslog это осуществлялось командой +tail -f /var/log/messages+. В journal ее
аналог выглядит так:
сообщения, сгенерированные на текущий момент, и возвращает управление оболочке.
Однако, иногда бывает полезно отслеживать их появление в режиме реального
времени. В классической реализации syslog это осуществлялось командой
+tail -f /var/log/messages+. В journal ее аналог выглядит так:
\begin{Verbatim}
$ journalctl -f
\end{Verbatim}
@@ -3669,13 +3684,13 @@ $ journalctl -u httpd --since=00:00 --until=9:30
\begin{Verbatim}
$ journalctl /dev/sdc
\end{Verbatim}
Кошмар, ошибка ввода-вывода!\footnote{Ну ладно, признаюсь, здесь я немножко
Кошмар, ошибка ввода-вывода\footnote{Ну ладно, признаюсь, здесь я немножко
считерил. Индексирование сообщений ядра по блочным устройствам пока что
не~принято в апстрим, но Ганс
\href{http://www.spinics.net/lists/linux-scsi/msg62499.html}{проделал огромную
работу}, чтобы реализовать эту функциональность, и я надеюсь, что к релизу F18
все будет.} Нужно срочно заменить диск, пока не~начались более серьезные
проблемы. Ладно, пошли дальше. Что у нас там случилось с процессом vpnc?
все будет.}! Нужно срочно заменить диск, пока не~начались более серьезные
проблемы. Ладно, пойдем дальше. Что у нас там случилось с процессом vpnc?
\begin{Verbatim}
$ journalctl /usr/sbin/vpnc
\end{Verbatim}
@@ -3735,7 +3750,7 @@ Tue, 2012-10-23 23:51:38 CEST [s=ac9e9c423355411d87bf0ba1a9b424e8;i=4301;b=5335e
\href{http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html}%
{странице руководства}.
И база данных Journal индексируется по \emph{всем} этим полям! И мы можем
База данных Journal индексируется по \emph{всем} этим полям! И мы можем
использовать любое из них в качестве критерия выборки:
\begin{Verbatim}
$ journalctl _UID=70
@@ -3746,18 +3761,18 @@ $ journalctl _UID=70
\begin{Verbatim}
$ journalctl _UID=70 _UID=71
\end{Verbatim}
Указание двух значений для одного и того же поля эквивалентно логическому ИЛИ.
Таким образом, будут выведены записи как от процессов с UID 70, так и от
Указание нескольких значений для одного и того же поля эквивалентно логическому
ИЛИ. Таким образом, будут выведены записи как от процессов с UID 70, так и от
процессов с UID 71.
\begin{Verbatim}
$ journalctl _HOSTNAME=epsilon _COMM=avahi-daemon
\end{Verbatim}
А указание двух \emph{различных} полей дает эффект логического И. В результате,
будут выведены записи только от процесса +avahi-daemon+, работающего на хосте с
именем +epsilon+.
А вот указание нескольких \emph{различных} полей дает эффект логического И. В
результате, будут выведены записи только от процесса +avahi-daemon+, работающего
на хосте с именем +epsilon+.
Но мы этим не~ограничимся! Мы же суровые компьютерщики, мы хотим использовать
сложные логические выражения!
Но мы этим не~ограничимся! Мы же суровые компьютерщики, нам нужны сложные
логические выражения!
\begin{Verbatim}
$ journalctl _HOSTNAME=theta _UID=70 + _HOSTNAME=epsilon _COMM=avahi-daemon
\end{Verbatim}
@@ -3773,8 +3788,8 @@ $ journalctl _HOSTNAME=theta _UID=70 + _HOSTNAME=epsilon _COMM=avahi-daemon
\subsection{И немного магии}
Уже неплохо, правда? Но есть один недостаток~--- мы же не~сможем запомнить все
возможные значения все полей журнала! Для этого была бы нужна очень хорошая
Уже неплохо, правда? Но есть одна проблема~--- мы же не~сможем запомнить все
возможные значения всех полей журнала! Для этого была бы нужна очень хорошая
память. Но +journalctl+ вновь приходит к нам на помощь:
\begin{Verbatim}
$ journalctl -F _SYSTEMD_UNIT
@@ -3837,7 +3852,7 @@ SELinux ;-) Разумеется, такое дополнение работае
в соответствии с некоторыми правилами. В частности, это особенно актуально на
маломощных встраиваемых и мобильных системах, обладающих очень скудными
ресурсами. Но та же задача актуальна и для очень мощных вычислительных
кластеров, которые располагают огромными ресурсами, но при это несут и огромную
кластеров, которые располагают огромными ресурсами, но при этом несут и огромную
вычислительную нагрузку.
Исторически, в Linux поддерживался только одна схема управления ресурсами: все
@@ -3851,7 +3866,7 @@ CGI-процессов при прочих равных получает гор
syslog, у которой не~так много процессов.
В процессе проектирования архитектуры systemd, мы практически сразу поняли, что
управление ресурсов должно быть одной из его базовых функций, заложенных в
управление ресурсов должно быть одной из базовых функций, заложенных в
основы его структуры. В современной системе~--- неважно, серверной или
встраиваемой~--- контроль использования процессора, памяти и ввода-вывода для
различных служб нельзя добавлять задним числом. Такая функциональность должна
@@ -3915,13 +3930,13 @@ systemd предоставляет ряд высокоуровневых нас
несколькими рабочими процессами получит такую же долю процессорного времени,
как и Apache, даже если тот запустил 1000 CGI-процессов. Разумеется, такое
поведение при необходимости можно легко отключить~--- см. опцию
\href{http://0pointer.de/public/systemd-man/systemd.conf.html}{DefaultControllers=}
\hreftt{http://0pointer.de/public/systemd-man/systemd.conf.html}{DefaultControllers=}
в файле +/etc/systemd/system.conf+.
Если \emph{равномерное} распределение процессорного времени между службами вас
не~устраивает, и вы хотите выделить определенным службам больше или меньше
времени~--- используйте опцию
\href{http://0pointer.de/public/systemd-man/systemd.exec.html}{CPUShares} в
\hreftt{http://0pointer.de/public/systemd-man/systemd.exec.html}{CPUShares=} в
конфигурационном файле службы. По умолчанию это значение равно 1024. Увеличивая
это число, вы даете службе больше процессорного времени, уменьшая~---
соответственно, меньше.
@@ -4020,7 +4035,7 @@ MemoryLimit=1G
BlockIOWeight=500
\end{Verbatim}
При необходимости, вы можете задать это значение отдельно для каждого
При необходимости, вы можете задать такое значение отдельно для каждого
устройства:
\begin{Verbatim}
.include /usr/lib/systemd/system/httpd.service
@@ -4067,7 +4082,7 @@ BlockIOReadBandwith=/var/log 5M
\subsection{Прочие параметры}
Вышеописанные опции покрывают лишь малую толику настроек, поддерживаемых
различными контроллерами Linux croups. Мы добавили высокоуровневый интерфейс
различными контроллерами Linux cgroups. Мы добавили высокоуровневый интерфейс
только к тем настройкам, которые кажутся нам наиболее важным для большинства
пользователей. Из соображений удобства мы добавили механизмы, обеспечивающие
поддержку крупных единиц измерения (килобайты, мегабайты и т.д.) и
@@ -4126,6 +4141,198 @@ ControlGroupAttribute=memory.swappiness 70
и они не~так сильно ухудшают производительность. Возможно, мы рассмотрим их в
последующих статьях.
\section{Проверка на виртуальность}
Еще в начале разработки systemd, мы внимательно изучали существовавшие на тот
момент init-скрипты, выделяя наиболее типичные для них операции. Среди прочих, в
составленный нами список попала и такая функция, как определение виртуализации:
некоторые скрипты проверяли, запускаются они в виртуальном окружении (например,
KVM, VMWare, LXC и т.д.) или на полноценной, физической системе. Часть этих
скриптов отказывалась работать на виртуальных системах (например, службы
управления устройствами совершенно излишни в виртуальных контейнерах, не~имеющих
доступа к устройствам), другие же, наоборот, запускались только в определенных
виртуальных окружениях (например, всевозможные <<guest additions>>,
рекомендуемые к запуску на гостевых системах VMWare и VirtualBox). По-хорошему,
в некоторых ситуациях было бы более правильно проверять некоторые другие
условия, а не~пытаться явно определить наличие виртуализации. Тем не~менее,
всесторонне изучив вопрос, мы пришли к выводу, что во многих случаях
возможность явной проверки такого условия при запуске служб была бы очень
кстати. В результате, мы добавили поддержку соответствующей опции настройки
юнитов~---
\hreftt{http://www.freedesktop.org/software/systemd/man/systemd.unit.html}{ConditionVirtualization};
кроме того, мы создали небольшую утилиту, которую можно вызывать из
скриптов~---
\hreftt{http://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html}{systemd-detect-virt(1)};
и наконец, мы предоставили простой интерфейс для шины D-Bus, позволяющий
получить информацию о виртуализации даже непривилегированным программам.
Определить, запущен код на виртуальной системе, или на физической, на самом деле
\href{http://cgit.freedesktop.org/systemd/systemd/tree/src/shared/virt.c#n30}{не~так
уж и сложно}. В зависимости от того, какие именно механизмы виртуализации вы
хотите определить, основная работа сводится к выполнению инструкции CPUID и,
возможно, проверке некоторых файлов в +/sys+ и +/proc+. Основная трудность
здесь~--- точно знать строки, которые нужно искать. Список таких строк
необходимо поддерживать в актуальном состоянии. В настоящий момент, systemd
определяет следующие механизмы виртуализации:
\begin{itemize}
\item Полная виртуализация (т.е. виртуальные машины):
\begin{itemize}
\item qemu
\item kvm
\item vmware
\item microsoft
\item oracle
\item xen
\item bochs
\end{itemize}
\item Виртуализация на уровне ОС (т.е. контейнеры):
\begin{itemize}
\item chroot
\item openvz
\item lxc
\item lxc-libvirt
\item \hyperref[sec:chroots]{systemd-nspawn}
\end{itemize}
\end{itemize}
Рассмотрим, как можно использовать эту функциональность.
\subsection{Условия на запуск юнитов}
При помощи опции
\hreftt{http://www.freedesktop.org/software/systemd/man/systemd.unit.html}{ConditionVirtualization},
добавленной в секцию +[Unit]+ файла конфигурации юнита, вы можете обеспечить
запуск (или наоборот, отмену запуска) данного юнита в зависимости от того,
работает ли он на виртуальной системе, или нет. В случае утвердительного ответа,
также можно уточнить, какая система виртуализации при этом используется.
Например:
\begin{Verbatim}
[Unit]
Name=My Foobar Service (runs only only on guests)
ConditionVirtualization=yes
[Service]
ExecStart=/usr/bin/foobard
\end{Verbatim}
Помимо <<+yes+>> или <<+no+>>, вы также можете указать идентификатор конкретной
системы виртуализации (согласно списку выше, например, <<+kvm+>>, <<+vmware+>> и
т.д.), либо <<+container+>> или <<+vm+>> (что позволит отличить виртуализацию на
уровне ОС от полной виртуализации). Кроме того, вы можете добавить перед
значением восклицательный знак, и результат проверки будет инвертирован (юнит
запустится только в том случае, если указанная технология
\emph{не}~используется). Подробности вы можете узнать на
\href{http://www.freedesktop.org/software/systemd/man/systemd.unit.html}{странице
руководства}.
\subsection{В скриптах}
В скриптах оболочки вы можете выполнить аналогичные проверки при помощи утилиты
\hreftt{http://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html}{systemd-detect-virt(1)}.
Например:
\begin{Verbatim}
if systemd-detect-virt -q ; then
echo "Virtualization is used:" `systemd-detect-virt`
else
echo "No virtualization is used."
fi
\end{Verbatim}
Эта утилита возвращает код 0 (успех), обнаружив виртуализацию, или ненулевое
значение, если виртуализация не~выявлена. Кроме того, она выводит идентификатор
обнаруженной системы виртуализации (согласно списку выше), если это не~было
запрещено опцией +-q+. Кроме того, опции +-c+ и +-v+ позволяют ограничить
проверки только механизмами виртуализации на уровне ОС, либо полной
виртуализации, соответственно. Подробности см. на
\href{http://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html}{странице
руководства}.
\subsection{В программах}
Информация о виртуализации также представлена на системной шине:
\begin{Verbatim}
$ gdbus call --system --dest org.freedesktop.systemd1 --object-path /org/freedesktop/systemd1 \
> --method org.freedesktop.DBus.Properties.Get org.freedesktop.systemd1.Manager Virtualization
(<'systemd-nspawn'>,)
\end{Verbatim}
Если виртуализация не~выявлена, это свойство содержит пустую строку. Обратите
внимание, что некоторые контейнерные системы не~могут быть обнаружены напрямую
из непривилегированного кода. Именно поэтому мы не~стали создавать библиотеку, а
воспользовались шиной D-Bus, которая позволяет корректно решить проблему
привилегий.
Стоит отметить, что все эти инструменты определяют только <<самый внутренний>>
из задействованных механизмов виртуализации. Если вы используете несколько
систем, вложенных друг в друга, вышеописанные инструменты обнаружат только ту, в
которой они непосредственно запущены. В частности, если они работают в
контейнере, находящемся внутри виртуальной машины, они увидят только контейнер.
\section{Сокет-активация служб и контейнеров}
\href{http://0pointer.de/blog/projects/socket-activation.html}{Сокет}-%
\href{http://0pointer.de/blog/projects/socket-activation2.html}{активация}~---
это одна из наиболее интересных возможностей systemd. Еще в
\href{http://0pointer.de/blog/projects/systemd.html}{первом анонсе} нашего
проекта мы рассказывали о том, как этот механизм улучшает
параллелизацию и отказоустойчивость использующих сокеты служб, а также упрощает
формирование зависимостей между службами при загрузке. В данной статье я
продолжу рассказ о его возможностях~--- на этот раз речь пойдет об увеличении
числа служб и контейнеров, работающих на одной и той же системе, без повышения
потребления ресурсов. Другими словами: как можно увеличить количество клиентских
сайтов на хостинговых серверах без затрат на новое оборудование.
\subsection{Сокет-активация сетевых служб}
Начнем с небольшого отступления. Итак, что же такое сокет-активация, и как она
работает? На самом деле все довольно просто. systemd создает <<слушающие>>
сокеты (не~обязательно IP) от имени вашей службы (которая пока не~запущена) и
ожидает входящие соединения. Как только в сокет поступает первый запрос, systemd
запускает службу и передает ей полученные данные. После обработки запроса, в
зависимости от реализации службы, она может продолжать работу, ожидая новых
соединений, или завершиться, переложив эту задачу обратно на systemd (который
вновь запустит ее при поступлении очередного запроса). При этом, со стороны
клиента невозможно отличить, когда служба запущена, а когда~--- нет. Сокет
постоянно остается открытым для входящих соединений, и все они обрабатываются
быстро и корректно.
Такая конфигурация позволяет снизить потребление ресурсов: службы работают и
потребляют ресурсы только тогда, когда это действительно необходимо. Многие
интернет-сайты и службы могут использовать это с выгодой для себя. Например,
хостеры веб-сайтов знают, что из огромного количества существующих в Интернете
сайтов лишь малая часть получает непрерывный поток запросов. Большинство же
сайтов, хотя и должны постоянно оставаться доступными, получают запросы очень
редко. Используя сокет-активацию, вы можете воспользоваться этим: разместив
множество таких сайтов на одной системе и активируя их службы только при
необходимости, вы получаете возможность <<оверкоммита>>: ваша система
будет обслуживать сайтов больше, чем формально позволяют ее ресурсы. Разумеется,
увлекаться оверкоммитом не~стоит, иначе в моменты пиковой нагрузки ресурсов
может действительно не~хватить.
С помощью systemd вы без труда можете организовать такую схему. Множество
современных сетевых служб уже поддерживают сокет-активацию <<из коробки>> (а в
те, которые пока не~поддерживают, ее
\href{http://0pointer.de/blog/projects/socket-activation.html}{не~так уж} и
\href{http://0pointer.de/blog/projects/socket-activation2.html}{сложно}
добавить). Используя встроенный в systemd механизм управления
\hyperref[sec:instances]{экземплярами служб}, вы сможете подготовить
универсальные шаблоны конфигурации служб, и в соответствии с ними для каждого
сайта будет запускаться свой экземпляр службы. Кроме того, не~стоит забывать,
что systemd предоставляет вам \hyperref[sec:security]{богатый арсенал}
механизмов обеспечения безопасности и разграничения доступа, который позволит
изолировать клиентские сайты друг от друга (например, службы каждого клиента
будут видеть только его собственный домашний каталог, в то время как каталоги
всех остальных пользователей будут им недоступны). Итак, в конечном итоге вы
получаете надежную и масштабируемую серверную систему, на сравнительно небольших
ресурсах которой функционирует множество безопасно изолированных друг от друга
служб~--- и все это реализовано штатными возможностями вашей ОС.
Подобные конфигурации уже используются на рабочих серверах ряда компаний. В
частности, специалисты из \href{https://www.getpantheon.com/}{Pantheon}
используют такую схему для обслуживания масштабируемой инфраструктуры множества
сайтов на базе Drupal. (Стоит упомянуть, что заслуга ее внедрения в Pantheon
принадлежит Дэвиду Штрауссу. Дэвид, ты крут!)
\end{document}
vim:ft=tex:tw=80:spell:spelllang=ru