diff --git a/s4a.tex b/s4a.tex index ae76757..2c5d5b1 100644 --- a/s4a.tex +++ b/s4a.tex @@ -43,7 +43,8 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}} \author{Lennart P\"{o}ttering (автор)\thanks{Первоисточник (на английском языке) опубликован на сайте автора: \url{http://0pointer.de/blog/projects}}\\% Сергей Пташник (русский перевод)\thanks{Актуальная версия перевода -доступна на портале OpenNet: \url{http://wiki.opennet.ru/Systemd}}\\% +доступна на личной странице переводчика: +\url{http://www2.kangran.su/~nnz/pub/s4a/}}\\% \small Данный документ доступен на условиях лицензии \href{http://creativecommons.org/licenses/by-sa/3.0/legalcode}{CC-BY-SA}} \maketitle @@ -58,7 +59,7 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}} инициализации. Окончательный переход на systemd произошел лишь в Fedora~15.}. Помимо Fedora, systemd также поддерживает и другие дистрибутивы, в частности, \href{http://en.opensuse.org/SDB:Systemd}{OpenSUSE}\footnote{Прим. перев.: -сейчас systemd поддерживается практически во всех популярных дистрибутивах для +Сейчас systemd поддерживается практически во всех популярных дистрибутивах для настольных систем.}. systemd предоставляет администраторам целый ряд новых возможностей, значительно упрощающих процесс обслуживания системы. Эта статья является первой в серии публикаций, планируемых в ближайшие месяцы. В каждой из @@ -78,9 +79,9 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}} systemd эти сообщения будут пробегать все быстрее и быстрее, вследствие чего, читать их будет все труднее. К тому же, многие пользователи применяют графические оболочки загрузки (например, Plymouth), полностью скрывающие эти -сообщения. Тем не~менее, информация, которую несут эти сообщения, была и -остается чрезвычайно важной~--- они показывают, успешно ли запустилась каждая -служба, или попытка ее запуска закончилась ошибкой (зеленое +сообщения. Тем не~менее, информация, которую они несут, была и остается +чрезвычайно важной~--- они показывают, успешно ли запустилась каждая служба, или +попытка ее запуска закончилась ошибкой (зеленое \texttt{[~\textcolor{green}{OK}~]} или красное \texttt{[~\textcolor{red}{FAILED}~]} соответственно). Итак, с ростом скорости загрузки систем, возникает неприятная ситуация: информация о результатах @@ -208,7 +209,9 @@ ntpd.service - Network Time Service \end{Verbatim} systemd сообщает нам, что ntpd был запущен (с идентификатором процесса 953) и -аварийно завершил работу (с кодом выхода 255). +аварийно завершил работу (с кодом выхода 255)\footnote{Прим. перев.: +Впоследствии, про просьбам пользователей, считавших, что слово <> +недостаточно точно отражает ситуацию, оно было заменено на <>.}. В последующих версиях systemd, мы планируем добавить возможность вызова в таких ситуациях ABRT (Automated Bug Report Tool), но для этого необходима @@ -242,7 +245,7 @@ CGI-программы, а демон cron~--- команды, предписа к разработке демонов). Также, не~будем забывать, что процесс легко может изменить свое имя посредством +PR_SETNAME+, или задав значение +argv[0]+, что также усложняет процесс его опознания\footnote{Прим. -перев.: стоит отметить, что перечисленные ситуации могут возникнуть не~только +перев.: Стоит отметить, что перечисленные ситуации могут возникнуть не~только вследствие ошибок в коде и/или конфигурации программ, но и в результате злого умысла. Например, очень часто встречается ситуация, когда установленный на взломанном сервере процесс-бэкдор маскируется под нормального демона, меняя @@ -584,7 +587,7 @@ systemd именует группы в соответствии с назван службам, но и процессов, запущенных в рамках пользовательских сеансов. В последующих статьях мы обсудим этот вопрос более подробно. -\section{HOW-TO: преобразование SysV init-скрипта в systemd service-файл} +\section{Преобразование SysV init-скрипта в systemd service-файл} \label{sec:convert} Традиционно, службы Unix и Linux (демоны) запускаются через SysV init-скрипты. @@ -867,7 +870,7 @@ service-файлы. Но, к счастью, <<проблемных>> скрип Впрочем, этот метод не~вполне корректен, так как он действует не~только на самого демона, но и на другие процессы с тем же именем. Иногда подобное поведение может привести к неприятным последствиям. Более правильным будет -использование pid-файла: +kill $(cat /var/run/syslogd.pid)$+. Вот, вроде +использование pid-файла: \verb+kill $(cat /var/run/syslogd.pid)+. Вот, вроде бы, и все, что вам нужно\ldots{} Или мы упускаем еще что-то? Действительно, мы забываем одну простую вещь: существуют службы, такие, как @@ -905,15 +908,17 @@ Apache, crond, atd, которые по роду служебной деятел как бы она ни пыталась сбежать из-под нашего контроля при помощи двойного форка или \href{http://ru.wikipedia.org/wiki/Fork-%D0%B1%D0%BE%D0%BC%D0%B1%D0%B0}{форк-бомбардировки}% -\footnote{Прим. перев.: стоит особо отметить, что использование контрольных +\footnote{Прим. перев.: Стоит особо отметить, что использование контрольных групп не~только упрощает процесс уничтожения форк-бомб, но и значительно -уменьшает ущерб от работающей форк-бомбы. Так как systemd автоматически -помещает каждую службу и каждый пользовательский сеанс в свою контрольную -группу по ресурсу процессорного времени, запуск форк-бомбы одним -пользователем или службой не~создаст значительных проблем с отзывчивостью -системы у других пользователей и служб. Таким образом, в качестве основной -угрозы форк-бомбардировки остаются лишь возможности исчерпания памяти и -идентификаторов процессов (PID).}. +уменьшает ущерб от работающей форк-бомбы. Так как systemd автоматически помещает +каждую службу и каждый пользовательский сеанс в свою контрольную группу по +ресурсу процессорного времени, запуск форк-бомбы одним пользователем или службой +не~создаст значительных проблем с отзывчивостью системы у других пользователей и +служб. Таким образом, в качестве основной угрозы форк-бомбардировки остаются +лишь возможности исчерпания памяти и идентификаторов процессов (PID). Впрочем, и +их тоже можно легко устранить: достаточно задать соответствующие лимиты в +конфигурационном файле службы (см. +\href{http://www.0pointer.de/public/systemd-man/systemd.exec.html}{systemd.exec(5)}).}. В некоторый случах возникает необходимость отправить сигнал именно основному процессу службы. Например, используя +SIGHUP+, мы можем заставить демона @@ -1048,7 +1053,13 @@ systemd и на этот случай есть простое решение, и \end{Verbatim} Итак, блокировка сводится к созданию символьной ссылки - с именем соответствующей службы, указывающей на +/dev/null+. + с именем соответствующей службы, указывающей на + +/dev/null+\footnote{Прим. перев.: Впоследствии в программу + +systemctl+ была добавлена поддержка команд +mask+ и +unmask+, + упрощающих процесс блокирования и разблокирования юнитов. + Например, для блокирования службы +ntpd.service+ теперь + достаточно команды +systemctl mask ntpd.service+. Фактически + она сделает то же самое, что и приведенная выше команда +ln+.}. После такой операции служба не~может быть запущена ни~вручную, ни~автоматически. Символьная ссылка создается в каталоге +/etc/systemd/system/+, а ее имя должно соответствовать имени @@ -1077,7 +1088,7 @@ systemd и на этот случай есть простое решение, и файлом из пакета). Стоит отметить, что блокировка службы, как и ее отключение, - является перманентной мерой\footnote{Прим. перев.: подробно + является перманентной мерой\footnote{Прим. перев.: Подробно описав принцип работы блокировки службы (юнита), автор забывает привести практические примеры ситуаций, когда эта возможность оказывается полезной. @@ -1090,21 +1101,14 @@ systemd и на этот случай есть простое решение, и ошибочно указано +systemctl restart+ (+service restart+), что является прямым указанием на запуск службы, если она еще не~запущена. Вследствие таких ошибок, отключенная служба может - <<ожить>> в самый неподходящий момент. - - Другой пример~--- - ограничение возможностей непривилегированного пользователя при - управлении системой. Даже если такому пользователю делегировано - (через механизмы sudo или PolicyKit) право на использование - +systemctl+, это еще не~означает, что он сможет запустить - заблокированную службу~--- права на выполнение +rm+ (удаление - блокирующей символьной ссылки) выдаются отдельно.}. + <<ожить>> в самый неподходящий момент.}. \end{itemize} После прочтения изложенного выше, у читателя может возникнуть вопрос: как отменить произведенные изменения? Что ж, ничего сложного тут нет: +systemctl start+ отменяет действия +systemctl stop+, +systemctl enable+ -отменяет действие +systemctl disable+, а +rm+ отменяет действие +ln+. +отменяет действие +systemctl disable+, а +rm+ отменяет действие ++ln+. \section{Смена корня} @@ -1144,8 +1148,8 @@ systemd и на этот случай есть простое решение, и init, многие параметры среды выполнения (в частности, лимиты на системные ресурсы, переменные окружения, и т.п.) наследуются от оболочки, из которой был запущен init-скрипт. При использовании systemd ситуация меняется радикально: -пользователь просто уведомляет init-демона о необходимости запустить ту или иную -службу, и тот запускает демона в чистом, созданном <<с нуля>> и тщательно +пользователь просто уведомляет процесс init о необходимости запустить ту или +иную службу, и тот запускает демона в чистом, созданном <<с нуля>> и тщательно настроенном окружении, параметры которого никак не~зависят от настроек среды, из которой была отдана команда. Такой подход полностью отменяет традиционный метод запуска демонов в chroot-окружениях: теперь демон порождается процессом init @@ -1173,19 +1177,19 @@ chroot в самой программе. Прежде всего, коррект chroot-окружения требует глубокого понимания принципов работы программы. Например, нужно точно знать, какие каталоги нужно bind-монтировать из основной системы, чтобы обеспечить все необходимые для работы программы каналы связи. С -учетом вышесказанного, эффективная chroot-защита обеспечивается в том случае, -когда она реализована в коде самого демона. Именно разработчик лучше других -знает (\emph{обязан} знать), как правильно сконфигурировать chroot-окружение, и -какой минимальный набор файлов, каталогов и файловых систем необходим внутри -него для нормальной работы демона. Уже сейчас существуют демоны, имеющие -встроенную поддержку chroot. К сожалению, в системе Fedora, установленной с -параметрами по умолчанию, таких демонов всего два: +учетом вышесказанного, эффективная chroot-защита обеспечивается только в том +случае, когда она реализована в коде самого демона. Именно разработчик лучше +других знает (\emph{обязан} знать), как правильно сконфигурировать +chroot-окружение, и какой минимальный набор файлов, каталогов и файловых систем +необходим внутри него для нормальной работы демона. Уже сейчас существуют +демоны, имеющие встроенную поддержку chroot. К сожалению, в системе Fedora, +установленной с параметрами по умолчанию, таких демонов всего два: \href{http://avahi.org/}{Avahi} и RealtimeKit. Оба они написаны одним очень хитрым человеком ;-) (Вы можете собственноручно убедиться в этом, выполнив команду +ls -l /proc/*/root+.) Возвращаясь к теме нашего обсуждения: разумеется, systemd позволяет помещать -выбранных демонов в chroot, и управлять ими точно так же, как и другими. +выбранных демонов в chroot, и управлять ими точно так же, как и остальными. Достаточно лишь указать параметр +RootDirectory=+ в соответствующем service-файле. Например: \begin{Verbatim} @@ -1252,7 +1256,7 @@ InaccessibleDirectories=/home руководства}.) Фактически, FSNS по множеству параметров превосходят +chroot()+. Скорее всего, -Avahi и ReltimeKit в ближайшем будущем перейдут с +chroot()+ к использованию +Avahi и RealtimeKit в ближайшем будущем перейдут от +chroot()+ к использованию FSNS. Итак, мы рассмотрели вопросы использования chroot для обеспечения безопасности. @@ -1267,7 +1271,7 @@ chroot-окружения, по сути, весьма примитивны: о отличается лишь содержимое файловой системы, все остальное у них общее. Например, если вы обновляете дистрибутив, установленный в chroot-окружении, и пост-установочный скрипт пакета отправляет +SIGTERM+ процессу init для его -перезапуска\footnote{Прим. перев.: во избежание путаницы отметим, что перезапуск +перезапуска\footnote{Прим. перев.: Во избежание путаницы отметим, что перезапуск процесса init (PID~1) <<на лету>> при получении +SIGTERM+ поддерживается только в systemd, в классическом SysV init такой возможности нет.}, на него среагирует именно хост-система! Кроме того, хост и chroot'нутая система будут иметь общую @@ -1288,7 +1292,7 @@ systemd имеет целый ряд возможностей, полезных Таким образом, пакетные скрипты смогут включить/отключить запуск <<своих>> служб при загрузке (или в других ситуациях), однако команды наподобие +systemctl restart+ (обычно выполняется при обновлении пакета) не~дадут никакого -эффекта внутри chroot-окружения\footnote{Прим. перев.: автор забывает отметить +эффекта внутри chroot-окружения\footnote{Прим. перев.: Автор забывает отметить не~вполне очевидный момент: такое поведение +systemctl+ проявляется только в <<мертвых>> окружениях, т.е. в тех, где не~запущен процесс init, и соответственно отсутствуют управляющие сокеты в +/run/systemd+. Такая ситуация @@ -1304,7 +1308,7 @@ debootstrap/febootstrap. В этом случае возможности +system +chroot(1)+~--- она не~только подменяет корневой каталог, но и создает отдельные пространства имен для дерева файловых систем (FSNS) и для идентификаторов процессов (PID NS), предоставляя легковесную реализацию системного -контейнера\footnote{Прим. перев.: используемые в +systemd-nspawn+ механизмы +контейнера\footnote{Прим. перев.: Используемые в +systemd-nspawn+ механизмы ядра Linux, такие, как FS NS и PID NS, также лежат в основе \href{http://lxc.sourceforge.net/}{LXC}, системы контейнерной изоляции для Linux, которая позиционируется как современная альтернатива классическому @@ -1323,7 +1327,7 @@ Linux, которая позиционируется как современна ему в штатном режиме. Также, в отличие от +chroot(1)+, внутри окружения будут автоматически смонтированы +/proc+ и +/sys+. -Следующий пример иллюстрирует возможность запустить Debian в на Fedora-хосте +Следующий пример иллюстрирует возможность запустить Debian на Fedora-хосте всего тремя командами: \begin{Verbatim} # yum install debootstrap @@ -1342,15 +1346,18 @@ Linux, которая позиционируется как современна После быстрой загрузки вы получите приглашение оболочки, запущенной внутри полноценной ОС, функционирующей в контейнере. Изнутри контейнера невозможно увидеть процессы, которые находятся вне его. Контейнер сможет пользоваться сетью -хоста, однако не~имеет возможности изменить ее настройки (это может привести к -серии ошибок в процессе загрузки гостевой ОС, но ни~одна из этих ошибок -не~должна быть критической). Контейнер получает доступ к +/sys+ и +/proc/sys+, -однако, во избежание вмешательства контейнера в конфигурацию ядра и аппаратного -обеспечения хоста, эти каталоги будут смонтированы только для чтения. Обратите -внимание, что эта защита блокирует лишь \emph{случайные}, \emph{непредвиденные} -попытки изменения параметров. При необходимости, процесс внутри контейнера, -обладающий достаточными полномочиями, сможет перемонтировать эти файловые -системы в режиме чтения-записи. +хоста\footnote{Прим. перев.: Впоследствии в +systemd-nspawn+ была добавлена +опция +--private-network+, изолирующая систему внутри контейнера от сети хоста: +такая система будет видеть только свой собственный интерфейс обратной петли.}, +однако не~имеет возможности изменить ее настройки (это может привести к серии +ошибок в процессе загрузки гостевой ОС, но ни~одна из этих ошибок не~должна быть +критической). Контейнер получает доступ к +/sys+ и +/proc/sys+, однако, во +избежание вмешательства контейнера в конфигурацию ядра и аппаратного обеспечения +хоста, эти каталоги будут смонтированы только для чтения. Обратите внимание, что +эта защита блокирует лишь \emph{случайные}, \emph{непредвиденные} попытки +изменения параметров. При необходимости, процесс внутри контейнера, обладающий +достаточными полномочиями, сможет перемонтировать эти файловые системы в режиме +чтения-записи. Итак, что же такого хорошего в +systemd-nspawn+? \begin{enumerate} @@ -1500,41 +1507,40 @@ $ systemd-analyze blame Но почему эта служба вообще присутствует в нашем процессе загрузки? На самом деле, мы можем прекрасно обойтись и без нее. Она нужна лишь как часть -используемой в Fedora схемы инициализации устройств хранения, а именно, -набора скриптов, выполняющих настройку LVM, RAID и multipath-устройств. На -сегодняшний день, реализация этих систем не~поддерживает собственного механизма -поиска и опроса устройств, и поэтому их запуск должен производиться только после -того, как эта работа уже проделана~--- тогда они могут просто последовательно +используемой в Fedora схемы инициализации устройств хранения, а именно, набора +скриптов, выполняющих настройку LVM, RAID и multipath-устройств. На сегодняшний +день, реализация этих систем не~поддерживает собственного механизма поиска и +опроса устройств, и поэтому их запуск должен производиться только после того, +как эта работа уже проделана~--- тогда они могут просто последовательно перебирать все диски. Однако, такой подход противоречит одному из -фундаментальных требований к современным компьютерам: -возможности подключать и отключать оборудование в любой момент, как при -выключенном компьютере, так и при включенном. Для некоторых -технологий невозможно точно определить момент завершения формирования списка устройств -(например, это характерно для USB и iSCSI), и поэтому процесс опроса -таких устройств обязательно должен включать некоторую фиксированную задержку, -гарантирующую, что все подключенные устройства успеют отозваться. С точки зрения -скорости загрузки это, безусловно, негативный эффект: соответствующие скрипты -заставляют нас ожидать завершения опроса устройств, хотя большинство этих -устройств не~являются необходимыми на данной стадии загрузки. В частности, в -рассматриваемой нами системе LVM, RAID и multipath вообще -не~используются!\footnote{Наиболее правильным решением в данном случае будет -ожидание событий подключения устройств (реализованное через libudev или -аналогичную технологию) с соответствующей обработкой каждого такого события~--- -подобный подход позволит нам продолжить загрузку, как только будут готовы все -устройства, необходимые для ее продолжения. Для того, чтобы загрузка была -быстрой, мы должны ожидать завершения инициализации только тех устройств, которые -\emph{действительно} необходимы для ее продолжения на данной стадии. Ожидать -остальные устройства в данном случае смысла нет. Кроме того, стоит отметить, что -в числе программ, не~приспособленных для работы с динамически меняющимся -оборудованием и построенных в предположении о неизменности списка устройств, -кроме служб хранения, есть и другие подсистемы. Например, в нашем случае работа -initrd занимает так много времени главным образом из-за того, что для запуска -Plymouth необходимо дождаться завершения инициализации всех устройств -видеовывода. По неизвестной причине (во всяком случае, неизвестной для меня) -подгрузка модулей для моих видеокарт Intel занимает довольно продолжительное -время, что приводит к беспричинной задержке процесса загрузки. (Нет, я протестую -не~против опроса устройств, но против необходимости ожидать его завершения, чтобы -продолжить загрузку.)} +фундаментальных требований к современным компьютерам: возможности подключать и +отключать оборудование в любой момент, как при выключенном компьютере, так и при +включенном. Для некоторых технологий невозможно точно определить момент +завершения формирования списка устройств (например, это характерно для USB и +iSCSI), и поэтому процесс опроса таких устройств обязательно должен включать +некоторую фиксированную задержку, гарантирующую, что все подключенные устройства +успеют отозваться. С точки зрения скорости загрузки это, безусловно, негативный +эффект: соответствующие скрипты заставляют нас ожидать завершения опроса +устройств, хотя большинство этих устройств не~являются необходимыми на данной +стадии загрузки. В частности, в рассматриваемой нами системе LVM, RAID и +multipath вообще не~используются!\footnote{Наиболее правильным решением в данном +случае будет ожидание событий подключения устройств (реализованное через libudev +или аналогичную технологию) с соответствующей обработкой каждого такого +события~--- подобный подход позволит нам продолжить загрузку, как только будут +готовы все устройства, необходимые для ее продолжения. Для того, чтобы загрузка +была быстрой, мы должны ожидать завершения инициализации только тех устройств, +которые \emph{действительно} необходимы для ее продолжения на данной стадии. +Ожидать остальные устройства в данном случае смысла нет. Кроме того, стоит +отметить, что в числе программ, не~приспособленных для работы с динамически +меняющимся оборудованием и построенных в предположении о неизменности списка +устройств, кроме служб хранения, есть и другие подсистемы. Например, в нашем +случае работа initrd занимает так много времени главным образом из-за того, что +для запуска Plymouth необходимо дождаться завершения инициализации всех +устройств видеовывода. По неизвестной причине (во всяком случае, неизвестной для +меня) подгрузка модулей для моих видеокарт Intel занимает довольно +продолжительное время, что приводит к беспричинной задержке процесса загрузки. +(Нет, я возражаю не~против опроса устройств как такового, но против +необходимости ожидать его завершения, чтобы продолжить загрузку.)} С учетом вышесказанного, мы можем спокойно исключить +udev-settle.service+ из нашего процесса загрузки, так как мы не~используем ни~LVM, ни~RAID, @@ -1549,8 +1555,8 @@ Plymouth необходимо дождаться завершения иници После перезагрузки мы видим, что загрузка стала на одну секунду быстрее. Но почему выигрыш оказался таким маленьким? Из-за второго осквернителя нашей загрузки~--- cryptsetup. На рассматриваемой нами системе зашифрован раздел -+/home+. Специально для тестирования я записал пароль в файл, чтобы исключить -влияние скорости ручного набора пароля. К сожалению, для подключения ++/home+. Специально для нашего тестирования я записал пароль в файл, чтобы +исключить влияние скорости ручного набора пароля. К сожалению, для подключения шифрованного раздела cryptsetup требует более пяти секунд. Будем ленивы, и вместо того, чтобы исправлять ошибку в cryptsetup\footnote{На самом деле, я действительно пытался исправить эту ошибку. Задержки в cryptsetup, по @@ -1567,7 +1573,7 @@ cryptsetup, что снижение этого времени с 1 секунд может продолжить загрузку и приступить к запуску служб. Но первое обращение к +/home+ (в отличие, например, от +/var+), происходит на поздней стадии процесса загрузки (когда пользователь входит в систему). Следовательно, нам -нужно сделать так, чтобы этот каталога автоматически монтировался при загрузке, +нужно сделать так, чтобы этот каталог автоматически монтировался при загрузке, но процесс загрузки не~ожидал завершения работы +cryptsetup+, +fsck+ и +mount+ для этого раздела. Как же сделать точку монтирования доступной, не~ожидая, пока завершится процесс монтирования? Этого можно достичь, воспользовавшись @@ -1737,7 +1743,7 @@ LVM, RAID и multipath). Если они вам не~нужны, вы легко конфигурация общесистемной локали. \item \hreftt{http://0pointer.de/public/systemd-man/modules-load.d.html}{/etc/modules-load.d/*.conf}: - каталог\footnote{Прим. перев.: для описания этого и трех + каталог\footnote{Прим. перев.: Для описания этого и трех последующих каталогов автор пользуется термином <>. Этот термин означает каталог, в который можно поместить множество независимых файлов настроек, и при чтении @@ -1791,8 +1797,8 @@ LVM, RAID и multipath). Если они вам не~нужны, вы легко наличия уникального и постоянного идентификатора компьютера. \item \hreftt{http://0pointer.de/public/systemd-man/machine-info.html}{/etc/machine-info}: - новый конфигурационный файл, хранящий информации о полном имени - (описательном) хоста (например, <<Компьютер Леннарта>>) и + новый конфигурационный файл, хранящий информации о полном + (описательном) имени хоста (например, <<Компьютер Леннарта>>) и значке, которым он будет обозначаться в графических оболочках, работающих с сетью (раньше этот значок мог определяться, например, файлом +/etc/favicon.png+). Данный конфигурационный @@ -1809,18 +1815,18 @@ LVM, RAID и multipath). Если они вам не~нужны, вы легко момент эти файлы полностью поддерживаются только дистрибутивами, основанными на systemd, но уже сейчас в их число входят практически все ключевые дистрибутивы, \href{http://www.ubuntu.com/}{за исключением -одного}\footnote{Прим. перев.: в конце 2010~года энтузиаст Andrew Edmunds +одного}\footnote{Прим. перев.: В конце 2010~года энтузиаст Andrew Edmunds \href{http://cgit.freedesktop.org/systemd/commit/?id=858dae181bb5461201ac1c04732d3ef4c67a0256}{добавил} в systemd базовую поддержку Ubuntu и \href{https://wiki.ubuntu.com/systemd}{подготовил} соответствующие пакеты, однако его инициатива не~встретила поддержки среди менеджеров Canonical. На момент написания этих строк (май 2011 года) проект остается заброшенным уже пять -месяцев (с середины декабря 2010~г.).}. В этом есть что-то от <<пролемы курицы и -яйца>>: стандарт становится начинает работать как стандарт только тогда, когда -ему начинают следовать. В будущем мы намерены аккуратно форсировать процесс -перехода на новые конфигурационные файлы: поддержка старых файлов будет удалена -из systemd. Разумеется, этот процесс будет идти медленно, шаг за шагом. Но -конечной его целью является переход всех дистрибутивов на единый набор базовых +месяцев (с середины декабря 2010~г.).}. В этом есть что-то от <<проблемы курицы +и яйца>>: стандарт становится настоящим стандартом только тогда, когда ему +начинают следовать. В будущем мы намерены аккуратно форсировать процесс перехода +на новые конфигурационные файлы: поддержка старых файлов будет удалена из +systemd. Разумеется, этот процесс будет идти медленно, шаг за шагом. Но конечной +его целью является переход всех дистрибутивов на единый набор базовых конфигурационных файлов. Многие из этих файлов используются не~только программами для настройки системы, @@ -1847,7 +1853,7 @@ shell-скриптов, выполняющих тривиальные задач выбрали то, что должно устроить большинство людей. Форматы конфигурационных файлов максимально просты, и их можно легко читать и записывать даже из shell-скриптов. Да, +/etc/bikeshed.conf+ могло бы быть неплохим именем -для файла конфигурации!\footnote{Прим. перев.: здесь автор намекает на +для файла конфигурации!\footnote{Прим. перев.: Здесь автор намекает на \href{http://en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality}{Паркинсоновский Закон Тривиальности}, который гласит, что самые жаркие споры возникают вокруг наиболее простых вопросов. В частности, в качестве примера Паркинсон приводит @@ -1887,7 +1893,7 @@ shed)~--- если первое из этих решений принимает зоопарк их различных реализаций в разных дистрибутивах. Назначение этих каталогов определено весьма расплывчато. Абсолютное большинство -находящихся в них файлов являются включаемыми\footnote{Прим. перев.: здесь автор +находящихся в них файлов являются включаемыми\footnote{Прим. перев.: Здесь автор использует термин sourcable, происходящий от bash'овской директивы +source+, обеспечивающей включение в скрипт кода из внешнего файла. В классическом POSIX shell это соответствует оператору-точке <<+.+>>. В отличие от прямого запуска @@ -1927,7 +1933,7 @@ init-скрипта, или даже сами не~являющиеся скри \item Режим остановки для демона. \item Общесистемные настройки, например, системная локаль, часовой пояс, параметры клавиатуры для консоли. - \item Избыточные информация о системных настройках, например, указание, + \item Избыточная информация о системных настройках, например, указание, установлены ли аппаратные часы по Гринвичу или по местному времени. \item Списки правил брандмауэра, не~являются скриптами (!). @@ -2056,11 +2062,13 @@ systemd? Одно из немногих исключений из этого правила~--- к сожалению, в настоящее время не~поддерживается автоматическая загрузка модулей на основании информации о возможностях процессора, - однако это будет исправлено в ближайшем будущем. В случае, если - нужный вам модуль ядра все же не~может быть подгружен - автоматически, все равно существует гораздо более удобные методы - указать его принудительную подгрузку~--- например, создав - соответствующий файл в каталоге + однако это будет исправлено в ближайшем будущем\footnote{Прим. + перев.: Патчи от разработчиков systemd уже приняты в ядро, и + соответствующая функция поддерживается Linux, начиная с версии + 3.3.}. В случае, если нужный вам модуль ядра все же не~может + быть подгружен автоматически, все равно существует гораздо более + удобные методы указать его принудительную подгрузку~--- + например, путем создания соответствующего файла в каталоге \hreftt{http://0pointer.de/public/systemd-man/modules-load.d.html}{/etc/modules-load.d/} (стандартный метод настройки принудительной подгрузки модулей). \item И наконец, хотелось бы отметить, что каталог +/etc+ определен как @@ -2091,16 +2099,16 @@ systemd? \item Найдите для них более подходящее место. Например, в случае с некоторыми общесистемными настройками (такими, как локаль или часовой пояс), мы надеемся аккуратно подтолкнуть дистрибутивы в - правильно направлении (см. предыдущий эпизод). + правильно направлении (см. предыдущую главу). \item Добавьте их поддержку в штатную систему настройки демона через собственные файлы конфигурации. К счастью, большинство служб, работающих в Linux, являются свободным программным обеспечением, так что сделать это довольно просто. \end{itemize} -Существует лишь одна причина поддерживать эти файлы еще некоторое +Существует лишь одна причина поддерживать файлы +/etc/sysconfig+ еще некоторое время: необходимо обеспечить совместимость при обновлении. Тем не~менее, как -минимум в новых пакетах, от этих файлов лучше отказаться. +минимум в новых пакетах, от таких файлов лучше отказаться. Если требование совместимости критично, вы можете задействовать эти конфигурационные файлы даже в том случае, если настраиваете службы через @@ -2143,7 +2151,15 @@ systemd? \emph{foobar}~--- строка, идентифицирующая службу (проще говоря, ее имя), а +.service+~--- суффикс, присутствующий в именах всех файлов конфигурации служб. Сами эти файлы могут находиться в каталогах +/etc/systemd/systemd+ и -+/lib/systemd/system+ (а также, возможно, и в других). Для служб, работающих в ++/lib/systemd/system+ (а также, возможно, и в других\footnote{Прим. перев.: В +качестве <<других>> каталогов, в которых выполняется поиск юнит-файлов, можно +упомянуть +/run/systemd/system+, в который помещаются временные файлы +конфигурации, созданные администратором или программами-генераторами и +действующие только текущем сеансе, и +/usr/lib/systemd/system+, в котором +находятся юнит-файлы для обычных служб, запускаемых на поздних стадиях загрузки +(то время, как в упомянутом каталоге +/lib/systemd/system+ находятся файлы +конфигурации ключевых системных юнитов, которые требуются на раннем этапе +загрузки, до монтирования +/usr+).}). Для служб, работающих в нескольких экземплярах, эта схема становится немного сложнее: \emph{foobar}+@+\emph{quux}+.service+, где \emph{foobar}~--- имя службы, общее для всех экземпляров, а \emph{quux}~--- идентификатор конкретного @@ -2190,7 +2206,7 @@ RestartSec=0 нем используются спецификаторы \%I и \%i. В момент загрузки юнита, systemd заменяет эти спецификаторы на идентификатор экземпляра службы. В нашем случае, при обращении к экземпляру +serial-getty@ttyUSB0.service+, они заменяются на -<<+ttyUSB0+>>. Результат этой замены можно проверить, например, запросив +<<+ttyUSB0+>>. Результат такой замены можно проверить, например, запросив состояние для этой службы: \begin{Verbatim}[commandchars=\\\{\}] $ systemctl status serial-getty@ttyUSB0.service @@ -2234,21 +2250,21 @@ systemd и заложен предварительный поиск файла В приведенном выше файле, в некоторых местах используется спецификатор +%I+, а в других~--- +%i+. У вас может возникнуть закономерный вопрос~--- чем они отличаются? +%i+ всегда точно соответствует идентификатору экземпляра, в то -время, как +%I+ соответствует экранированной (escaped) версии этого +время, как +%I+ соответствует неэкранированной (unescaped) версии этого идентификатора. Когда идентификатор не~содержит спецсимволов (например, -+ttyUSB0+). Но имена устройств, например, содержат слеши (<>), которые -не~могут присутствовать в имени юнита (и в имени файла на Unix). Поэтому, перед -использованием такого имени в качестве идентификатора устройства, оно должно -быть экранировано~--- <> заменяются на <<->>, а большинство других -специальных символов (включая <<->>) заменяются последовательностями вида -+\xAB+, где AB~--- ASCII-код символа, записанный в шестнадцатеричной системе -счисления\footnote{Согласен, этот алгоритм дает на выходе не~очень читабельный -результат. Но этим грешат практически все алгоритмы экранирования. В данном -случае, были использован механизм экранирования из udev, с одним изменением. В -конце концов, нам нужно было выбрать что-то. Если вы собираетесь комментировать -наш алгоритм экранирования~--- пожалуйста, оставьте свой адрес, чтобы я -мог приехать к вам и раскрасить ваш сарай для велосипедов в синий с желтыми -полосами. Спасибо!}. Например, чтобы обратиться ++ttyUSB0+), результат в обоих случаях одинаковый. Но имена устройств, например, +содержат слеши (<>), которые не~могут присутствовать в имени юнита (и в имени +файла на Unix). Поэтому, перед использованием такого имени в качестве +идентификатора устройства, оно должно быть экранировано~--- <> заменяются на +<<->>, а большинство других специальных символов (включая <<->>) заменяются +последовательностями вида +\xAB+, где AB~--- ASCII-код символа, записанный в +шестнадцатеричной системе счисления\footnote{Согласен, этот алгоритм дает на +выходе не~очень читабельный результат. Но этим грешат практически все алгоритмы +экранирования. В данном случае, был использован механизм экранирования из udev, +с одним изменением. В конце концов, нам нужно было выбрать что-то. Если вы +собираетесь комментировать наш алгоритм экранирования~--- пожалуйста, оставьте +свой адрес, чтобы я мог приехать к вам и раскрасить ваш сарай для велосипедов в +синий с желтыми полосами. Спасибо!}. Например, чтобы обратиться к последовательному USB-порту по его адресу на шине, нам нужно использовать имя наподобие +serial/by-path/pci-0000:00:1d.0-usb-0:1.4:1.1-port0+. Экранированная версия этого имени~--- @@ -2260,7 +2276,12 @@ systemd и заложен предварительный поиск файла спецификатор используется для ссылки на юнит +dev-%i.device+, соответствующий одноименному устройству). В то время как +%I+ удобно использовать в командной строке (+ExecStart+) и для формирования читабельных строк описания. Рассмотрим -работу этих принципов на примере нашего юнит-файла: +работу этих принципов на примере нашего юнит-файла\footnote{Прим. перев.: как +видно из нижеприведенного примера, в командной строке +systemctl+ необходимо +указывать экранированное имя юнита, что создает определенные трудности даже при +наличии в оболочке <<умного>> автодополнения. Однако, на момент написания этих +строк, в TODO проекта содержится пункт о добавлении в systemctl поддержки +неэкранированных имен юнитов.}: \begin{landscape} \begin{Verbatim}[fontsize=\small,commandchars=|\{\}] # systemctl start 'serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0.service' @@ -2275,7 +2296,7 @@ serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0. \end{landscape} Как видите, в качестве идентификатора экземпляра используется экранированная версия, в то время как в строке описания и в командной строке +getty+ -используется неэкранированная версия. Как и предполагалось. +фигурирует неэкранированный вариант, как и предполагалось. (Небольшое замечание: помимо +%i+ и +%I+, существует еще несколько спецификаторов, и большинство из них доступно и в обычных файлах конфигурации @@ -2290,32 +2311,32 @@ serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0. преобразовать SysV init-скрипт в юнит-файл systemd. В этой главе мы рассмотрим, как провести аналогичное преобразование для служб inetd. -Начнем с небольшого экскурса в историю вопроса. По давно устоявшейся традиции, +Начнем с небольшого экскурса в историю вопроса. Уже многие годы inetd считается одной из базовых служб Unix-систем. Работая как суперсервер, он слушает сетевые сокеты от имени различных служб, и активирует соответствующие службы при поступлении на эти сокеты входящих соединений. Таким образом, он обеспечивает механизм активации по запросу (on-demand activation). Подобный подход избавляет от необходимости держать постоянно работающими все серверные процессы, что позволяет поддерживать множество служб даже на системах с очень -ограниченными ресурсами. На протяжении многих лет, дистрибутивы Linux -поставляются с различными реализациями inetd. Наиболее популярные из них~--- BSD +ограниченными ресурсами. В дистрибутивах Linux можно встретить +несколько различных реализаций inetd. Наиболее популярные из них~--- BSD inetd и xinetd. Хотя inetd во многих дистрибутивах до сих пор устанавливается по -умолчанию, сейчас уже он редко используется для запуска сетевых служб~--- теперь +умолчанию, сейчас он уже редко используется для запуска сетевых служб~--- теперь большинство из них запускаются автономно при загрузке системы (основной аргумент в пользу такой схемы~--- она позволяет обеспечить более высокую производительность служб). Одной из ключевых возможностей systemd (а также launchd от Apple) является -сокет-активация~--- тот самый механизм, давным-давно реализованный inetd, +сокет-активация~--- тот же самый механизм, давным-давно реализованный inetd, однако в данном случае ключевые цели немного другие. Сокет-активация в стиле systemd прежде всего ориентирована на локальные сокеты (+AF_UNIX+), хотя поддерживаются также и сетевые сокеты (+AF_INET+). И более важное отличие~--- сокет-активация в systemd обеспечивает не~только экономию системных ресурсов, -но также и эффективную параллелизацию работы (так как она -позволяет запускать клиентов и серверы одновременно, непосредственно после -создания сокета), упрощение процесса конфигурации (отпадает необходимость явно -указывать зависимости между службами) и увеличение надежности (служебный или -экстренный, в случае падения, перезапуск службы не~приводит к недоступности +но также и эффективную параллелизацию работы (так как она позволяет запускать +клиентские и серверные процессы одновременно, непосредственно после создания +сокета), упрощение процесса конфигурации (отпадает необходимость явно указывать +зависимости между службами) и увеличение надежности (перезапуск службы, +служебный или экстренный~--- в случае падения~--- не~приводит к недоступности сокета). Тем не~менее, systemd ничуть не~хуже inetd может запускать службы в ответ на входящие сетевые соединения. @@ -2328,7 +2349,7 @@ systemd прежде всего ориентирована на локальны Однако, интерфейс, традиционно используемый в inetd, еще проще. Он позволяет передавать запускаемой службе только один сокет, который формируется из потоков STDIN и STDOUT запущенного процесса. Поддержка этого механизма также -присутствует в systemd~--- для обеспечения совместимости с множеством служб +присутствует в systemd~--- для обеспечения совместимости со множеством служб, поддерживающих сокет-активацию только в стиле inetd. Прежде, чем мы перейдем к примерам, рассмотрим три различных схемы, использующих @@ -2339,7 +2360,7 @@ STDIN и STDOUT запущенного процесса. Поддержка эт загрузки, и единственный экземпляр службы тут же начинает обслуживать все поступающие запросы. Такая схема подходит для часто используемых системных служб~--- очевидно, что такие - службы лучше запускать как можно раньше, и по вомзожности + службы лучше запускать как можно раньше, и по возможности параллельно. В качестве примера можно привести D-Bus и Syslog. \item \textbf{Сокет-активация для одиночных служб:} сокеты создаются на ранних стадиях загрузки, и единственный экземпляр службы @@ -2456,7 +2477,7 @@ ExecStart=-/usr/sbin/sshd -i StandardInput=socket \end{Verbatim} -Большинство представленных здесь опции, как и раньше, понятны интуитивно. Особое +Большинство представленных здесь опций, как всегда, понятны интуитивно. Особое внимание стоит обратить лишь на +StandardInput=socket+, которая, собственно, и включает для данной службы режим совместимости с inetd-активацией. Опция +StandardInput=+ позволяет указать, куда будет подключен поток STDIN процесса @@ -2464,14 +2485,14 @@ StandardInput=socket \href{http://0pointer.de/public/systemd-man/systemd.exec.html}{на странице руководства}). Задав для нее значение +socket+, мы обеспечиваем подключение этого потока к сокету соединения, как того и требует механизм inetd-активации. -Заметим, что явно указывать опцию +StandardInput=+ в данном случае +Заметим, что явно указывать опцию +StandardOutput=+ в данном случае необязательно~--- она автоматически устанавливается в то же значение, что и +StandardInput+, если явно не~указано что-то другое. Кроме того, можно отметить наличие <<+-+>> перед именем бинарного файла sshd. Таким образом мы указываем systemd игнорировать код выхода процесса sshd. По умолчанию, systemd сохраняет коды выхода для всех экземпляров службы, завершившихся с ошибкой (сбросить эту информацию можно командой +systemctl reset-failed+). SSH -периодически откалывает подобные номера, и мы разрешаем systemd +довольно часто завершается с ненулевым кодом выхода, и мы разрешаем systemd не~регистрировать подобные <<ошибки>>. Служба +sshd@.service+ предназначена для работы в виде независимых экземпляров @@ -2508,7 +2529,7 @@ sshd.socket - SSH Socket for Per-Connection Servers Итак, наш сокет уже прослушивается, но входящих соединений на него пока не~поступало (счетчик +Accepted:+ показывает количество принятых соединений -с момента запуска сокета, счетчик +Connected:+~--- количество активных +с момента создания сокета, счетчик +Connected:+~--- количество активных соединений на текущий момент). Подключимся к нашему серверу с двух разных хостов, и посмотрим на список служб: @@ -2529,46 +2550,46 @@ sshd.socket loaded active listening SSH So # systemctl kill sshd@172.31.0.52:22-172.31.0.4:47779.service \end{Verbatim} -Вот и все, что вам нужно знать о портировании inetd-служб в systemd и дальнейшем -их использовании. +Вот, пожалуй, и все, что вам нужно знать о портировании inetd-служб в systemd и +дальнейшем их использовании. -Приметительно к SSH, в большинстве случаев схема с inetd-активацией позволяет +Применительно к SSH, в большинстве случаев схема с inetd-активацией позволяет сэкономить системные ресурсы и поэтому оказывается более эффективным решением, чем использование обычного service-файла sshd, обеспечивающего запуск одиночной службы без использования сокет-активации (поставляется в составе пакета и может быть включен при необходимости). В ближайшее время я собираюсь направить -соответсвующий запрос относительно нашего пакета SSH в багтрекер Fedora. +соответствующий запрос относительно нашего пакета SSH в багтрекер Fedora. В завершение нашей дискуссии, сравним возможности xinetd и systemd, и выясним, может ли systemd полностью заменить xinetd, или нет. Вкратце: systemd поддерживает далеко не~все возможности xinetd и поэтому отнюдь не~является его -полноценной заменой на все случаи жизни. В частности, если вы загляните -в \href{http://linux.die.net/man/5/xinetd.conf}{список параметров конфигурации} +полноценной заменой на все случаи жизни. В частности, если вы загляните в +\href{http://linux.die.net/man/5/xinetd.conf}{список параметров конфигурации} xinetd, вы заметите, что далеко не~все эти опции доступны в systemd. Например, в -systemd нет и не~будет встроенных служб +echo+, +time+, +daytime+, +discard+ и -т.д. Кроме того, systemd не~поддерживает TCPMUX и RPC. Впрочем, большинство этих -опций уже не~актуальны в наше время. Подавляющее большинство inetd-служб -не~используют эти опции (в частности, все имеющиеся в Fedora xinetd-службы -принадлежат к этому большинству, и не~используют перечисленные опции). Стоит -отметить, что xinetd поддерживает некоторые интересные возможности, -отсутствующие в systemd, например, списки контроля доступа для IP-адресов (IP -ACL). Однако, большинство администраторов, скорее всего, согласятся, что -настройка барндмауэра является более эффективным решением подобных задач, -а для ценителей устаревших технологий systemd предлагает поддержку tcpwrap. -С другой стороны, systemd тоже предоставляет ряд возможностей, отсутствующих в -xinetd, в частности, индивидуальный контроль над каждым экземпляром службы (см. -выше), и куда более полный +systemd нет и никогда не~будет встроенных служб +echo+, +time+, +daytime+, ++discard+ и т.д. Кроме того, systemd не~поддерживает TCPMUX и RPC. Впрочем, +большинство этих опций уже не~актуальны в наше время. Подавляющее большинство +inetd-служб не~используют эти опции (в частности, ни~одна из имеющихся в Fedora +xinetd-служб не~требует поддержки перечисленных опций). Стоит отметить, что +xinetd имеет некоторые интересные возможности, отсутствующие в systemd, +например, списки контроля доступа для IP-адресов (IP ACL). Однако, большинство +администраторов, скорее всего, согласятся, что настройка барндмауэра является +более эффективным решением подобных задач, а для ценителей устаревших технологий +systemd предлагает поддержку tcpwrap. С другой стороны, systemd тоже +предоставляет ряд возможностей, отсутствующих в xinetd, в частности, +индивидуальный контроль над каждым экземпляром службы (см. выше), и куда более +полный \href{http://0pointer.de/public/systemd-man/systemd.exec.html}{список настроек} для контроля окружения, в котором запускаются экземпляры. Я надеюсь, что возможностей systemd должно быть достаточно для решения большинства задач, а в тех редких случаях, когда вам потребуются специфические опции xinetd~--- ничто не~мешает вам запустить его в дополнение к systemd. Таким образом, уже сейчас в большинстве случаев xinetd можно выкинуть из числа обязательных системных -компонентов. В некотором смысле, systemd возвращает функциональность -классического юниксового inetd и вновь возвращает ей ключевую роль в -Linux-системах. +компонентов. Можно сказать, что systemd не~просто возвращает функциональность +классического юниксового inetd, но еще и восстанавливает ее ключевую +роль в Linux-системах. -Теперь, вооруженные этими занниями, вы можете портировать свои службы с inetd на +Теперь, вооруженные этими знаниями, вы можете портировать свои службы с inetd на systemd. Но, конечно, будет лучше, если этим займутся разработчики из апстрима приложения, или сопровождающие вашего дистрибутива.