2017-03-20 22:35:51 +00:00
---
2018-02-27 18:51:46 +00:00
reviewers:
2017-03-20 22:35:51 +00:00
- mikedanese
- thockin
title: Container Lifecycle Hooks
2018-05-05 16:00:51 +00:00
content_template: templates/concept
2018-06-06 23:51:26 +00:00
weight: 30
2017-03-20 22:35:51 +00:00
---
2018-05-05 16:00:51 +00:00
{{% capture overview %}}
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
This page describes how kubelet managed Containers can use the Container lifecycle hook framework
2017-07-28 15:23:11 +00:00
to run code triggered by events during their management lifecycle.
2017-03-20 22:35:51 +00:00
2018-05-05 16:00:51 +00:00
{{% /capture %}}
2017-03-20 22:35:51 +00:00
2018-05-05 16:00:51 +00:00
{{< toc > }}
2017-03-20 22:35:51 +00:00
2018-05-05 16:00:51 +00:00
{{% capture body %}}
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
## Overview
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
Analogous to many programming language frameworks that have component lifecycle hooks, such as Angular,
Kubernetes provides Containers with lifecycle hooks.
The hooks enable Containers to be aware of events in their management lifecycle
and run code implemented in a handler when the corresponding lifecycle hook is executed.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
## Container hooks
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
There are two hooks that are exposed to Containers:
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
`PostStart`
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
This hook executes immediately after a container is created.
However, there is no guarantee that the hook will execute before the container ENTRYPOINT.
2017-07-28 15:23:11 +00:00
No parameters are passed to the handler.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
`PreStop`
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
This hook is called immediately before a container is terminated.
It is blocking, meaning it is synchronous,
2017-07-28 15:23:11 +00:00
so it must complete before the call to delete the container can be sent.
No parameters are passed to the handler.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
A more detailed description of the termination behavior can be found in
2017-05-03 15:22:28 +00:00
[Termination of Pods ](/docs/concepts/workloads/pods/pod/#termination-of-pods ).
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
### Hook handler implementations
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
Containers can access a hook by implementing and registering a handler for that hook.
There are two types of hook handlers that can be implemented for Containers:
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
* Exec - Executes a specific command, such as `pre-stop.sh` , inside the cgroups and namespaces of the Container.
Resources consumed by the command are counted against the Container.
* HTTP - Executes an HTTP request against a specific endpoint on the Container.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
### Hook handler execution
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
When a Container lifecycle management hook is called,
2017-07-28 15:23:11 +00:00
the Kubernetes management system executes the handler in the Container registered for that hook.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
Hook handler calls are synchronous within the context of the Pod containing the Container.
This means that for a `PostStart` hook,
the Container ENTRYPOINT and hook fire asynchronously.
However, if the hook takes too long to run or hangs,
2017-07-28 15:23:11 +00:00
the Container cannot reach a `running` state.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
The behavior is similar for a `PreStop` hook.
If the hook hangs during execution,
2017-10-17 18:05:49 +00:00
the Pod phase stays in a `Terminating` state and is killed after `terminationGracePeriodSeconds` of pod ends.
2017-04-25 17:36:59 +00:00
If a `PostStart` or `PreStop` hook fails,
it kills the Container.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
Users should make their hook handlers as lightweight as possible.
There are cases, however, when long running commands make sense,
such as when saving state prior to stopping a Container.
2017-03-20 22:35:51 +00:00
### Hook delivery guarantees
2017-04-25 17:36:59 +00:00
Hook delivery is intended to be *at least once* ,
which means that a hook may be called multiple times for any given event,
such as for `PostStart` or `PreStop` .
It is up to the hook implementation to handle this correctly.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
Generally, only single deliveries are made.
If, for example, an HTTP hook receiver is down and is unable to take traffic,
there is no attempt to resend.
In some rare cases, however, double delivery may occur.
2017-07-28 15:23:11 +00:00
For instance, if a kubelet restarts in the middle of sending a hook,
2017-04-25 17:36:59 +00:00
the hook might be resent after the kubelet comes back up.
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
### Debugging Hook handlers
2017-03-20 22:35:51 +00:00
2017-04-25 17:36:59 +00:00
The logs for a Hook handler are not exposed in Pod events.
If a handler fails for some reason, it broadcasts an event.
2017-07-28 15:23:11 +00:00
For `PostStart` , this is the `FailedPostStartHook` event,
and for `PreStop` , this is the `FailedPreStopHook` event.
You can see these events by running `kubectl describe pod <pod_name>` .
2017-04-25 17:36:59 +00:00
Here is some example output of events from running this command:
2017-03-20 22:35:51 +00:00
```
Events:
2017-03-23 07:10:00 +00:00
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"
2017-07-28 15:23:11 +00:00
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook
2017-04-25 17:36:59 +00:00
```
2018-05-05 16:00:51 +00:00
{{% /capture %}}
2017-04-25 17:36:59 +00:00
2018-05-05 16:00:51 +00:00
{{% capture whatsnext %}}
2017-04-25 17:36:59 +00:00
2017-05-02 21:12:48 +00:00
* Learn more about the [Container environment ](/docs/concepts/containers/container-environment-variables/ ).
2017-04-25 17:36:59 +00:00
* Get hands-on experience
[attaching handlers to Container lifecycle events ](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/ ).
2017-04-06 20:54:35 +00:00
2018-05-05 16:00:51 +00:00
{{% /capture %}}
2017-04-06 20:54:35 +00:00