Факапы, история 2
Мы используем kubernetes в google и эта история будет про него.
У гугла с кубом довольно интересный момент, который вы не контролируете. Эти друзья могут в любой момент без предупреждения вырубить вашу ноду. Чем это для вас может грозить? Начнем с того, что окей, кубернетес умеет переподнимать убитые контейнеры, но как бы то ни было это все равно время. Хорошо, если у вас были настроены реплики и попали они на разные ноды, а гугл их вырубил в разное время. Если же нет - вас ожидает сюрприз в виде небольшого простоя. Когда умирает один контейнер и куб поднимает его на другой ноде - это все происходит быстро. Когда у вас умирает целая нода, на которой быть может 100-200-300 или больше контейнеров - это уже немножечко больно. Как минимум потому что нужно скачать образа (если их нет), а затем все это запустить. Все эти контейнеры, отправленные в свободный полет размажутся по кластеру и будут там запущены. На этом бы история закончилась, но в этот момент вылезла проблема - на нодах стала кончаться память. Как это происходит? на сервер набивается некоторое количество контейнеров, кто-то обжирается памяти, приходит OOM и прибивает обожравшийся контейнер. Верно? на самом деле нет. В реалиях ООМ убивает что под руку подвернется. Что происходит дальше? А дальше идет веселуха с Liveness, Readiness пробами. Это такой волшебный функционал, который позволяет приложению выполнять селфчек (например, доступность разнообразных бэкендов) а затем отчитываться кластеру, что приложение готово к работе. Или не готово. И тогда кластер пытается перезапустить приложение. А теперь смотрите что происходит. Перезапуск приложения по ООМ чаще всего ведет к тому что приложение мигрирует на другой сервер. Перезапуск по пробе - обычно ведет к тому что приложение локально перезапускается. Смигрировавшее на другой сервер приложение (приложения) приводят к тому, что добрый дядюшка ООМ приходит на эти сервера. И убивает их там. Или не их, а кого-то еще. Это ведет к тому, что чей-то бекенд (кого убили) может стать недоступен и из-за этого кто-то помирает по пробе. А этот кто помер по пробе снова может быть чьей-то зависимостью. И он тоже помрет по пробе. И вот такая карусель будет продолжаться пока у вас на перезапущенную ноду не приедет достаточное колиество приложений, которые с нее уехали и стали мешать другим нодам.
Вы спросите, почему не распределяется нагрузка равномерно? Всего этого можно было бы избежать, если бы были настроены лимиты. В кубернетесе существуют ограничения по ресурсам для приложения, которое можно ограничить с двух сторон - requests (сколько приложению требуется) и limits (верхний потолок сколько мы разрешаем приложению потреблять). Таким образом, вычисляется сумма всех request приложений приехавших на ноду и новые приложения, если их request < количества свободной памяти уже на ноду не приедут.
Ну и на сладкое. Гугл после перезагрузки ноды может сменить ее белый адрес. Если у вас есть какой-то внешний сервис, который по iptables ограничивает трафик и принимает его только с этого адреса ноды, вас ждет сюрприз. После ребута ноды вы можете этот трафик потерять. Придется идти и править фильтруемое значение.
З.Ы. эта история является продолжением предыдущего факапа и случилась примерно в одно и то же время с ней. Поэтому прошу не думать, что мы не учимся на своих ошибках и не ввели лимиты с прошлого раза.
#fuckup