Как настроить инициализацию Pod в определенном порядке в Kubernetes? - PullRequest
0 голосов
/ 08 июля 2019

Я хочу знать, как я могу начать развертывание в определенном порядке.Я знаю о initContainers, но это не работает для меня.У меня есть огромная платформа с примерно 20 развертываниями и 5 наборами состояний, каждый из которых имеет свой собственный сервис, переменные среды, тома, горизонтальное автоматическое масштабирование и т. Д. Поэтому невозможно (или я не знаю, как) определить их в другомразвертывание yaml как initContainers.

Есть ли другой вариант запуска развертываний в определенном порядке?

Ответы [ 7 ]

1 голос
/ 08 июля 2019

Я надеюсь, что ваши контейнеры имеют датчик живучести . Используйте их в зависимом развертывании, чтобы создать initContainer, который проверит, готово ли приложение. После того, как initContainer проверит, что другой контейнер готов, запускается зависимый контейнер.

С чем конкретно вы столкнулись с initContainer? Пример ссылки, где initContainer используется для запуска зависимого контейнера: здесь .

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

1 голос
/ 10 июля 2019

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

Например, дождитесь, пока модуль "busybox1" будет содержать состояние состояния типа "Готово".

kubectl wait --for=condition=Ready pod/busybox1

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

для более подробной информации kubect-wait

Вот еще один пример из @Michael Hausenblas job-зависимость , имеющая зависимости между объектами работы

если вы хотите начать другую работу после того, как работник завершит работу? Вот, пожалуйста:

$ kubectl -n waitplayground \
             wait --for=condition=complete --timeout=32s \     
             job/worker
job.batch/worker condition met
1 голос
/ 08 июля 2019

Просто запустите их все параллельно и дайте им упасть. Kubernetes перезапустит отказавшие после некоторой задержки.

Скажем, у вас есть служба A, которая зависит от B, которая зависит от C. A запускается первой и как часть своей последовательности запуска пытается выполнить вызов B. Сбой (потому что B не работает) и модуль изменяется на статус ошибки. Он может повторить попытку один или два раза, а затем перейти в состояние CrashLoopBackOff. Кубернетес делает паузу в течение нескольких секунд, прежде чем повторить попытку. То же самое произойдет для B.

В конце концов, сервис C (внизу стека) будет запущен, и через некоторое время после этого начнется автоматический перезапуск B (сразу над ним). На этот раз B начнется успешно. Через некоторое время после этого начнется автоматический перезапуск A, который на этот раз пройдет успешно.

Единственное, о чем вам нужно знать, это то, что если Pod действительно оказывается в состоянии CrashLoopBackOff, это может быть связано с ошибкой в ​​коде, неправильной конфигурацией или просто потому, что служба, от которой он зависит, еще не запущена , Вам нужно взглянуть на kubectl logs (и убедиться, что ваш сервисный код записывает полезную диагностику), чтобы понять, в каком случае вы находитесь.

1 голос
/ 08 июля 2019

Как указывалось во многих других ответах, приложение в архитектуре микросервиса не должно нарушать , если пакет / служба недоступны.

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

Kubernetes по своей сути не менеджер релизов, а скорее платформа. Если вам необходимо развертывать модули или службы последовательно или в определенном порядке, вам может понадобиться взглянуть на фактический менеджер релизов, такой как Helm , с использованием определенных шаблонов развертывания / разработки, таких как зонтик шаблон диаграммы ( пример StackOverflow ). Это может включать в себя дополнительную работу, но может быть то, что вы ищете.

Я действительно надеюсь, что это хоть немного помогло тебе. :)

1 голос
/ 08 июля 2019

Можно заказать запуск initContainers в модуле или модулях, которые принадлежат одному и тому же StatefulSet.Однако эти решения не применимы к вашему делу.

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

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

1 голос
/ 08 июля 2019

В k8s нет опции "зависящий от типа", и я думаю, что он не реализован только потому, что в облачной среде (= microservices) приложение не должно иметь состояния.Отсутствие состояния подразумевает также, что ни одно приложение не должно знать о состоянии другого: каждое приложение должно быть способно запускаться, уничтожаться, восстанавливаться в любой момент, не затрагивая других, за исключением того, что службы платформы, конечно, могут ухудшать качество!

Если у вас есть такого рода ограничения (это разумно, если вы развертываете брокер сообщений и каждый потребитель должен ждать, пока он не заработает, чтобы установить соединения), вам придется управлять этим «без сохранения состояния»Например, вы можете заблокировать процесс загрузки до тех пор, пока не будет установлено соединение с брокером, а затем периодически повторять попытку.С помощью kubernetes healthcecks вы даже можете объявить, что ваша служба «не готова» в этом временном окне или «не работоспособна», если не удалось выполнить несколько попыток

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

0 голосов
/ 08 июля 2019

Как уже отвечали в других ответах, вы не можете определить порядок инициализации между POD за пределами развертывания.

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

  • Что произойдет, если POD был запущен при запуске и вышел из строя после запуска другого POD?
  • Если POD B обновляется, а POD A обновляется после?

Вы должны проектировать свои системы с учетом того, что они всегда будут выходить из строя, если служба B запускается до службы A, POD будет вести себя так же, как если бы они были запущены в правильном порядке, а служба A (то есть зависимость от B) впоследствии не работала.

Ваше приложение должно обрабатывать их, а не выгружать это в оркестратор.

.

В случае, если вам действительно необходимо реализовать упорядочение и изменение приложений, не может быть и речи, вы можете использовать init containers для отправки запросов к конечным точкам работоспособности (готовности) в другойконтейнеры, точно так же, как K8 проверяет, готов ли ваш контейнер, когда они отвечают успешным ответом, вы затем завершаете выполнение init и позволяете POD запускать другие контейнеры.

...