Skip to content

Слаконар: Супервизоры. Системы инициализации системы. [1.04.2016]

Serge Braun edited this page Feb 25, 2017 · 3 revisions

Так вот, тема супервизоров прямо какая-то чужая для большинства, причем нет понимания, о чем вообще идет речь, поэтому мы уже давно планировали что-то этакое замутить, но все кого мы приглашаем, отмазывались словами “а чо я настроил и забыл” ) Короче сложно найти экспертов. Саша что-то там заресерчил и раскроет вам все тайны мироздания.

nox73: Сегодня затронем интересную тему. Кирилл ее озвучил, как рассказ, про супервизоры, но мне бы хотелось взять чуть шире. В основе таких высокоуровневых штук всегда кроются мелкие детали, принципы по которым устроены такие системы, и они зачастую интереснее и приносят больше пользы для развития.

Вначале мы затронем тему что такое процесс вообще в ОС и чем он представлен. В основном наша беседа думаю будет нацелена на junior, но если будут учавствовать и старички - будет здорово. Примерно расчитываем на час с небольшим я думаю, как пойдет. Во второй части поговорим непосредственно про супервижн, зачем он нужен, какие задачи решает

(все что я буду говорить относится больше к linux, но я буду рассказывать больше о принципах, поэтому +- применимо к остальным и не linux like ОС)

Итак что же представляет из себя процесс для ОС? Если упрощенно это область в памяти со списком команд, процессор при выполнении команды переставляет указатель команды на след ячейку памяти, так он поочереди и исполняет команды

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

после того как процесс запущен (далее поговорим как это происходит) и процессор начал выполнять команды, наш процесс может что-то вычислять, класть в регистры значения, выполнять над ними дествия, записывать считывать все это в\из памяти

посмотрим теперь как процесс взаимодействует с внешним миром на низком уровне

единственным средством взаимодействия с внешним миром для процесса и посредником является ОС

сам процесс запущен в тн user mode, тоесть ему не доступны все команды процессора, и чтобы выполнить некоторые функции (чтение из файла, сокета, посылка сообщения и многое другое) он должен попросить об этом ОС сделать это

в этом ему помогают syscall вызовы :robot_face:

чтобы позвать ОС на низком уровне процесс генерирует прерывание и уже процессор находит в специальной таблице прерываний созданной ОС, то, которое отвечает за обработку системны вызовов (syscall)

конечно перед тем как позвать ОС процесс должен разложить правильно параметры вызова по регистрам и памяти, но это детали

итак, взаимодействие процесса с внешним миром происходит через syscall и посредник - ОС

Давайте теперь разберем вопрос создания нового процесса

первый syscall который нам поможет в этом называет exec

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

системный вызов exec заменяет образ текущего процесса (образ в памяти, т.е. те самые команды) на образ нового процесса

тоесть если у вас есть запущенные процесс, то вы можете заменить его на другой

второй syscall уникальный )) про него есть загадка, и бывает что ее задают на собеседовании ) это функция, которая возвращает результат дважды и оба результата разные

fork - создает полную копию процесса

выглядит это обычно так:

if(fork() == 0) {
//child process
} else {
//parent process
}

тоесть возвращает она результат дважды - один раз в процесс потомок и результатом является 0, второй раз в процесс родитель и результатом является pid созданного процесса

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

механизм copy on write

новый процесс наследует от родительского все

открытые файлы например

опять же отступление, есть еще один syscall clone - по сути команда fork вызывает его, просто с параметрами. Clone может создать процесс и не копировать его образ, а использовать тот же

если кто-то догадался, то таким образом можно реализовывать потоки в linux

Итак, последовательным вызовом fork + exec можем создать новый процесс и запустить его в ОС

Посмотрим теперь что же нашему новому процессу досталось от родителя

первое это конечно дескрипторы

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

псевдокод:

fd = open("/tmp/file")

open - syscall, который говорит ОС, что процесс хочет открыть файл для операций над ним, в ответ ОС нам просто говорит "6"

теперь чтобы записать в файл мы просто говорим

write(6, "some text")

тоже самое происходит с разными ресурсами, доступ к которым мы можем получить через ОС

файлы, сокеты, таймеры, мультиплексоры сокетов, мютексы и пр.

trooper

при создании процессу ставится в соответсвие 3 дескриптора - 0, 1, 2

sudo lsof -p 6239

выполнив эту команду с pid любого процесса вы увидите все дескрипторы, которые использует процесс, среди них будет 3

0 - дескриптор ассоциированный с потоком ввода stdin

1 - поток вывод stdout

2 - вывод ошибок stderr

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

есть у кого вопросы?

jllfsh Пока вроде ясно все

friday_next да, я внимательно слушаю. ой, то есть читаю

эти азы в свое время дали большой буст в развитии меня как разработчика

sashashakun Довольно последовательный рассказ:+1:

и дали много понимания в том что вообще происходит в ОС

ок, идем дальше

поговорим про другие способы взаимодействиия процессов друг с другом

я уже упоминал сокеты

ridzhi Вопрос откуда вы черпали инфу по тому что рассказываете ? В ОС Таненбаума я смогу прочитать об этом ?

сокеты это довольно общее понятие, если просто - это что-то во что можно писать, а с другой стороны читать

kirill.mokevnin робачевский вестимо, у нас в андеве большая библиотека )

oneumyvakin в любой книже по программированию это написано, читайте книжки.

да, Таненбаум, Столлингс

ridzhi Спасибо

думаю да, про это можно прочитать почти в любой книжке по ОС

пример сокета Unix domain socket - это именованный сокет и он представлен как файл на файловой системе, вы можете открыть его в одном процессе для чтения, в другом для записи и таким образом общаться между процессами

melekes а я могу его в nano открыть к примеру?

пайпы - в переводе означает труба, тоесть вы так же можете создать пайп в одном процессе, ОС создать дескриптор ассоциированный с этим пайпом, потом создать новый процесс через форк и общаться через эти дескрипторы

в nano вы его не откроете, он только представлен как файл на файловой системе, но по факту таковым не является, это просто имя для того чтобы другие процессы могли его найти

кто работает с докером, скорее всего видели, докер по дефолту создает сокет /var/run/docker.sock

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

сигналы - еще один способ взаимодействия между процессами

думаю каждый сталкивался с командой kill

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

например, когда вы нажимаете Ctrl+C в командной строке, терминал перехватывает это и посылает запущенному процессу сигнал SIGINT

ОС при получении сигнала для процесса, останавливает процесс и запускает обработчик для этого сигнала в процессе

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

#!/bin/bash

trap "echo Booh!" SIGINT SIGTERM
echo "pid is $$"

while :
do
    sleep 60
done

если вы запустите след bash скрипт, то вы не сможете остановить его нажатием Ctrl+C, сможете только "убить" его посылкой сигнала SIGKILL

an.kazakov то есть kill по сути "посылает" сигнал не процессу, а операционной системе - и та уже передает ее процессу? Так как один процесс не может связаться на прямую с другим. Так? 1

@an.kazakov: да, все верно, ОС является посредником для всего, все общение процесса с внешним миром происходит через этого посредника

народ, еще есть вопросы

?

след что мы рассмотрим - это демоны 4

демонизация это общий термин определяет процесс, который не взаимодействует с пользователем. По сути все наши веб сервера, БД, очереди, воркеры и пр. это демоны.

чертовы

если вы запустите какой-то процесс в терминале, то новый процесс (порожденный терминалом через системные вызовы fork + exec, как мы помним) отнаследует дескрипторы 0 1 2 от терминала (сделаем вид что это так), поэтому все что будет выводить процесс в stdout - будет выводить на экран

чтобы демонизироваться процессу нужно выполнить след действия:

  1. переоткрыть 0 - 2 дескрипторы
  2. выполнить setsid - при обрыве сессии в терминале всем процессам в группе посылается сигнал SIGHUP, поэтому нужно установить новый session id

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

nohup ping ya.ru

после закрытия терминала процесс так и останется висеть

теперь посмотрим на всякие веселости:

zombie процессы

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

но если родительский процесс умер или проигнорировал сигнал - в таблице процессов так и останется запись о дочернем процессе с информацией о нем

ресурсы памяти и CPU такие процессы конечно же не потребляют, это только лишь строчка в таблице процессов, но существует ограничение на размер этой таблицы и кол-ва процессов которые может запустить пользователь

kirill.mokevnin задача на дом, породить в баше зомби) 3

anatol_s А как убить потом зомби?

sheregeda kill -9 pid

mrtheyann @kirill.mokevnin: отличный таcк кстати для практики (edited)

внимание! не выполнять этот код в терминале:

:(){ :|:& };:

хотя можете попробовать, ребутнетесь и все пройдет, этот код выполняет fork бомбу в bash - состояние процесса, когда он постоянно выполняет форк, где дочерний процесс вновь выполняет форк рекурсивно 1

kirill.mokevnin смайлы выглядят как отряд орков 1

в ОС есть так называемый init процесс - это процесс запускаемый первым, он является корнем для всех остальных. Интересно что только init процесс может обрабатывать необрабатываемые сигналы, напрмер SIGKILL

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

densom я думал знаю bash

mrtheyann а если послать SIGKILL в init процесс?

попробуй )))

kirill.mokevnin пид у инита всегда 1

можно смело слать)

так, я думал пойдет быстрее, постараюсь далше быстрее, так что пристегнитесь )

итого мы "немного" поговорили о том как это все там работает "под капотом"

sashasava

как это поможет нам?

чтобы наше приложение работало на сервере его нужно как-то запустить

варианты:

при деплое вы скриптом запускаете с nohup запускаете ручками кто-то за вас запускает ваше приложение

зачем вам нужна штука, которая будет следить за вашим приложение когда вас нет раядом?

приложения падают (ошибки программирования, сервера падают, oom killer)

oom killer веселый друг, который приходит, когда у ОС заканчивается память, он выбирает жертву и убивает ее принудительно

плюс ко всему современные приложения должны и пишутся с таким расчетом, чтобы падение части системы не повлияло на ее работоспособность

более того современные средства уже предлагают перевозить приложения с сервера на сервер

почему не while true ? 2

можно написать простой скрипт в котором в бесконечном цикле запускается приложение в случае падения

проблема в том что если ваше приложение падает при запуске - оно будет перезапускаться вечно, кушать ресуры, хуже если оно сделает форк, тогда ваш while true превратиться в форк бомбу 1

для этого в системах супервизоров есть лимиты, скажем вы можете настроить так что если ваше приложение упало 5 раз за минуту, то все, не пробовать больше оживить этот труп

как же супервизору следить за вашим приложением, живо оно или нет?

про одно мы уже поговорили - сигнал, при смерти потомка родитель получает сигнал

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

pid file

второй способ

супервизор может расчитывать на то, что ваш демон запишет при запуске свой PID в файл и так вы сможете проверять, запущен ли процесс

теоретически тоже не на 100% надежно, ваш процесс может умереть а его PID получить другой процесс (это ОЧЕНЬ маловероятно, но может быть) но этот метод требует от процесса записи пид файла, что накладывает ограничения

супервизор может отслеживать с помощью ОС системные вызовы fork в процессе, так он может всегда знать актуальный PID процесса

это третий способ следить за процессом

и последний - как-то промаркировать процесс так, чтобы сам процесс уже никак не смог избавиться от этот маркировки, например запустить процесс в cgroup - механизм предоставляемый ОС (edited)

последними двумя способами пользуются upstart и systemd соответсвенно

что еще делают супервизоры кроме перезапуска приложения

логирование - в целом задача не самого процесса, она зависит от окружения в котором процесс запущен

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

поэтому часто в функцию супервизоров (или набора инструментов постовляемых с ними) так же входит сбор логов их stdout stderr процесса

конфигурация приложения

еще одна функция

http://12factor.net/ - тут очень подробно об этом написано, почему приложение должно получать все свои внешние зависимости через конфигурацию при запуске

есть очень много инструментов для супервижена

Runit Upstart Systemd

вот три из них

systemd - с 15 версии убунты входит в стандартную поставку

у меня впринципе почти все, дальше лучше в интерактиве пообсуждать существующие решения

greynix а какие ещё супервизоры кроме systemd бывают ?

connacte а у каждого супервизора есть лимиты ? или это частый случай ?

greynix лимиты можно настроить

@connacte: вообще зависит от реализации, но это очень частый кейс, так что большинство да их реализует

jllfsh Что скажете о systemd? Спрашиваю потому что в интернете очень неоднозначная реакция. Кто-то говорил что за ним будущее, а кто-то что это не linux way и все такое

sheregeda расскажи что-нибудь про supervisor, использую его для демонизации gunicorn. он норм вообще? стоит его использовать? чем он плох, хорош? (edited)

sse4 https://hexlet-ru.slack.com/archives/general/p1459526088005360 launchd Rodion Don greynix а какие ещё супервизоры кроме systemd бывают ? Today at 6:54 PM

freepad т.е. супервизор чтобы наше приложение не падало из-за

:(){ :|:& };:

да? (edited)

@greynix: runit, upstart, god, supervisor

@freepad: нет, супервизор нас от этого не спасет, про форк бомбу было в качестве отступления, от этого могут спасти лимиты для пользователся на кол-во запущенных процессов

greynix спасибо, почитаю подробнее

@jllfsh: по поводу systemd было много холивара при его включении в дистрибудтив убунты, и его все таки включили, подробнее, думаю можно прочитать в треде с обсуждением этого топика на форуме убунты, много + и - обсуждалось

connacte Большое спасибо! Очень хороший материал 👏

brownmoose3q Да, хорошо задвинул) thx (edited)

jllfsh Спасибо! В целом хочу сказать спасибо за рассказ. Наталкивает на определенные мысли. Буду изучать глубже. Если будет возможность ждем продолжения

freepad Пока слабо понял для чего нужен супервизор) Есть мысли, что он создан для более удобного управления процессами 1

densom

в этом ему помогают syscall вызовы :robot_face:

чтобы позвать ОС на низком уровне процесс генерирует прерывание и уже процессор находит в специальной таблице прерываний созданной ОС, то, которое отвечает за обработку системны вызовов (syscall)

я думал, что syscall это просто вызов функции ядра, а тут про прерывание говорится

зачем вам нужна штука, которая будет следить за вашим приложение когда вас нет раядом?

приложения падают

это сжатый пересказ 2ух часов )))) 2

sse4 а если приложение не падает а зависает это как-то обнаруживается?

я думал, что syscall это просто вызов функции ядра, а тут про прерывание говорится

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

an.kazakov что значит - зависают? Если у тебя бесконечный цикл в приложении, то это никто кроме создателя приложения и не отследит

@sse4: да, есть системы, которые могут "щупать" приложение

arthur

probe - например проверить слушает ли приложение на определенном порту (edited)

monit - как пример системы для мониторинга работоспособности приложение

sse4 @an.kazakov: deadlock например или бесконечный цикл

да, приложение моежет войти в состояние при котором оно работает, но функцию не выполняет

an.kazakov @ : да, пинговать его по порту можно, но это не факт что оно не зависло же

ага, как раз про это

да, вы можете придумать свой пробник

сделать http запрос

и отвалидировать ответ

densom Почему актуальных супервизоров на сегодняшний день три ? В чем отличия

kirill.mokevnin саша не раскрыл одну важную вещь связь супервизоров с системами инициализации системы

если позволите я вклинюсь и расскажу

да, есть такой косяк )

кто ж тебе запретит )

kirill.mokevnin главной идеей сегодняшнего слаконара было внедрить всем в мозг мысль “блин надо срочно под супервизор приложение завести” )

видно что пока не прошло

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

делается это системой инициализации, которая в дереве процессов как раз представлена процессом init 1

возможно будет сюрпризом что вы можете подменить эту подсистему

исторически в линукс системах была штука initv

ее уже давно нет вроде нигде

по сути когда вы смотрите в /etc/init.d это оно и есть (было)

это просто тупые sh скрипты которые свитчем выполняют разный код, типа start stop restart reload

misfit

kirill.mokevnin initv обладала множеством недостатков, но это была либо первая либо одна из первых систем инициализации

один из них это отсутствие порядка загрузки и реагирования на события

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

кто знает как это делалось в initv?

где тут бородатые админы?)

densom по алфавиту

kirill.mokevnin да тупо по тому как файлы отсортируются

versusbassz 05 имя скрипта

kirill.mokevnin поэтому вы могли видеть часто такое 01_nginx 02_apache

03_mysql

jllfsh Как это вообще работало?

akosorotov Отлично работало :simple_smile:

kirill.mokevnin Файл /etc/inittab

в котором описано что из какой папки на каком уровне стартовать

тут конечно еще надо рассказывать что есть уровни инициализации

и на разных уровнях грузятся разные вещи, вы с этим все сталкивались даже в винде

типа загрузить в сетевом режиме, в одиночном

в /etc все это представлено папками rc.d

с числами

копипаста:

В процессе загрузки, после инициализации ядра, ядро запускает /sbin/init как первый процесс пользовательского режима. init отвечает за дальнейшую загрузку системы. Для этого он запускает так называемые стартовые скрипты, которые выполняют проверку и монтирование файловых систем, запуск необходимых демонов, настройку ядра (в том числе загрузку модулей ядра согласно установленному оборудованию, настройку IP-адресов, таблиц маршрутизации и др.), запуск графической оболочки и другие действия.

В операционных системах Unix/Linux с помощью init можно изменить уровень инициализации. Уровень инициализации — степень загрузки операционной системы. Вот как происходит инициализация системы: процесс init запускается и анализирует файл /etc/inittab. Следует отметить, что приведенная здесь система инициализации работает на системах Linux и Unix System V и она несколько отличается от стиля инициализации системы в BSD-подобных системах.

По умолчанию, в системе использовано 7 уровней инициализации:

0 — остановка системы

1 — загрузка в однопользовательском режиме

2 — загрузка в многопользовательском режиме без поддержки сети

3 — загрузка в многопользовательском режиме с поддержкой сети

4 — не используется

5 — загрузка в многопользовательском режиме с поддержкой сети и графического входа в систему

6 — перезагрузка

sse4 уровни инциализации это run level?

kirill.mokevnin да

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

от которого зависят другие

либо он сам стартовал чертовски долго (а инит подумал что он уже встал на ноги)

и следующий процесс нагнулся

например может быть такая постановка “стартануть докер только если примонтировали сетевой диск"

это первая проблема

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

и тут на сцену врывается ubuntu, которая сделала upstart

godod Вот после всего прочитанного, только одно в голове: "Вот сиди и думай, как "много" ты знаешь" 😞 2

kirill.mokevnin ребята, надо прочитать просто одну книгу, я про нее тут год рассказываю)

и она у нас есть в map.hexlet.io

так вот upstart это в первую очередь система инициализации, а следовательно и супервизор

а не наоборот

она призвана заменить initv и заменяет его. Много лет назад апстарт появился в убунту, а потом появился везде в общем то, насколько я знаю redhat тоже его юзал до тех пор пока не придумали systemd

и так ключевые особенности

upstartd построен уже не на обычных sh скриптах, а это очень продвинутый событийный механизм

зависимости выстраиваются на основе событий через специальную шину

эмитить эвенты можно даже снаружи (чем часто пользуются)

все у кого линукс, откройте любой файл в /etc/init/...

почти наверняка это будет апстарт скрипт

что там у вас?

у кого новая убунта или redhat like система, там будет systemd

jllfsh У меня systemd

godod systemd

kirill.mokevnin вот можно определить кто тут устарел 😄

когда вы в своей системе делаете sudo service postgres start то это на самом деле идет команда системе инициализации, и все так или иначе работали с upstart/systemd

даже если не догадывались об этом

i_rastypain у меня нет /etc/init/ openSuSE 42.1

kirill.mokevnin насчет /etc/init.d есть один маленький ньюанс, для обратной совместимости туда складываются initv like скрипты, и вроде даже кем то используются

i_rastypain а, то есть опечатка)

kirill.mokevnin еще раз upstart/systemd хранят все в /etc/init

а в /etc/init.d хранились скрипты initv

и до сих пор эта папка есть у всех и наполняется

обратной совместимости для (edited)

если у вас только /etc/init.d то поздравляю, вы мамонт

jllfsh Т.е. shutdown -h now тоже что и init 0?

sheregeda ubuntu 15.10 )

kirill.mokevnin теоретически там может быть какая-то иная система инициализации, но я слабо в это верю

i_rastypain класс. последний релиз)

kirill.mokevnin и так, показываю скрипт докера

sse4 CentOS 7.1 /etc/init отсутсвует

OSX 10.11 тоже нет

misfit ребята я нубас

kirill.mokevnin osx это вообще своя история

misfit как фронтенщиком стать

kirill.mokevnin

~$ cat /etc/init/docker.conf
description "Docker daemon"

start on (filesystem and net-device-up IFACE!=lo)
stop on runlevel [!2345]

azmesmparser :smile:

kirill.mokevnin вот это начало init скрипта докера (upstart)

во первых как видим это не просто sh скрипт, это свой dsl для описания процесса

если вы посмотрите доку upstart, то ужаснетесь, там сотни страниц я думаю

тут мы как раз определяем по каким событиям стартовать и на каких складываться

vmatveev

kirill.mokevnin

~$ cat /etc/init/webserver.conf
description "Webserver"

start on filesystem and started docker
stop on runlevel [!2345]

а вот это апстарт скрипт хекслета

аппликейшейн хекслета внутри контейнера, значит стартовать мы должны после докера

и тут мы это определяем

как видите довольно тривиально

фирштейн? 5

misfit ребята как практиковать js

ничего толкового написать не могу

с чего начать

kirill.mokevnin вам во #frontend (edited)

misfit спасибо

sheregeda start on filesystem and started docker эта фраза говорит что запустить нужно после докера?

kirill.mokevnin на готовность файловой системы и после старта докера да

sheregeda start on filesystem - за что эта часть отвечает?

kirill.mokevnin файловая система тоже инициализируется, а не посылается нам господом богом изначально ) 3

тут начало это start on

остальное опционально

sheregeda т.е. вот так в строчку через and и перечисляется?

jougene а книга это которая Робачевского?

kirill.mokevnin я формат не помню полностью, не каждый день мы их настраиваем

в доке все подробно

respawn limit 3 30 вот так определяются лимиты рестарта

# change to match your deployment user
setuid vagrant
setgid vagrant

env HOME=/home/vagrant

так же можно установить переменные окружения, сказать от какого юзера старт и много всякого

кроме этого сам старт подразумевает наличие кучи колбеков типа pre-start post-start pre-stop post-stop и еще немного

вы можете делать всяко разно в зависимости от ситуации

следующий крайне важный аспект, саша про него сказал, но скзаал так как будто все знают о чем идет речь)

limit nofile 524288 1048576
limit nproc 524288 1048576

кто знает что это?

sheregeda лимиты вестимо)

mrtheyann ох, что-то strong language пошёл

bobrebyc норм

kirill.mokevnin лимиты да, но что это?)

sheregeda дескрипторы

kirill.mokevnin это cgroups

механизм в ядре, на котором основана контейнерная виртуализация, докер и все такое

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

современные системы инициализации активно используют cgroups

теперь апстарт скрипт из официальной д оки

description "Redis container"
author "Me"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
/usr/bin/docker start -a redis_server
end script

примерно так должны стартовать ваши контейнеры (если приложение находится внутри)

это полностью оформленный upstart скрипт, как видите ничего сложного, вся суть в том что между script

jllfsh Да, синтаксис довольно простой

kirill.mokevnin в общем на базовом уровне про upstart все, systemd это upstart на стероидах, очень похож, но гораздо более агрессивный, параллелизм, бинарные логи вот это все

теперь самое главное собственно, система инициализации контролирует процессы вашей операционки, и не имеет никакого смысла тащить в систему еще один супервизор если у вас уже есть upstart/systemd

они очень мощные/они из коробки/они точка унификации

любой демон на ваших серверах должен запускаться системой инициализации (не initv конечно, а systemd/upstart)

вы получаете 1) мощный контроль с тонкой настройкой 2) унификацию всей системы, все везде стартует и рестартует по одним и тем же принципам и на одном и том же механизме

очень часто когда разговор заходит про то что докер победил и на продакшене нужен докер, а ansible и компания не нужны, то это не так (edited)

ansible нужен чтобы как раз доставлять на сервера upstart/systemd скрипты (если вы конечно не используете какую-нибудь докер оркестрацию)

раньше было засилье разных прикладных супервизоров (они не именно супервизоры, не системы инициализации)

foreman runit supervisord launchd daemontools god еще десятка два

versusbassz Со такое оркестрация русским языком?

kirill.mokevnin в большинстве из них нет смысла, но бывают особые случаи ситуации

@versusbassz: дерижирование. Пойдет? 😄

sheregeda а upstart/systemd может все тоже самое что и, например, supervisor? например, указать куда логи класть? перезапуск приложения при падении?

gord Оркестрация??

kirill.mokevnin @sheregeda: елы палы, я как будто в пустоту сейчас рассказывал)

supervisord это как кукурузник рядом с боингом

sheregeda :grinning:

densom respawn - перезапуск видимо

kirill.mokevnin kirill.mokevnin я формат не помню полностью, не каждый день мы их настраиваем

в доке все подробно

respawn limit 3 30 вот так определяются лимиты рестарта

ваш супервизорд сам по себе не система инициализации, и притаскивая его в систему вы получаете два супервизора

за supervisord начинает следить upstart

зачем вам это надо?)

sheregeda вот я и хочу его выкинуть) надоело настраивать каждый раз, ставить из pip (edited)

kirill.mokevnin более того, многолетняя практика показывает что все прикладные супервизоры (понаписанные на python, ruby) текут

плюс они требуют наличия на сервере python/ruby и так далее

sheregeda о да, он течет)

kirill.mokevnin в общем за ними самими нужен контроль

мы раньше активно использовали runit

он очень тупой, но в итоге оказалось что слишком тупой и тоже не нужен

форк бомба на раз, и плюс нельзя демонизироваться под ним

да Саша ведь писал что такие супервизоры стартуют процесс наблюдатель и форкаются чтобы дочкой запустить ваш сервис?

тогда они гарантированно узнают о смерти процесса

sheregeda еще есть иногда потребность перезапустить процесс если было изменение кода. такое тоже умеет?

kirill.mokevnin теперь кажется я раскрыл тему, подводя итог, если у вас где-то стартует процесс на сервере и он не под upstart/systemd, вы что то делаете не так (почти наверняка)

вы это сами делаете

sudo service restart

никогда так не делали?

вот у вас база на продакшене, как вы думаете почему она не падает?)

потому что она под upstart'ом

в итоге получается что если у вас еще один супервизор, то вы получаете минимум два способа управления своим зоопарком

supervisord нужен в особых случаях, например на хекслете такой. Те кто завтра в воркшопе участвуют они это узнают

zoh всегда юзаю супервизор для прикладных, системд для системных

каких атких особых то?

sheregeda @kirill.mokevnin: убедил, пойду все переделывать. спасибо за лекцию!

kirill.mokevnin например внутри контейнера хекслета, в тех местах где у нас statefull практика

где нет системы инициализации и она там не нужна, а дерево процессов есть и его надо контролировать

zoh линух-контейнера имеется ввиду?

kirill.mokevnin в случае наличия нормальной системы инициализации это просто ненужный оверхед причем с ручными ограничениями, supervisord не умеет cgroups (или я ошибаюсь?), течет (как любой супервизор написанный на динамике), заставляет тащить в систему кучи ненужных пакетов ради него одного

я имею ввиду конкретно docker контейнеры

вы можете на хекслете стартануть какой нибудь урок по http и запустить top, там будет видно supervisord

но при этом там нет init

daniilorain

kirill.mokevnin но в любом случае я вас убеждать не планирую, просто за много лет практики (а мы повидали все супервизоры и пробовали почти все схемы), оказалось что система инициализации решает (опять же upstart/systemd)

connacte А подключить init не так просто похоже?

kirill.mokevnin но в итоге все равно все свалим на systemd, кстати уже скоро ubuntu lts, думаю через пару месяцев мы начнем мигрировать

connacte В этом случае ?

zoh initd ?

он помер же

kirill.mokevnin не понял вопрос про init

кто нибудь обратил внимание что убунта стала быстрее грузиться когда там systemd появился? Или все это провокация была?)

connacte Как я понял, вы используете supervisord в случае с statefull практикой

Это целенаправленный шаг похоже. И вот собственно вопрос ) А подключить init не так просто похоже?

kirill.mokevnin на самом деле я обманул, мы всегда используем там supervisord, просто потому что сама иде это процесс внутри контейнера который надо контролировать

поэтому в любой практике минимум supervisord => ide

подключить можно и даже есть специальный образ который туда эту систему засовывает, что там fuse вроде

но у нас там понятный и ограниченный скоуп, нам не нужна система инициализации

то есть да можно, но это ничего не даст кроме усложнения

конкретно в нашем кейсе

кстати в контейнерах еще есть проблемы с зомби процессами, мы про это даже статью на хабр переводили

https://habrahabr.ru/company/hexlet/blog/248519/

Проблема PID 1 zombie reaping в Докере Привет, Хабр! Мы в Хекслете активно используем Докер как для запуска самого приложения и сопутствующих серверов, так и для запуска пользовательского кода в...

connacte Спасибо за ответ. К сожалению, не понимаю что такое statefull практика. Это что-то из курсов? Или это особенности докера ?

kirill.mokevnin слова statefull и stateless это главные слова для разработчиков сервисов

http://stackoverflow.com/questions/5436069/what-are-the-differences-between-stateless-and-stateful-systems-and-how-do-they

What are the differences between stateless and stateful systems, and how do they impact parallelism? Explain the differences between stateless and stateful systems, and impacts of state on parallelism. 1

ваши сервисы всегда либо стейтфул либо стейтлес

это влияет вообще на все, как они строятся запускаются перезапускаются объединяются резервируются докеризируются и существуют

Clone this wiki locally