Модуль K8S с указанными параметрами startupProbe и initialDelaySeconds слишком долго ожидает перехода в состояние готовности

Я пытался устранить очень странную задержку в развертывании K8S. Я отследил это до простого воспроизведения ниже. Оказывается, что если я установлю initialDelaySeconds в пробе запуска или оставлю ее равной 0 и получу единственный сбой, то проба не будет запускаться снова в течение некоторого времени и закончится с задержкой по крайней мере 1–1,5 минут при переходе в состояние готовности. : истинное состояние.

Я работаю локально с Ubutunu 18.04 и microk8s v1.19.3 со следующими версиями:

  • кубелет: v1.19.3-34 + a56971609ff35a
  • kube-proxy: v1.19.3-34 + a56971609ff35a
  • containerd: //1.3.7
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: microbot
  name: microbot
spec:
  replicas: 1
  selector:
    matchLabels:
      app: microbot
  strategy: {}
  template:
    metadata:
      labels:
        app: microbot
    spec:
      containers:
      - image: cdkbot/microbot-amd64
        name: microbot
        command: ["/bin/sh"]
        args: ["-c", "sleep 3; /start_nginx.sh"]
        #args: ["-c", "/start_nginx.sh"]
        ports:
        - containerPort: 80
        startupProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 0  # 5 also has same issue
          periodSeconds: 1
          failureThreshold: 10
          successThreshold: 1
        ##livenessProbe:
        ##  httpGet:
        ##    path: /
        ##    port: 80
        ##  initialDelaySeconds: 0
        ##  periodSeconds: 10
        ##  failureThreshold: 1
        resources: {}
      restartPolicy: Always
      serviceAccountName: ""
status: {}
---
apiVersion: v1
kind: Service
metadata:
  name: microbot
  labels:
    app: microbot
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: microbot

Проблема в том, что если у меня есть какая-либо задержка в startupProbe или если есть начальный сбой, модуль переходит в состояние Initialized: true, но имеет Ready: False и ContainersReady: False. Из этого состояния он не изменится в течение 1-1,5 минут. Шаблон в настройках не нашел.

Я также оставил в настройках комментариев, чтобы вы могли видеть, к чему я пытаюсь добраться здесь. У меня запускается контейнер, в котором есть служба, запуск которой займет несколько секунд. Я хочу сказать startupProbe, чтобы он немного подождал, а затем каждую секунду проверял, готовы ли мы к работе. Конфигурация вроде работает, но есть задержка, которую я не могу отследить. Даже после прохождения зонда запуска модуль не переводится в состояние готовности более минуты.

Есть ли какая-то настройка где-нибудь в k8s, которая задерживает количество времени до того, как Pod может перейти в состояние готовности, если он изначально не был готов?

Любые идеи приветствуются.


person Allen    schedule 02.12.2020    source источник
comment
Зонд запуска AFAIK не использует initialDelaySeconds, поэтому я бы предложил удалить его, затем настроить failureThreshold и periodSeconds с более высокими значениями, зонд запуска использует failureThreshold * periodSeconds, поэтому с вашей конфигурацией 10 с может быть недостаточно для вашего приложения. Не могли бы вы его увеличить, например до failureThreshold: 30 periodSeconds: 10 и еще раз проверить?   -  person Jakub    schedule 03.12.2020
comment
Спасибо. Я предполагаю, что initialDelaySeconds не работает с пробой запуска. Для меня это безумие, но если это так, то я поступлю именно так.   -  person Allen    schedule 04.12.2020


Ответы (1)


На самом деле я сделал ошибку в комментариях, вы можете использовать initialDelaySeconds в startupProbe, но лучше вместо этого использовать failureThreshold и periodSeconds.


Как упоминалось, здесь

Зонды Kubernetes

Kubernetes поддерживает тесты готовности и живучести для версий ≤ 1.15. Зонды запуска были добавлены в 1.16 как альфа-функция и перешли в бета-версию в 1.18 (ПРЕДУПРЕЖДЕНИЕ: 1.16 устарел несколько API Kubernetes. Используйте это руководство по миграции, чтобы проверить совместимость). Все пробники имеют следующие параметры:

  • initialDelaySeconds: количество секунд ожидания перед запуском проверки работоспособности или готовности
  • periodSeconds: как часто проверять зонд
  • timeoutSeconds: количество секунд до отметки зонда как тайм-аута (неудачная проверка работоспособности)
  • successThreshold: минимальное количество последовательных успешных проверок для прохождения зондом
  • failureThreshold: количество повторных попыток перед пометкой зонда как сбойного. Для зондов живучести это приведет к перезапуску модуля. Для зондов готовности это пометит контейнер как неготовый.

Так почему вы должны использовать failureThreshold и periodSeconds?

рассмотрим приложение, в котором время от времени требуется загрузить большие объемы данных или выполнить дорогостоящую операцию в начале процесса. Поскольку initialDelaySeconds является статическим числом, мы вынуждены всегда брать наихудший сценарий (или увеличивать значение failureThreshold, которое может повлиять на длительное поведение) и ждать в течение длительного времени, даже если это приложение не необходимо выполнить длительные этапы инициализации. Вместо этого с помощью зондов запуска мы можем настроить failureThreshold и periodSeconds, чтобы лучше моделировать эту неопределенность. Например, установка failureThreshold на 15 и periodSeconds на 5 означает, что приложение получит 10 x 5 = 75 секунд на запуск, прежде чем произойдет сбой.

Кроме того, если вам нужна дополнительная информация, ознакомьтесь с этой статьей на носителе.


Цитируется из kubernetes документация о защите медленно запускаемых контейнеров с помощью зондов запуска

Иногда вам приходится иметь дело с устаревшими приложениями, которым может потребоваться дополнительное время запуска при их первой инициализации. В таких случаях может быть сложно настроить параметры проверки работоспособности без ущерба для быстрого ответа на тупиковые ситуации, которые послужили причиной такой проверки. Хитрость заключается в том, чтобы настроить пробу запуска с той же командой, проверкой HTTP или TCP, с параметром failureThreshold * periodSeconds, достаточным для покрытия времени запуска наихудшего случая.

Итак, предыдущий пример будет выглядеть следующим образом:

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080

livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 1
  periodSeconds: 10

startupProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 30
  periodSeconds: 10

Благодаря тесту запуска у приложения будет максимум 5 минут (30 * 10 = 300 секунд), чтобы завершить запуск. После того, как зонд запуска был успешен один раз, зонд живучести вступает во владение, чтобы обеспечить быстрый ответ на тупиковые ситуации контейнера. Если зонд запуска никогда не завершается успешно, контейнер уничтожается через 300 секунд и подчиняется политике restartPolicy модуля.

person Jakub    schedule 07.12.2020