Как настроить инициализацию Pod в определенном порядке в Kubernetes?

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

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


person AVarf    schedule 08.07.2019    source источник
comment
Можете ли вы привести пример того, как вы запускаете их в настоящее время и какую фактическую ошибку или проблему вы пытаетесь решить? Как уже говорилось, на самом деле это не вопрос программирования, и его лучше задать для serverfault.com.   -  person Andy Shinn    schedule 08.07.2019
comment
Предположим, у меня есть 4 развертывания (и каждое из них имеет свой собственный сервис и автомасштабирование), а dep B и C зависят от A, а D зависит от B. На данный момент у меня есть bash-скрипт, который запускает эти компоненты по порядку и в этот скрипт я жду 10-15 секунд перед запуском следующего развертывания. Я задавал здесь другие вопросы, связанные с k8s, но если вы думаете, что мне нужно задать этот вопрос при сбое сервера, я перенесу его.   -  person AVarf    schedule 08.07.2019
comment
Привет, вы можете проверить, верно ли условие готовности, тогда вы можете развернуть следующее развертывание https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#wait   -  person Suresh Vishnoi    schedule 08.07.2019
comment
@SureshVishnoi отличный ответ, пожалуйста, опубликуйте его как ответ, чтобы я мог принять его как решение.   -  person AVarf    schedule 10.07.2019


Ответы (7)


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

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

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

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

Подробнее см. kubectl-wait.

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

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

$ kubectl -n waitplayground \
             wait --for=condition=complete --timeout=32s \     
             job/worker
job.batch/worker condition met
person Suresh Vishnoi    schedule 10.07.2019

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

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

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

person Alassane Ndiaye    schedule 08.07.2019

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

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

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

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

person David Maze    schedule 08.07.2019

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

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

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

person Carmine Ingaldi    schedule 08.07.2019

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

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

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

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

person Todai    schedule 08.07.2019
comment
Спасибо, я не знал, что мы можем использовать helm для этого, я посмотрю на это. - person AVarf; 08.07.2019
comment
Абсолютно не беспокойтесь. Однако, как уже упоминалось, делать это helm довольно утомительно и требует большой настройки. Хотя это может стоить того, если вы хотите иметь нулевое развертывание и т. д. Не стесняйтесь пинговать меня здесь, если вам нужна дополнительная помощь. :) - person Todai; 08.07.2019

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

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

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

person Malathi    schedule 08.07.2019

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

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

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

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

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

.

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

person Diego Mendes    schedule 08.07.2019