Catatonit: различия между версиями
(Новая страница: «'''Catatonit представляет собой программу /sbin/init для использования в контейнерах. Он позволяе…») |
Нет описания правки |
||
(не показаны 2 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
'''Catatonit представляет собой программу /sbin/init для использования в контейнерах. | '''Catatonit представляет собой программу /sbin/init для использования в контейнерах.''' | ||
Он позволяет решать проблему PID 1 zombie reaping problem. | |||
Он позволяет решать проблему PID 1 zombie reaping problem. | |||
По сути, catatonit - это переписанный initrs (Rust) на C, который в свою очередь является переосмыслением других контейнерных init-систем, таких как tini и dumb-init. | По сути, catatonit - это переписанный initrs (Rust) на C, который в свою очередь является переосмыслением других контейнерных init-систем, таких как tini и dumb-init. | ||
Строка 6: | Строка 7: | ||
__TOC__ | __TOC__ | ||
== Суть проблемы PID 1 zombie reaping problem: == | == Суть проблемы PID 1 zombie reaping problem [https://habr.com/ru/company/hexlet/blog/248519/ [1<nowiki>]</nowiki>] == | ||
Все процессы в Unix представлены в виде дерева. Каждый процесс порождает дочерние процессы, и каждый процесс имеет родителя кроме самого верхнего (или корневого). | Все процессы в Unix представлены в виде дерева. Каждый процесс порождает дочерние процессы, и каждый процесс имеет родителя кроме самого верхнего (или корневого). | ||
Корневой процесс это init. Он запускается ядром при загрузке системы. init отвечает за старт остальных частей системы, например, демона SSH, демона | Корневой процесс это init. Он запускается ядром при загрузке системы. init отвечает за старт остальных частей системы, например, демона SSH, демона docker, запуск Apache/Nginx, запуск графического интерфейса и так далее. Каждый из них в свою очередь запускает свои дочерние процессы. | ||
Unix сделан таким образом, что родительский процесс ждет завершения дочернего чтобы получить код завершения (exit status). Зомби процесс существует до тех пор, пока родительский процесс не закончит это действие, используя семейство системных вызовов waitpid(). Т.е. зомби-процессы - это процессы, которые завершились, но их родительские процессы еще ждут их завершения. | Unix сделан таким образом, что родительский процесс ждет завершения дочернего чтобы получить код завершения (exit status). Зомби процесс существует до тех пор, пока родительский процесс не закончит это действие, используя семейство системных вызовов waitpid(). Т.е. зомби-процессы - это процессы, которые завершились, но их родительские процессы еще ждут их завершения. | ||
Но есть особый случай. | Но есть особый случай. Когда родительский процесс завершился, намеренно или из-за действия пользователя. Тогда у дочерних процессов больше нет родителя, поэтому они становятся “сиротами” (это технический термин). | ||
Тут в игру вступает процесс init. У процесса init – PID 1 – есть специальная задача: “усыновлять” осиротевшие процессы (это снова настоящий технический термин). Это означает, что init становится родителем таких процессов, не смотря на то, что они в реальности не были порождены init’ом. | Тут в игру вступает процесс init. У процесса init – PID 1 – есть специальная задача: “усыновлять” осиротевшие процессы (это снова настоящий технический термин). Это означает, что init становится родителем таких процессов, не смотря на то, что они в реальности не были порождены init’ом. | ||
Строка 21: | Строка 22: | ||
Каждый раз когда процесс, имеющий детей, завершается, он ожидает, что init подчистит все за ним. Это описано детально в двух очень хороших книгах: Operating System Concepts и Advanced Programming in the UNIX Environment. | Каждый раз когда процесс, имеющий детей, завершается, он ожидает, что init подчистит все за ним. Это описано детально в двух очень хороших книгах: Operating System Concepts и Advanced Programming in the UNIX Environment. | ||
== Особенности docker | == Особенности docker == | ||
Ядро ОС завершает весь контейнер со всеми процессами внутри. Эти процессы завершаются с помощью SIGKILL. Поэтому нет способа завершить эти процессы чисто. Допустим, ваше приложение пишет что-то в файл. Файл может быть поврежден если приложение завершилось таким образом во время записи. Нечистое завершение процессов это плохо. Это почти как выдернуть шнур питания у сервера. | Ядро ОС завершает весь контейнер со всеми процессами внутри. Эти процессы завершаются с помощью SIGKILL. Поэтому нет способа завершить эти процессы чисто. Допустим, ваше приложение пишет что-то в файл. Файл может быть поврежден если приложение завершилось таким образом во время записи. Нечистое завершение процессов это плохо. Это почти как выдернуть шнур питания у сервера. | ||
Но почему нас должно волновать, что процесс init завершается сигналом SIGTERM? Потому что docker stop посылает SIGTERM процессу init. “docker stop” должен остановить контейнер правильно, чтобы его можно было потом запустить с помощью “docker start”. [ | Но почему нас должно волновать, что процесс init завершается сигналом SIGTERM? Потому что docker stop посылает SIGTERM процессу init. “docker stop” должен остановить контейнер правильно, чтобы его можно было потом запустить с помощью “docker start”. [https://habr.com/ru/company/hexlet/blog/248519/ [1<nowiki>]</nowiki>] | ||
== Как работает catatonit | == Как работает catatonit == | ||
'''Если catatonit запущен с PID = 1, то Catatonit становится корневым процессом.''' | '''Если catatonit запущен с PID = 1, то Catatonit становится корневым процессом.''' | ||
Строка 47: | Строка 46: | ||
% sudo make install | % sudo make install | ||
Лицензия | == Лицензия == | ||
GNU General Public License 3 и выше. | |||
[[Категория:Catatonite]] | [[Категория:Catatonite]] |
Текущая версия от 17:10, 25 сентября 2020
Catatonit представляет собой программу /sbin/init для использования в контейнерах.
Он позволяет решать проблему PID 1 zombie reaping problem.
По сути, catatonit - это переписанный initrs (Rust) на C, который в свою очередь является переосмыслением других контейнерных init-систем, таких как tini и dumb-init.
Суть проблемы PID 1 zombie reaping problem [1]
Все процессы в Unix представлены в виде дерева. Каждый процесс порождает дочерние процессы, и каждый процесс имеет родителя кроме самого верхнего (или корневого).
Корневой процесс это init. Он запускается ядром при загрузке системы. init отвечает за старт остальных частей системы, например, демона SSH, демона docker, запуск Apache/Nginx, запуск графического интерфейса и так далее. Каждый из них в свою очередь запускает свои дочерние процессы.
Unix сделан таким образом, что родительский процесс ждет завершения дочернего чтобы получить код завершения (exit status). Зомби процесс существует до тех пор, пока родительский процесс не закончит это действие, используя семейство системных вызовов waitpid(). Т.е. зомби-процессы - это процессы, которые завершились, но их родительские процессы еще ждут их завершения.
Но есть особый случай. Когда родительский процесс завершился, намеренно или из-за действия пользователя. Тогда у дочерних процессов больше нет родителя, поэтому они становятся “сиротами” (это технический термин).
Тут в игру вступает процесс init. У процесса init – PID 1 – есть специальная задача: “усыновлять” осиротевшие процессы (это снова настоящий технический термин). Это означает, что init становится родителем таких процессов, не смотря на то, что они в реальности не были порождены init’ом.
Ядро ОС ожидает от init специального поведения: ядро считает, что init должен обрабатывать (собирать, “reap”) усыновленные процессы тоже.
Каждый раз когда процесс, имеющий детей, завершается, он ожидает, что init подчистит все за ним. Это описано детально в двух очень хороших книгах: Operating System Concepts и Advanced Programming in the UNIX Environment.
Особенности docker
Ядро ОС завершает весь контейнер со всеми процессами внутри. Эти процессы завершаются с помощью SIGKILL. Поэтому нет способа завершить эти процессы чисто. Допустим, ваше приложение пишет что-то в файл. Файл может быть поврежден если приложение завершилось таким образом во время записи. Нечистое завершение процессов это плохо. Это почти как выдернуть шнур питания у сервера.
Но почему нас должно волновать, что процесс init завершается сигналом SIGTERM? Потому что docker stop посылает SIGTERM процессу init. “docker stop” должен остановить контейнер правильно, чтобы его можно было потом запустить с помощью “docker start”. [1]
Как работает catatonit
Если catatonit запущен с PID = 1, то Catatonit становится корневым процессом.
И в случае, когда процесс становится зомби или сиротой, Catatonit знает как правильное его завершить. Он пересылает (почти) все сигналы порожденному процессу, завершает контейнер, когда дочерние процессы завершены, и в противном случае очищает другие завершённые процессы (зомби).
В отличие от других контейнерных систем инициализации (таких как "tini" или "dumb-init"), которые используют sigwait(2), catatonit использует современные средства Linux (такие как signalfd(2)) и не имеет никаких дополнительных функций.
Использование Catatonit используется также как и docker-init-системы. Он принимает команды и список аргументов для этой команды. Если catatonit не является pid1, он попытается использовать поддержку sub-reaper в ядре. Если необходимо, чтобы сигналы пересылались всей группе процессов порожденного процесса, необходимо указывать -g (в противном случае сигналы просто пересылаются порожденному процессу).
Установка Catatonit использует autotools для сборки, поэтому собирается и устанавливается стандартным образом:
% ./autogen.sh % ./configure % make % sudo make install
Лицензия
GNU General Public License 3 и выше.