Как стать автором
Обновить

Комментарии 18

Спасибо за статью, повеселилась 👏 так вот почему все бесконечно заводят девопсам задачи на перекладывание сервисов с ноды на ноду. Чисто чтобы парням скучно не стало и они не придумали себя развлечь чем-то подобным))

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

Чем бы солдат DevOps не занимался, лишь бы за*бался

Жду подобных историй от крупных компаний, которые в кубере запускают базы данных. Только все будет еще интереснее.

У нас там были базы данных. Просто стейдж у нас всего в одном ДЦ и он выключился весь, а препрод и прод в нескольких и там мы тоже выключали куберы, но уже после замены сети, чтобы не совмещать. Все приложения, в том числе и базы, нормально пережили это приключение)

А что не так с базами в кубернетисах? При условии, что база данных может пережить потерю реплики, конечно.

Гуглите p2p и spegel для образов.

все так, дельный совет. у нас dragonfly пир как раз в каждом слое и вот он немного не справился из-за необходимости скачать почти 5000 образов разом. добавили в них ресурсов

Dragonfly и Kraken выглядят крайне хрупкими и болезненными в эксплуатации, сапог в бою надежнее.

dragonfly с нами два года уже. отлично себя показывает. но вот на таких проверках наши новые узкие места)

Не выдержал и после стольких лет зарегался, потому что "моя свирепость не выносит такой наглости".

Вот зачем было так старательно искать приключений на свои вторые девяносто, когда правильный вариант действий был не просто возможен, а вы же его сами и описали – перезапускать ноды по одной. Да долго, да скучно, зато безопасно! А если после восьми часов махания kubectl drain вам начинает хотеться этот процесс как-то автоматизировать... То это правильное желание, автоматизировать такие вещи можно и нужно, диапазон вариантов крайне широк, от баш-скрипта до пачки операторов. Версию кубернетисов вы как обновляете? Тоже тушите кластера на пару дней? А на проде?

Для тех, кто не настолько погружен в тему, поясню. В некоторых аспектах кубернетисы довольно хрупкая система, и масштабирования туда не завезли. Сломать кластер нагрузкой на API server или etcd – фигня вопрос. Контроль нагрузки предлагается делать на клиенте. Да, на кажом. Да, самостоятельно. Нет, никакого метода понять, какие ограничения ставить нет. Да, в большинстве случаев в из или не трогают и берут значения по умолчанию, или выставляют от балды. При таких вводных делать масштабные операции типа "перезапустить все поды в кластере" – это просто напрашиваться на неприятности. И вообще в кубернетисах большие кластера живут со скрипом, лучше несколько маленьких кластеров, чем один большой.

С другой стороны, если с ним правильно обращаться, то кластер становится живучим, как советская власть – при возникновении ошибок операции by design повторяются до позеленения и куча вещей пересоздаются: прибил под – он пересоздался как ни в чем не бывало, отрубил ноду – поды разбежались по другим как тараканы, и снова работают. За то кубернетисы и любят.

Теперь подробнее по статье по пунктам.

блокировка базы данных — это нужно, чтобы минимизировать любые воздействия. Она приводит к невозможности запуска новых подов: деплоев и просто перезапусков подов вследствие выхода из строя ноды.

Заодно потеряли ивенты, и вообще все изменения в кластере. Под помер, а убрать его из эндпоинтов нельзя.

Практически единовременный запуск почти 5 000 подов — это серьёзная задачка.

Настолько серьезная, что API server скорее всего будет адски тупить в это время.

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

Э? Поды в etcd, вообще говоря, не ходят. Кьюблет взаимодействует с API сервером, а тот уже ходит в etcd.

Для этого нужно погасить containerd, удалить всю информацию о выделенных сетевых неймпейсах и запустить всё назад.

Эээ? Ну допусти ноды у вас железные, ваше право, но почему нет какого-нибудь ансибля, или парапета, или что там сейчас любят железячные админы, который придет и снесет все выступающее возвращая ноду в первозданное состояние? А операционку на нодах вы как обновляете когда там RCA находят?

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

Ну, собственно, и вот, бегать по нодам и пришлось, только не в нормальном рабочем режиме, а в состоянии "шеф, все пропало!"

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

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

некоторые поды не могут запуститься, потому что из registry не читаются данные.

Registry это который container registry? Вы бы какие нибудь ключевые слова к нему приписали, если не container, то OCI или докер, а то этих реестров – в каждом утюге, непонятно когда какой имеется в виду.

Делаю слепок всех установленных deployment и statefulset и удаляю эти объекты из кластера,

У вас приложение катятся прямо как Deployments и StatefulSets? Не сильно удобно для разработчиков, прямо скажем, особенно если много кластеров. А кластеров лучше много, по ому что см. выше про отсутствие масштабирования.

Но из-за зачистки всего и вся, мы получили бутшторм не по CPU, а по сети — все встали в очередь за образами.

Угумс, и это ещё ноды таскают образа по одному, иначе container registry тоже может мяукнуться.

Но у инфраструктуры фактически нет разделения на стейдж\пре\прод

Чистая правда, и поэтому нужен ещё один контур, например дев, который можно немножко сломать к хренам и парализовать работу только инфры, а не все разработки.

Решения для кластеров с парой десятков нод, скорее всего, не подходят для кластеров с сотнями нод.

Чистая правда, кубернетисы не умеют в масштабирование. Увы.

Наш k8s в стейдже понемногу пытается догнать продовые кластеры в Kubernetes по количеству нод: в проде — 240 и 194 ноды, в препроде — 109 и 77, в стейдже — 141.

Нахрена столько нод в стейджинге? У вас деньги лишние, что ли? Или откуда там такая нагрузка? А в препроде (это же Гамма, да? Новый код, зависимости и данные из прода) откуда, там вообще кроме тестов перед выкаткой никакой нагрузки нет? А, ну и да, два кластера. Лучше, чем один, и запас по росту у вас есть, но все равно лучше бы было больше.

Из-за запуска большого количества подов в стейдже registry, который находится не в стейдже, падает по ООМ.

Кстати, а почему он падает, а не ругается пятисотками? Может на нем каких защит накрутить?

А в завершение – извините, если критика прозвучало слишком резко, и здорово, что вы написали так подробно и с таймлайнами. Опыт, он так и приобретается, с упавшими кластерами, сегфолтами, а иногда и звонками роботети в два часа ночи. Удачи вам!

Привет. Прекрасно, что такие истории факапов помогают людям преодолеть себя и вести дискуссию :)

Версию кубернетисов вы как обновляете? Тоже тушите кластера на пару дней? А на проде?

Нет, конечно же, все это автоматизировано, как и написано в статье - пару-тройку дней летит обновление\фикс, который дрейнит ноды и все само переезжает.

Заодно потеряли ивенты, и вообще все изменения в кластере. Под помер, а убрать его из эндпоинтов нельзя.

Все верно, это болячка, которая есть при остановке. Но, мы блокировали только calico etcd, а не etcd для всего kubernetes, так что теряли по сути только часть которая касается сетевого плагина, это гораздо меньшее из зол, т.к. все пробы, например, продолжают работать.

Настолько серьезная, что API server скорее всего будет адски тупить в это время.

Да, на него нагрузка сильно увеличивается, но наши API-server даже не поперхнулись в этой части.

Э? Поды в etcd, вообще говоря, не ходят. Кьюблет взаимодействует с API сервером, а тот уже ходит в etcd.

Calico с режимом хранения информации прямо в ETCD ходит, как раз и перевозили на kubernetes API (https://docs.tigera.io/calico/latest/operations/datastore-migration)

Эээ? Ну допусти ноды у вас железные, ваше право, но почему нет какого-нибудь ансибля, или парапета, или что там сейчас любят железячные админы, который придет и снесет все выступающее возвращая ноду в первозданное состояние? А операционку на нодах вы как обновляете когда там RCA находят?

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

Ну, собственно, и вот, бегать по нодам и пришлось, только не в нормальном рабочем режиме, а в состоянии "шеф, все пропало!"

Я там в начале статьи писал, что у нас несколько разных конфигураций нод (где-то rpm-based, где-то deb, какие-то ноды выделены под общую нагрузку, а какие-то под особенную), поэтому вариант пройтись "руками" ( запускал условный `ansible hostname1,hostname32 -i inv.yml -m shell -a 'systemctl stop kubelet && systemctl stop containerd && sedgrepawk && ip netns delete...'`) все еще подходит чтобы достаточно достоверно провериить что оно работает для всех кейсов, после чего и был за 5 минут написан нормальный плейбук, который потом и полетел по серверам :)

Registry это который container registry?

Да, это был container registry. Постараюсь такие моменты в будущем отмечать, потому что внутри привыкли, что registry это всегда про контейнеры, а все остальные registry у нас больше repository

У вас приложение катятся прямо как Deployments и StatefulSets?

У нас разработчики все выкатывают с помощью helm в котором да, фактически чистые Deployment и STS

Нахрена столько нод в стейджинге? У вас деньги лишние, что ли? Или откуда там такая нагрузка?

Нод столько, как раз чтобы экономить :D. Нагрузка там от разработчиков, тестировщиков и прочих причастных к приложениям. В препроде меньше нод чем в стейдже, потомучто он не пользуется у нас большой популярностью, к сожалению, и это как раз хочется исправить, чтобы однажды наш stage и правда был тем самым dev, который не страшно уложить. Мы потом выключали также кластера k8s в pre и prod, и там не было никаких проблем и тонны вопросов "ну чо, кагда?", потому что pre и prod в нескольких экземплярах в отличии от stage

А в завершение – извините, если критика прозвучало слишком резко, и здорово, что вы написали так подробно и с таймлайнами. Опыт, он так и приобретается, с упавшими кластерами, сегфолтами, а иногда и звонками роботети в два часа ночи. Удачи вам!

Объективная критика не может быть резкой. Спасибо за такой объемный и детальный комент, такое всегда полезно 🤜🤛

Нет, конечно же, все это автоматизировано, как и написано в статье - пару-тройку дней летит обновление\фикс, который дрейнит ноды и все само переезжает.

Собственно, в этом и есть мой основной посыл: при наличие работающей схемы замены нод отказываться от нее и намеренно устраивать big bang – чревато. Посмотреть как кластер встаёт из бекапа, конечно, тоже интересно, но это отдельное развлечение со своими граблями.

Но, мы блокировали только calico etcd, а не etcd для всего kubernetes, так что теряли по сути только часть которая касается сетевого плагина, это гораздо меньшее из зол, т.к. все пробы, например, продолжают работать.

Тогда не так страшно, это да.

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

Это, наверное, вторая часть моего посыла: если в кубернетисах что-то работает не так, проще снести и пересоздать с нуля, чем чинить.

У нас разработчики все выкатывают с помощью helm в котором да, фактически чистые Deployment и STS

Понял. Это, в целом, рабочая схема, но не очень гуманно по отношению к продуктовым разработчикам (хелм – это текстовый шаблонизатор поверх ямла, и работает он примерно так же хорошо, как можно ожидать), и может выйти боком для инфраструктуры, если в кластер шаловливые ручки выкатят что-то неожиданное.

Нагрузка там от разработчиков, тестировщиков и прочих причастных к приложениям. В препроде меньше нод чем в стейдже, потомучто он не пользуется у нас большой популярностью, к сожалению, и это как раз хочется исправить, чтобы однажды наш stage и правда был тем самым dev, который не страшно уложить.

Нагрузка в стейджинге треть от прода, а в препроде ещё столько же – серьезно у вас относятся к тестам, внушает!

Несколько кластеров полезно и уменьшением blast radius когда что-то пошло не так, и вообще я сторонник держать все окружение архитектурно максимально унифицированными, но, возможно, тут расхождения в терминах. У вас в препроде настоящие данные пользователей? Если да, то его ломать никому не надо, и продуктовым разработчикам нужен всегда рабочий стейджинг. Если в препроде настоящих данных нет, то он на самом стейджинге, а стейджинг на самом деле дев.

EDIT: рано отправил.

Понял. Это, в целом, рабочая схема, но не очень гуманно по отношению к продуктовым разработчикам (хелм – это текстовый шаблонизатор поверх ямла, и работает он примерно так же хорошо, как можно ожидать)

А у нас на этот счет тоже есть "помощник", я про него рассказывал на devoops 2022 - https://youtu.be/HOIkjDIesWs. Если видео не захочется смотреть: мы написали мегачарт, который позволяет деплоить любое из наших приложений (отдельные чарты под разные opensource statefulset у нас тоже есть, но их пишет одна команда, а остальные переиспользуют)

и может выйти боком для инфраструктуры, если в кластер шаловливые ручки выкатят что-то неожиданное.

А здесь нас закрывает свои authorization и admission webhook (про них чуть детальнее рассказывал на Highload, как раз 2 декабря :)). В наш общий чарт вписано только то, что точно можно использовать, и то, некоторые из параметров в values закрыты проверками в нашем портале для разработчиков (т.е. только специально обученный человек может выписать для cервиса права на использование какого-нибудь флажочка, например, hostNetwork, для системы мониторинга)

Один чарт на все это интересная идея. Допустим, я продуктовый разработчик, что я делаю чтобы тупо выкатить новую версию? А если я хочу поменять количество реплик, или настройки HPA, или настройки readiness probe?

А здесь нас закрывает свои authorization и admission webhook

Это рабочий подход, особенно если ошибки явно выкидываются, а не как я иногда видел: Deployment есть, Replicaset есть, а подов нет. Начинаешь разбираться, смотришь на события и видишь, что ReplicaSet старательно пыьается создавать поды, а validation webhook не менее старательно их отбивает.

На самом деле я больше думал безопасность типа hostNetwork, а про PDB maxUnavailable=0 или minAvailable=1 при поде-синглтоне: оно работает нормально и все вроде ОК, но когда приходит пора апгрейдить кластер, процесс становится нетривиальным :)

Допустим, я продуктовый разработчик, что я делаю чтобы тупо выкатить новую версию? А если я хочу поменять количество реплик, или настройки HPA, или настройки readiness probe?

values.yaml 😅 есть внутренняя дока и примеры как что вписывается и куда (ну и ещё, конечно же, ctrl-c,ctrl-v из соседнего проекта). чтобы выкатить новую версию обычно используют --set и передают imageTag

Начинаешь разбираться, смотришь на события и видишь, что ReplicaSet старательно пыьается создавать поды, а validation webhook не менее старательно их отбивает

врать не буду, такое тоже иногда бывает. классический пример: квота на ресурсы CPU кончилась в неймспейсе, а квота на количество деплойментов в порядке. но от такого обычно спасает helm upgrade --wait, которой таску выкатки закончит провалом, и kubectl get events, который такое показывает.

а про PDB maxUnavailable=0 или minAvailable=1 при поде-синглтоне: оно работает нормально и все вроде ОК, но когда приходит пора апгрейдить кластер, процесс становится нетривиальным

вот с этой штукой мы в чарте подложили себе соломинку - если replicas: 1, то мы не создаем объект pdb 😀

values.yaml 😅 есть внутренняя дока и примеры как что вписывается и куда (ну и ещё, конечно же, ctrl-c,ctrl-v из соседнего проекта). чтобы выкатить новую версию обычно используют --set и передают imageTag

Это получше, чем прям весь Deployment писать, да. Из values.yaml можно попробовать сделать терпимый интерфейс для продуктовых программистов, особенно если к нему прикрутить систему овероайдов (стейджинг/прод, например), а внутри темплейтов делать особую хелмовскую магию. Правда в какой-то момент разбирать пять уровней вложенности условий в земле становится неприятно даже тем, кому это по службе положено.

если replicas: 1, то мы не создаем объект pdb

Вот да, такого рода магию я и имел виду. Ради интереса: а maxUnavailable=0 и общий случай minAvailable=replicas вы отлавливаете?

EDIT: опечатка

Вот да, такого рода магию я и имел виду. Ради интереса: а maxUnavailable=0 и общий случай minAvailable=replicas вы отлавливаете?

Не-а, т.е. если реплик больше 1, то вписывается minAvailable: 1 и все. Всем хватает, особенно в свете работы всяких HPA (хотя, конечно, корректнее будет сказать: никто не жаловался 😆)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий