Хуки жизненного цикла контейнера (Container Lifecycle Hooks) в Kubernetes

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

Аналогично многим языковым средам программирования (таким как Angular), которые имеют хуки жизненного цикла компонентов, Kubernetes предоставляет контейнерам хуки жизненного цикла. Хуки позволяют контейнерам узнавать о событиях в их жизненном цикле управления и запускать код, реализованный в обработчике, когда выполняется соответствующий хук жизненного цикла.

Контейнеры открыты для двух хуков:

PostStart

Этот хук выполняется сразу после создания контейнера. Тем не менее, нет никакой гарантии, что хук выполнится перед ENTRYPOINT контейнера. Параметры не передаются обработчику.

PreStop

Этот хук вызывается непосредственно перед тем, как контейнер завершается из-за запроса API или события управления, такого как сбой проверки жизнеспособности, вытеснение, конфликт ресурсов и другие. Вызов хука preStop завершается неудачно, если контейнер уже находится в terminated или completed состоянии. preStop это блокировка, синхронная, поэтому она должна быть завершена до того, как будет отправлен вызов на удаление контейнера. Параметры не передаются обработчику.

Реализации обработчиков хуков

Контейнеры могут получить доступ к хуку, реализовав и зарегистрировав обработчик для этого хука. Существует два типа обработчиков хуков, которые могут быть реализованы для контейнеров:

  • Exec - выполняет определенную команду, такую как pre-stop.sh, внутри cgroups и пространств имен контейнера. Ресурсы, использованные командой, засчитываются в Контейнер.
  • HTTP - выполняет HTTP-запрос к определенной конечной точке контейнера.

Исполнение обработчика хука

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

Вызовы обработчиков хуков являются синхронными в контексте pod'а, содержащего контейнер. Это означает, что для хука PostStart - ENTRYPOINT контейнера и хук срабатывают асинхронно. Однако, если хук занимает слишком много времени для запуска или зависает, контейнер не может достичь running состояния.

Поведение аналогично для хука PreStop. Если хук зависает во время выполнения, фаза Pod остается в состоянии Terminating и уничтожается после окончания TerminationGracePeriodSeconds pod'а. Если перехват PostStart или PreStop завершается неудачей, он убивает контейнер.

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

Гарантия выполнения хука

Предполагается, что выполнение хуков будет хотя бы один раз, что означает, что хук может быть вызван несколько раз для любого данного события, например для PostStart или PreStop. Это обязанность реализации хука - обрабатывать данную ситуацию корректно.

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

Отладка обработчиков хуков

Журналы для обработчика хука не отображаются в событиях Pod. Если по какой-либо причине обработчик завершается ошибкой, он передает событие. Для PostStart это событие FailedPostStartHook, а для PreStop это событие FailedPreStopHook. Вы можете увидеть эти события, запустив kubectl describe pod <pod_name>. Вот пример вывода событий при выполнении этой команды:

Events:
  FirstSeen  LastSeen  Count  From                                                   SubobjectPath          Type      Reason               Message
  ---------  --------  -----  ----                                                   -------------          --------  ------               -------
  1m         1m        1      {default-scheduler }                                                          Normal    Scheduled            Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Pulling              pulling image "test:1.0"
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Created              Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Pulled               Successfully pulled image "test:1.0"
  1m         1m        1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Started              Started container with docker id 5c6a256a2567
  38s        38s       1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Killing              Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
  37s        37s       1      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Normal    Killing              Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
  38s        37s       2      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}                         Warning   FailedSync           Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
  1m         22s       2      {kubelet gke-test-cluster-default-pool-a07e5d30-siqd}  spec.containers{main}  Warning   FailedPostStartHook


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


Комментарии

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

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

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

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