Version v8.3 (2011-12-15 03:23) [AUTO]
This commit is contained in:
126
s4a.tex
126
s4a.tex
@@ -2117,6 +2117,7 @@ systemd?
|
||||
вместо бинарника демона.
|
||||
|
||||
\section{Экземпляры служб}
|
||||
\label{sec:instances}
|
||||
|
||||
Большинство служб в Linux/Unix являются одиночными (singleton): в каждый момент
|
||||
времени на данном хосте работает только один экземпляр службы. В качестве
|
||||
@@ -2245,8 +2246,8 @@ systemd и заложен предварительный поиск файла
|
||||
результат. Но этим грешат практически все алгоритмы экранирования. В данном
|
||||
случае, были использован механизм экранирования из udev, с одним изменением. В
|
||||
конце концов, нам нужно было выбрать что-то. Если вы собираетесь комментировать
|
||||
наш алгоритм экранирования~--- пожалуйста, также укажите, где вы живете, чтобы я
|
||||
мог приехать к вам и раскрасить ваш велосипедный гараж в синий с желтыми
|
||||
наш алгоритм экранирования~--- пожалуйста, оставьте свой адрес, чтобы я
|
||||
мог приехать к вам и раскрасить ваш сарай для велосипедов в синий с желтыми
|
||||
полосами. Спасибо!}. Например, чтобы обратиться
|
||||
последовательному USB-порту по его адресу на шине, нам нужно использовать имя
|
||||
наподобие +serial/by-path/pci-0000:00:1d.0-usb-0:1.4:1.1-port0+. Экранированная
|
||||
@@ -2286,7 +2287,7 @@ serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0.
|
||||
\section{Службы с активацией в стиле inetd}
|
||||
|
||||
В одной из предыдущих глав (гл.~\ref{sec:convert}) я рассказывал, как можно
|
||||
преобразовать SysV init-скрипт в юнит-файл systemd. В этой главе мы рассмотрим
|
||||
преобразовать SysV init-скрипт в юнит-файл systemd. В этой главе мы рассмотрим,
|
||||
как провести аналогичное преобразование для служб inetd.
|
||||
|
||||
Начнем с небольшого экскурса в историю вопроса. По давно устоявшейся традиции,
|
||||
@@ -2357,7 +2358,126 @@ STDIN и STDOUT запущенного процесса. Поддержка эт
|
||||
Пример: SSH.
|
||||
\end{enumerate}
|
||||
|
||||
Описанные схемы отнюдь не~эквивалентны с точки зрения производительности. Первая
|
||||
и вторая схема, после завершения запуска службы, обеспечивают точно такую же
|
||||
производительность, как и в случае с независимой (stand-alone) службой (т.е.
|
||||
службой, запущенной без использования суперсервера и сокет-активации), так как
|
||||
слушающий сокет передается непосредственно процессу службы, и дальнейшая
|
||||
обработка входящих соединений происходит точно так же, как и в независимой
|
||||
службе. В то же время, производительность третьей из предложенных схем порою
|
||||
оставляет желать лучшего: каждое входящее соединение порождает еще один процесс
|
||||
службы, что, при большом количестве соединений, может привести к значительному
|
||||
потреблению системных ресурсов. Впрочем, эта схема имеет и свои достоинства.
|
||||
В частности, обеспечивается эффективная изоляция обработки клиентских запросов
|
||||
и, кроме того, выбор такой схемы активации значительно упрощает процесс
|
||||
разработки службы.
|
||||
|
||||
В systemd наибольшее внимание уделяется первой из этих схем, однако остальные
|
||||
две тоже прекрасно поддерживаются. В свое время, я
|
||||
\href{http://0pointer.de/blog/projects/socket-activation2.html}{рассказывал},
|
||||
какие изменения в коде службы нужно сделать для обеспечения работы по второй
|
||||
схеме, на примере сервера CUPS. Что же касается inetd, то он предназначен прежде
|
||||
всего для работы по третьей схеме, хотя поддерживает и вторую (но не~первую).
|
||||
Именно из-за специфики этой схемы inetd получил репутации <<медленного>> (что,
|
||||
на самом деле, немного несправедливо).
|
||||
|
||||
Итак, изучив теоретическую сторону вопроса, перейдем к практике и рассмотрим,
|
||||
как inetd-служба может быть интегрирована с механизмами сокет-активации systemd.
|
||||
В качестве примера возьмем SSH, известную и широко распространенную службу. На
|
||||
большинстве систем, где она используется, частота обращений к ней не~превышает
|
||||
одного раза в час (как правило, она \emph{значительно} меньше этой величины).
|
||||
SSH уже очень давно поддерживает сокет-активацию в стиле inetd, согласно третьей
|
||||
схеме. Так как необходимость в этой службе возникает сравнительно редко, и
|
||||
число одновременно работающих процессов обычно невелико, она хорошо подходит для
|
||||
использования по этой схеме. Перерасход системных ресурсов должен быть
|
||||
незначителен: большую часть времени такая служба фактически не~выполняется и
|
||||
не~тратит ресурсы. Когда кто-либо начинает сеанс удаленной работы, она
|
||||
запускается, и останавливается немедленно по завершению сеанса, освобождая
|
||||
ресурсы. Что ж, посмотрим, как в systemd можно воспользоваться режимом
|
||||
совместимости с inetd и обеспечить сокет-активацию SSH.
|
||||
|
||||
Так выглядит строка с конфигурацией службы SSH для классического inetd:
|
||||
\begin{Verbatim}
|
||||
ssh stream tcp nowait root /usr/sbin/sshd sshd -i
|
||||
\end{Verbatim}
|
||||
|
||||
Аналогичный фрагмент конфигурации для xinetd:
|
||||
\begin{Verbatim}
|
||||
service ssh {
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = root
|
||||
server = /usr/sbin/sshd
|
||||
server_args = -i
|
||||
}
|
||||
\end{Verbatim}
|
||||
|
||||
Б\'{о}льшая часть опций интуитивно понятна, кроме того, нетрудно заметить, что оба
|
||||
этих текста повествуют об одном и том же. Однако, некоторые моменты не~вполне
|
||||
очевидны. Например, номер прослушиваемого порта (22) не~указывается в явном
|
||||
виде. Он определяется путем поиска имени службы в базе данных +/etc/services+.
|
||||
Подобный подход был некогда весьма популярен в Unix, но сейчас он уже постепенно
|
||||
выходит из моды, и поэтому в современных версиях xinetd поддерживается возможность
|
||||
явного указания номера порта. Одна из наиболее интересных настроек названа
|
||||
не~очень очевидно~--- +nowait+ (+wait=no+). Она определяет, будет ли служба
|
||||
работать по второй (+wait+) или третьей (+nowait+) схеме. И наконец, ключ +-i+
|
||||
активирует inetd-режим в SSH-сервере (без этого ключа он работает в независимом
|
||||
режиме).
|
||||
|
||||
На языке systemd эти фрагменты конфигурации превращаются в два файла. Первый из
|
||||
них, +sshd.socket+, содержит информацию о прослушиваемом сокете:
|
||||
\begin{Verbatim}
|
||||
[Unit]
|
||||
Description=SSH Socket for Per-Connection Servers
|
||||
|
||||
[Socket]
|
||||
ListenStream=22
|
||||
Accept=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
\end{Verbatim}
|
||||
|
||||
Смысл большинства опций вполне очевиден. Сделаю лишь пару замечаний.
|
||||
+Accept=yes+ соответствует режиму +nowait+. Надеюсь, предложенное мною название
|
||||
более точно отражает смысл опции~--- в режиме +nowait+ суперсвервер сам вызывает
|
||||
+accept()+ для слушающего сокета, в то время как в режиме +wait+ эта работа
|
||||
ложится на процесс службы. Опция +WantedBy=sockets.target+ обеспечивает
|
||||
активацию данного юнита в нужный момент при загрузке системы.
|
||||
|
||||
Второй из этих файлов~--- +sshd@.service+:
|
||||
\begin{Verbatim}
|
||||
[Unit]
|
||||
Description=SSH Per-Connection Server
|
||||
|
||||
[Service]
|
||||
ExecStart=-/usr/sbin/sshd -i
|
||||
StandardInput=socket
|
||||
\end{Verbatim}
|
||||
|
||||
Большинство представленных здесь опции, как и раньше, понятны интуитивно. Особое
|
||||
внимание стоит обратить лишь на +StandardInput=socket+, которая, собственно, и
|
||||
включает для данной службы режим совместимости с inetd-активацией. Опция
|
||||
+StandardInput=+ позволяет указать, куда будет подключен поток STDIN процесса
|
||||
данной службы (подробности см.
|
||||
\href{http://0pointer.de/public/systemd-man/systemd.exec.html}{на странице
|
||||
руководства}). Задав для нее значение +socket+, мы обеспечиваем подключение
|
||||
этого потока к сокету соединения, как того и требует механизм inetd-активации.
|
||||
Заметим, что явно указывать опцию +StandardInput=+ в данном случае
|
||||
необязательно~--- она автоматически устанавливается в то же значение, что и
|
||||
+StandardInput+, если явно не~указано что-то другое. Кроме того, можно отметить
|
||||
наличие <<+-+>> перед именем бинарного файла sshd. Таким образом мы указываем
|
||||
systemd игнорировать код выхода процесса sshd. По умолчанию, systemd сохраняет
|
||||
коды выхода для всех экземпляров службы, завершившихся с ошибкой (сбросить эту
|
||||
информацию можно командой +systemctl reset-failed+). SSH
|
||||
периодически откалывает подобные номера, и мы разрешаем systemd
|
||||
не~регистрировать подобные <<ошибки>>.
|
||||
|
||||
Служба +sshd@.service+ предназначена для работы в виде независимых экземпляров
|
||||
(такие службы мы рассматривали в предыдущей главе~\ref{sec:instances}). Для
|
||||
каждого входящего соединения systemd будет создавать свой экземпляр этой службы,
|
||||
и идентификатор экземпляра формируется на основе реквизитов соединения.
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user