Kubernetes - подожди, пока другой модуль будет готов
У меня есть два приложения - app1 и app2, где app1 является config server
который содержит конфиги для app2. Я определил /readiness
конечная точка в app1 и нужно ждать, пока она не вернется OK
Статус запуска модулей приложения 2.
Крайне важно, чтобы развертывание app2 подождало до kubernetes
получает Http Status OK
конечная точка from / readiness в app1, так как это сервер конфигурации и содержит важные настройки для app2.
Можно ли сделать такой тип развертывания зависимости?
7 ответов
Вам нужно использовать initContainers
, Ниже приведен пример того, как вы можете сделать в своем YAML
файл
initContainers:
- name: wait-for-other-pod
image: docker.some.image
args:
- /bin/sh
- -c
- >
set -x;
while [ $(curl -sw '%{http_code}' "http://www.google.com" -o /dev/null) -ne 200]; do
sleep 15;
done
Будь осторожен с YAML
пространства. я использовал curl
, вы можете использовать любую другую команду UNIX, чтобы проверить, готов ли другой модуль, например, ping
, если вы знаете имя хоста.
Обратите внимание: вам нужно решить, исходя из требований вашего бизнеса, хотите ли вы ждать в initcontainer
или же containers
(в args
) следующее:
containers:
- name: <container_name>
image: "<image_name>"
imagePullPolicy: Always
args:
- /bin/sh
- -c
- >
<write your wait code here>
Да, возможно использование контейнеров инициализации (также см. Этот пост в блоге для получения дополнительной информации о хронометраже), но лучше, более родной шаблон Kubernetes- использовать повторные попытки и тайм-ауты, а не жестко кодировать зависимости таким образом.
initContainers:
- name: wait-for-dependent-service
image: stefanevinance/wait-for-200
env:
- name: URL
value: http://dependent-service.{{.Release.Namespace}}.svc.cluster.local:3000
Используя https://hub.docker.com/r/stefanevinance/wait-for-200/
В моем случае у приложения нет конечной точки /readiness. У нас есть главные модули и рабочие модули, и мы хотим, чтобы рабочие модули запускались только после того, как главный модуль запущен и работает. Главный модуль запускает приложение, прослушивающее TCP-порт 80. В итоге я использовал netcat в контейнере инициализации в рабочем модуле.
nc -z <host> <port>
nc проверит, открыт ли порт, завершив работу с 0 в случае успеха и 1 в случае неудачи.
initContainers:
- name: wait-for-master-before-starup
image: busybox
command: ["sh", "-c", "until nc -z master-service 80 > /dev/null; do echo Waiting for master.; sleep 2; done;"]
Если у вас уже есть конечная точка работоспособности/готовности, гораздо лучше использовать ее, как указано в других ответах здесь.
На самом деле использовать wait-for-it.sh довольно просто:
initContainers:
- name: wait-for-app1
image: image-docker-containing-sh
args:
- /bin/sh
- -c
- /usr/app/wait-for-it.sh app1:<portapp1> -t 0
Конечно, можно использовать повторные попытки и тайм-ауты, но это отлично работает как обходной путь.
В настоящее время kubernetes не поддерживает эту функцию "из коробки". И я не думаю, что это должно (в идеале). Вот мои мысли по этому вопросу:
Что делать, если Kubernetes пытается запланировать оба одновременно? а. Сначала появляется app1, не о чем беспокоиться. б. Сначала появляется app2 и не находит app1, а затем его модуль перезапускается. Между тем, app1 появляется, а потом не о чем беспокоиться.
Вы можете попытаться добиться поведения зависимости, используя '
lifecycle
Крюк под контейнерами. Там вы можете выполнить команду / скрипт, который может блокировать контейнер, пока не появится app1. Они объяснены на https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/На базе kubernetes построены аддоны, которые пытаются достичь того же. Вы можете найти их на GitHub.
то же, что и @Vishrant Answer... просто другой способ записать команды bash в одну строку в файле YAML
initContainers:
- name: wait-for-some-pod
image: yourDockerImage
command: ["/bin/sh","-c"]
args: ['while [ $(curl -ksw "%{http_code}" "https://<pod_health_check_end_point>" -o /dev/null) -ne 200 ]; do sleep 5; echo "health check failed . Waiting for the service..."; done']