Жизненный цикл Pod'а (Pod Lifecycle)

Pod phase

Поле status Pod'а - это объект PodStatus, который имеет поле phase.

Фаза (phase) Pod'а - это простая, высокоуровневая сводка о том, где Pod находится в его жизненном цикле. Эта фаза не предназначена для того, чтобы быть полным сводом данных наблюдений за состоянием контейнера или Pod, и при этом она не предназначена для того, чтобы быть всеобъемлющим конечным состоянием машины.

Количество и значения фазы Pod строго регламентированы.

Вот все возможные значения для фазы (phase):

  • Pending (в ожидании). Pod был принят системой Kubernetes, но один или несколько образов Контейнера не были созданы. Эта фаза включает время до того, как Pod запланирован (scheduled) на какой-либо узел, а также время, потраченное на загрузку образов по сети, что может занять некоторое время.
  • Running (запуск). Pod связан с узлом, и все контейнеры созданы. По крайней мере, один Контейнер все еще работает или находится в процессе запуска или перезапуска.
  • Succeeded (успешно). Все контейнеры в Pod успешно завершены и не будут перезапущены.
  • Failed (сбой). Все контейнеры в Pod были завершены, и по крайней мере один контейнер завершил работу в результате сбоя. То есть контейнер либо вышел с ненулевым статусом, либо был завершен системой.
  • Unknown (неизвестно). По какой-то причине состояние Pod не может быть получено, как правило, из-за ошибки связи с хостом Pod.

Условия Pod (Pod conditions)

Pod имеет PodStatus, который имеет массив PodConditions, через которые Pod прошел или не прошел. Каждый элемент массива PodCondition имеет шесть возможных полей:

  • Поле lastProbeTime предоставляет метку времени (timestamp), когда условие (condition) Pod было в последний раз проверено.
  • Поле lastTransitionTime предоставляет временную метку (timestamp) для последнего перехода Pod из одного состояния (status) в другое.
  • Поле message представляет собой удобочитаемое сообщение, указывающее подробную информацию о переходе.
  • Поле reason - это уникальная причина, состоящая из одного слова (записанная в CamelCase), для последнего перехода условия.
  • Поле status представляет собой строку с возможными значениями “True”, “False”, и “Unknown”.
  • Поле type представляет собой строку со следующими возможными значениями:
    • PodScheduled: Pod был запланирован для узла;
    • Ready: Pod может обслуживать запросы и должен быть добавлен в пулы балансировки нагрузки всех соответствующих сервисов;
    • Initialized: все init-контейнеры успешно запущены;
    • Unschedulable: планировщик не может планировать Pod прямо сейчас, например, из-за нехватки ресурсов или других ограничений;
    • ContainersReady: все контейнеры в Pod готовы.

Контейнерные пробы (Container probes)

Probe - это диагностика, которую периодически выполняет kubelet на контейнере. Чтобы выполнить диагностику, kubelet вызывает Handler (обработчик), реализованный контейнером. Есть три типа обработчиков:

ExecAction: выполняет указанную команду внутри контейнера. Диагностика считается успешной, если команда завершается с кодом состояния 0.

TCPSocketAction: выполняет проверку TCP по IP-адресу контейнера на указанном порту. Диагностика считается успешной, если порт открыт.

HTTPGetAction: выполняет HTTP GET запрос по IP-адресу контейнера на указанном порту и пути. Диагностика считается успешной, если ответ имеет код состояния больше или равный 200 и меньше 400.

Каждая probe имеет один из трех результатов:

  • Success (успех): Контейнер прошел диагностику.
  • Failure (сбой): Контейнер не прошел диагностику.
  • Unknown (неизвестно): диагностика не удалась, поэтому никаких действий предпринимать не нужно.

Kubelet может опционально выполнять и реагировать на два типа проб (probes) на работающих контейнерах:

livenessProbe: указывает, работает ли контейнер. В случае сбоя проверки работоспособности (liveness probe) kubelet уничтожает Контейнер, и Контейнер подвергается политике перезапуска. Если Контейнер не предоставляет проверку жизнеспособности (liveness probe), состояние по умолчанию - Success (успех).

readinessProbe: указывает, готов ли контейнер к обслуживанию запросов. В случае сбоя проверки готовности (readiness probe) контроллер конечных точек удаляет IP-адрес Pod'а из конечных точек всех служб, соответствующих Pod'у. Состояние готовности по умолчанию до начальной задержки - Failure (сбой). Если Контейнер не предоставляет проверку готовности, состояние по умолчанию - Success (успех).

Когда следует использовать пробы жизнеспособности (liveness) или готовности (readiness)?

Если процесс в вашем контейнере может обрушиться сам по себе, когда он сталкивается с проблемой или становится нездоровым, вам не обязательно нужен тест на жизнеспособность; kubelet автоматически выполнит правильное действие в соответствии с restartPolicy Pod'а.

Если вы хотите, чтобы ваш Контейнер был уничтожен и перезапущен в случае сбоя пробы, задайте пробу жизнеспособности и укажите restartPolicy как Always или OnFailure.

Если вы хотите начать отправку трафика на Pod только после успешного прохождения пробы, укажите пробу готовности. В этом случае проба готовности может совпадать с пробой жизнеспособности, но наличие в спецификации (spec) пробы готовности (readiness probe) означает, что Pod запускается без получения трафика и начинает получать трафик только после успешного прохождения пробы. Если ваш Контейнер должен работать при загрузке больших данных, файлов конфигурации или миграций во время запуска, задайте пробу готовности.

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

Обратите внимание, что если вы просто хотите получать запросы при удалении модуля Pod, вам не обязательно иметь пробу готовности; при удалении Pod автоматически переводит себя в состояние unready (не готов), независимо от того, существует ли проба готовности. Pod остается в unready состоянии, пока он ожидает остановки Контейнеров в Pod'е.

Состояния контейнеров (Container States)

Как только Pod назначен на узел планировщиком, kubelet начинает создавать контейнеры с использованием среды выполнения контейнера. Существует три возможных состояния контейнеров: Waiting (Ожидание), Running (Работает) и Terminated (Завершен). Чтобы проверить состояние контейнера, вы можете использовать kubectl describe pod [POD_NAME]. Состояние отображается для каждого контейнера в этом Pod'е.

Waiting (Ожидание): состояние контейнера по умолчанию. Если контейнер не находится в состоянии Running или Terminated, он находится в состоянии Waiting. Контейнер в состоянии Waiting все еще выполняет свои необходимые операции, такие как загрузка образов, применение секретов и т.д. Наряду с этим состоянием отображается сообщение и причина состояния, чтобы предоставить дополнительную информацию.

...
  State:         Waiting
   Reason:       ErrImagePull
  ...

Running (Работает): указывает, что контейнер выполняется без проблем. Как только контейнер входит в Running, выполняется хук postStart (если есть). В этом состоянии также отображается время, когда контейнер перешел в состояние Running.

   ...
      State:         Running
       Started:      Wed, 30 Jan 2019 16:46:38 +0530
   ...

Terminated (Завершен): указывает, что контейнер завершил выполнение и прекратил работу. Контейнер входит в это состояние, когда он успешно завершил выполнение или когда он потерпел неудачу по некоторой причине. Независимо от этого, отображается причина и код выхода, а также время начала и окончания контейнера. Перед входом контейнера в Terminated выполняется preStop хук (если есть).

   ...
      State:          Terminated
        Reason:       Completed
        Exit Code:    0
        Started:      Wed, 30 Jan 2019 11:45:26 +0530
        Finished:     Wed, 30 Jan 2019 11:45:26 +0530
    ...

Этап готовности Pod

Чтобы добавить расширяемость в готовность Pod, позволяя вводить дополнительную обратную связь или сигналы в PodStatus, Kubernetes 1.11 представил функцию с именем Pod ready++. Вы можете использовать новое поле ReadinessGate в PodSpec, чтобы указать дополнительные условия, которые будут оцениваться для готовности Pod. Если Kubernetes не может найти такое условие в поле status.conditions модуля Pod, статус условия по умолчанию равен “False”. Ниже приведен пример:

Kind: Pod
...
spec:
  readinessGates:
    - conditionType: "www.example.com/feature-1"
status:
  conditions:
    - type: Ready  # это встроенный PodCondition
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
    - type: "www.example.com/feature-1"   # дополнительный PodCondition
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
  containerStatuses:
    - containerID: docker://abcd...
      ready: true
...

Новые условия Pod должны соответствовать формату ключа метки Kubernetes. Поскольку команда kubectl patch по-прежнему не поддерживает исправление состояния объекта, новые условия Pod должны вводиться с помощью действия PATCH с использованием одной из библиотек KubeClient.

С введением новых условий Pod, Pod оценивается как готовый, только если оба следующих утверждения верны:

  • Все контейнеры в Pod готовы.
  • Все условия, указанные в ReadinessGates, являются "True".

Чтобы упростить это изменение оценки готовности Pod, введено новое условие Pod ContainersReady для захвата старого условия Pod Ready.

В K8s 1.11, в качестве альфа-функции, необходимо явно включить функцию "Pod Ready++", установив для параметра "PodReadinessGates" значение true.

В K8s 1.12 эта функция включена по умолчанию.

Политика перезапуска

PodSpec имеет поле restartPolicy с возможными значениями Always, OnFailure и Never. Значением по умолчанию является Always (Всегда). restartPolicy применяется ко всем контейнерам в Pod. restartPolicy относится только к перезапускам контейнеров посредством kubelet на том же узле. Контейнеры, выполнившие выход, которые перезапускаются с помощью kubelet, перезапускаются с экспоненциальной задержкой отсрочки (10 с, 20 с, 40 с ...), ограниченной пятью минутами, и сбрасываются после десяти минут успешного выполнения. После привязки к узлу Pod никогда не будет привязан к другому узлу.

Время жизни Pod

В общем, Pod'ы не исчезают, пока их не уничтожат. Это может сделать администратор (человек) или контролер. Единственное исключение из этого правила состоит в том, что Pod с фазой Succeeded или Failed в течение более некоторой продолжительности (определяемой в terminated-pod-gc-threshold в ведущем устройстве) истекает и автоматически уничтожается.

Доступны три типа контроллеров:

  • Используйте Job для Pod'а, который, как ожидается, прекратит работу, например, Pod с пакетными вычислениями. Job'ы подходят только для Pod со значением restartPolicy, равным OnFailure или Never.
  • Используйте ReplicationController, ReplicaSet или Deployment для Pod, которые не должны завершаться, например, веб-серверы. Контроллеры ReplicationController подходят только для Pod с restartPolicy (политикой перезапуска) равной Always.
  • Используйте DaemonSet для Pod, которые должны запускаться по одному на каждой машине, поскольку они предоставляют системную службу для конкретной машины.

Все три типа контроллеров содержат PodTemplate. Рекомендуется создать соответствующий контроллер и позволить ему создавать Pod'ы, а не создавать их самостоятельно. Это связано с тем, что сами Pod не устойчивы к сбоям машины, а контроллеры устойчивы.

Если узел умирает или отключается от остальной части кластера, Kubernetes применяет политику для установки фазы всех Pod в потерянном узле на Failed.

Примеры

Пример расширенной пробы жизнеспособности (liveness probe)

Пробы жизнеспособности выполняются kubelet'ом, поэтому все запросы выполняются в пространстве имен сети kubelet.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - args:
    - /server
    image: k8s.gcr.io/liveness
    livenessProbe:
      httpGet:
        # когда "host" не задан, "PodIP" будет использован
        # host: my-host
        # когда "scheme" не задана, "HTTP" scheme будет использована. 
        # Только "HTTP" и "HTTPS" допустимы
        # scheme: HTTPS
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 15
      timeoutSeconds: 1
    name: liveness

Примеры состояний

  • Pod работает и имеет один контейнер. Контейнер выходит с успехом.
    • Логируется событие завершения (completion event).
    • Если restartPolicy равна:
      • Always: перезапустить контейнер; фаза Pod остается Running.
      • OnFailure: фаза Pod становится Succeeded.
      • Never: фаза Pod становится Succeeded.
  • Pod работает и имеет один контейнер. Контейнер выходит с ошибкой.
    • Логируется событие сбоя (failure event).
    • Если restartPolicy равна:
      • Always: перезапустить контейнер; фаза Pod остается Running.
      • OnFailure: перезапустить контейнер; фаза Pod остается Running.
      • Never: фаза Pod становится Failed.
  • Pod работает и имеет два контейнера. Контейнер 1 выходит из строя с ошибкой.
    • Логируется событие сбоя (failure event).
    • Если restartPolicy равна:
      • Always: перезапустить контейнер; фаза Pod остается Running.
      • OnFailure: перезапустить контейнер; фаза Pod остается Running.
      • Never: не перезапускать контейнер; фаза Pod остается Running.
    • Если контейнер 1 не запущен, а контейнер 2 завершен:
      • Логируется событие сбоя (failure event).
      • Если restartPolicy равна:
        • Always: перезапустить контейнер; фаза Pod остается Running.
        • OnFailure: перезапустить контейнер; фаза Pod остается Running.
        • Never: фаза Pod становится Failed.
  • Pod работает и имеет один контейнер. Контейнеру не хватает памяти (runs out of memory).
    • Контейнер завершается в сбое.
    • Логируется OOM (out of memory) событие (OOM event).
    • Если restartPolicy равна:
      • Always: перезапустить контейнер; фаза Pod остается Running.
      • OnFailure: перезапустить контейнер; фаза Pod остается Running.
      • Never: Логируется событие сбоя (failure event); фаза Pod становится Failed.
  • Pod работает и происходит тотальный сбой диска.
    • Уничтожаются все контейнеры.
    • Логируется соотвествующее событие.
    • Фаза Pod становится Failed.
    • Если работает под контроллером, Pod воссоздается в другом месте.
  • Pod работает, и его узел сегментирован.
    • Контроллер узла ожидает истечения времени ожидания.
    • Контроллер узла устанавливает фазу Pod в состояние Failed.
    • Если работает под контроллером, Pod воссоздается в другом месте.

Читайте также:


Комментарии

Популярные сообщения из этого блога

Контроллеры в Kubernetes: DaemonSet

Контроллеры в Kubernetes: ReplicaSet

Контроллеры в Kubernetes: StatefulSet