Допустим сервер перегружен чем-то (мы знаем через мониторинг, что load average дикий, но больше, толком, ничего не знаем). Посмотреть через SSH не можем, т.к. залогиниться не получается. Либо сразу обывает соединение, либо устанавливается TCP соединение, но не дает баннера SSH даже за полчаса.
Очень обидная ситуация, так как сервер в общем-то работает, даже на простые HTTP запросы отвечает. Был бы ssh - все можно было бы разобраться и починить. (логин, ps, kill, kill, kill). Но его нет.
Ну семь бед - один ответ, хостер перегрузит. Но возникают вопросы.
Вопрос 1 - по какой именно причине не логинится SSH? Нет свободной памяти? (основная моя версия) Или процессора настолько не хватает? (но я полчаса ждал - так даже баннера от SSH не дождался)
Вопрос 2 (админский) - может быть есть какая-то возможность для этого, чтобы избежать этой проблемы в будущем? Теоретически, если SSH сразу себе лишние десять мегабайт на сервере зарезервирует под рут логин, и при логине их будет использовать - это бы сильно помогло. Может быть есть какой-то трюк для этого?
Вопрос 3 (программистский. актуален, если на 2 нет хорошего ответа) - а возможно ли это в Linux в принципе? Если наша программа (наш ssh демон или getty) запускает другую программу (шелл) и для этого ей нужно сколько-то памяти, то можем ли мы заранее ее занять, и к моменту запуска как-то указать, что можно ее использовать, чтобы шелл-процесс запустился гарантированно? Может быть (как извращенный трюк) сразу запускать bash (при запуске сервера) а при логине только коннектить как-то юзера и bash?
1. Да, память. Если процесс жив, но долго отвечает - чаще всего проблема в дисковом io, а потом уже цпу.
Или сеть, или хитрый ддос
Но у вас может быть свой кейс
Правильнее будет найти первоисточник проблемы, перегрузка сети\цп\озу\io. Дальше отталкиваться уже от нее. А если совсем правильно то найти это проблему, найти причину и устранить ее т.к. скорее всего она будет крыться в кривых конфигах.
В частном случае - конечно.
Но у меня в жизни не первый раз, когда сервер живой, а достучаться не могу. Поэтому хочется в общем случае решить эту проблему.
Ярослав Поляков, еще раз, ищите первоисточник. Грубо , есть задача которая жрет все ЦП время? Ограничьте ее и оставьте свободным хотябы одно.? нет ядер\потоков тогда ограничьте для процесса потребление. Процесс жрет всю память, ограничьте потребление!
Теперь еще раз внимательно перечитайте оба сообщения.
Да в другом дело. С сервером (с частной проблемой) уже решилось все. (перегрузили и зашли).
Суть моего вопроса про ОБЩУЮ ситуацию - как сделать когда у меня или у вас или у кого-то еще будет какая-то задача, которая отжирает память - как сделать чтобы SSH работал? Предотвратить OOM в мировом масштабе - задача заведомо невыполнимая. А вот сделать так, чтобы по SSH можно было зайти даже когда на сервере OOM - это вполне решаемо. (и мне немного странно, что до сих пор это никем в мире не сделано).
Как один из вариантов - вот cgroups выше предложили. А у меня была мысль, может быть как-то можно пре-аллоцировать мегабайт 10-50 для SSH, чтобы рут всегда мог зайти и запустить ps, kill итд
Владимир, как написал автор сервер могут перезагрузить. Соответственно после перезагрузки нужно и начинать решать проблемы.
Ярослав Поляков, видимо не хотите понимать что я пытаюсь донести до Вас. Раз так то идите тупейшим путем, режьте глобально через cgroups потребление ресурсов для группы пользователей и под ними запускайте весь ваш софт который по совершенно неинтересной для вас причине начинает их выжирать. Демона ssh оставьте вне этих групп.
Еще вариант ulimit чтобы рулить в пределах процесса конкретного(хотя точнее будет сессии).
Еще вариант , раз вам глубоко пофиг на причина а значит и рождаемые вами проблемы убийства процессов и возможной потери данных, шаманить с конфигами самого OOMKiller чтобы он сам прибивал толстяка. В конечном счете сейчас вам нужен ssh чтобы просто прибить процесс так проще это автоматизировать.
Дмитрий Александров, я понимаю что вы хотите донести. И я спрашиваю про другой (гораздо более сложный) путь, не потому что простой, прямой и короткий путь мне не нравится, а именно наоборот - именно потому что он мне полностью понятен, зачем мне отвлекать тут людей вопросами, на которые я знаю ответ? Это не ситуация или/или. Сервер уже ребутнули, логи начали копать, итд. (как бы, простуду вылечили до следующего раза традиционными понятными средствами)
Просто эта проблема (моя частная, локальная и понятная) меня натолкнула на мысль о более глобальной мировой проблеме, с которой все изредка сталкиваются (невозможность удаленно зайти на сервер) и вот эта ситуация технически у меня вызывает больше интереса и желания понять ее :-). (хочется понять, есть ли универсальная вакцина от этой простуды)
Александр Маджугин, мне понравилась эта идея (хотя и через задницу, но вполне рабочая же!). Только, надо, наверное, не bash а busybox, потому что bash не сможет даже ps запустить, если памяти нет, а в busybox они встроены все. Хотя, блин, malloc() то все равно вызывают - может и упасть, наверное.
Kvm по идее спас бы ситуацию. На крайняк если виртуалка, то менеджер виртуалки. По хорошему настроить мониторинг с логами и уже копать там что является причиной.
Во-первых - сам oom настраивается, можно процессам задавать приоритеты для oom.
Во-вторых - высокий la, из-за которого всё тормозит, может быть по очень разным причинам. И вообще странно думать сразу в сторону oom - он бы наубивал там и всё стало б хорошо, а раз не становится - это уж скорее диск. Или что-то еще.
В-третьих (хотя на самом деле с этого надо начинать) - мониторинг настраивай. Хотя бы netdata поставь, это максимально быстро. Но лучше конечно на отдельный сервер Prometheus с Grafana, а на проблемный сервер соответственно node exporter и экспортеры для конкретных твоих приложений. Ну т.е. в общем случае задача решается мониторингом, опять же логи тоже чтобы отправлялись на другой сервер. А в мониторинге алерты, чтобы успеть среагировать на проблемы, когда они только-только начались.
Полностью согласен с ораторами насчет виртуализации.
По поводу ситуации что уже случилась. Скорее всего заход в баш вам ничего не даст. Т.к. любые команды что вы будете выполнять будут запускать процессы и вы будете снова и снова получать ту-же ситуацию что и с башом. Тоесть каким-то чудом зашли но ничего сделать толком нельзя.
Нужно 100% собрать логи и посмертные снимки памяти приложений. Или приложения. Скорее всего оно одно. И оно-же является источником проблемы. Это приложение надо перенести в докер к лимитами по памяти и там запускать.
Дампы памяти надо проанализировать и понять что флудит. С точки зрения приложения должны быть какие-то гарантии или требования по штатному режиму работы. Тоесть если ему надо 8Г то дайте ему ровно 8 и не больше.
Я согласен. Поэтому, наверное, для такого rescue shell нужно использовать busybox, чтобы все утилиты уже были включены. Хотя бы ls/cat/ps.
Для решения частной проблемы - так и надо поступать, как вы описали. Но меня заинтересовало общее решение. При разработке же не знаешь где соломку подстелить. Поэтому и подумалось, что, наверное, было б хорошо, чтобы ssh сразу имел такую возможность, чтобы хоть что-то сразу сделать в аварийной ситуации и быстрее понять ситуацию. Еще при установке сервера включить какую-нибудь опцию EnableRescueShell yes, и через три года она пригодится.