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 или же containersargs) следующее:

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 не поддерживает эту функцию "из коробки". И я не думаю, что это должно (в идеале). Вот мои мысли по этому вопросу:

  1. Что делать, если Kubernetes пытается запланировать оба одновременно? а. Сначала появляется app1, не о чем беспокоиться. б. Сначала появляется app2 и не находит app1, а затем его модуль перезапускается. Между тем, app1 появляется, а потом не о чем беспокоиться.

  2. Вы можете попытаться добиться поведения зависимости, используя 'lifecycleКрюк под контейнерами. Там вы можете выполнить команду / скрипт, который может блокировать контейнер, пока не появится app1. Они объяснены на https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/

  3. На базе 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']
Другие вопросы по тегам