Kubernetes allows container lifecycle hooks to respond to container creations and terminations. You can handle events by running a command inside the container or by making an HTTP request to the endpoint it exposes.
Hooks are typically used to log container events, run cleanup scripts, and perform asynchronous tasks after connecting to your new Pod cluster. In this article, we’ll show you how to add fork handlers to your Pods and gain more control over container lifecycles.
Two Available Hooks
Current Kubernetes releases support two container lifecycle hooks:
PostStart– Handlers for this hook are called immediately after a new container is created.
PreStop– This hook is fired just before Kubernetes stops the container.
They can be controlled using two different mechanisms:
Exec– Executes the command defined inside the container.
HTTP– Sends an HTTP request to the URL inside the container.
None of the hooks provide any arguments to their handlers. Each container supports one handler for each hook; it is not possible to call multiple endpoints or combine an exec command with an HTTP request.
Defining Hook Handlers
You define fork handlers for Pods using them
containers.lifecycle open field. In this field, select
preStop properties to implement one or both of the existing hooks.
Here’s a simple Pod that logs a message on startup:
apiVersion: v1 kind: Pod metadata: name: pod-with-hooks spec: containers: - name: pod-hook-container image: nginx:latest lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo STARTED > /startup_message"]
Deploy a Pod to your cluster using kubectl:
$ kubectl apply -f pod.yaml
Now take a shell to the container running inside Pod:
$ kubectl exec --stdin --tty pod/pod-with-hooks -- sh
Read the content
$ cat /startup_message STARTED
This indicates that the hook has been called successfully. An exec hook is considered successful when its command exits with a zero status code.
you can configure the HTTP handler by replacing
exec area with
httpGet. HTTP only
GET queries are supported (no
apiVersion: v1 kind: Pod metadata: name: pod-with-hooks spec: containers: - name: pod-hook-container image: nginx:latest lifecycle: postStart: httpGet: path: /startup port: 80
In this example, Kubernetes does
GET apply for
/startup at the port of the container 80. The
httpGet field also accepts
host properties to further configure the query.
There is a Pod here
/shutdown is called over HTTPS before container termination occurs:
apiVersion: v1 kind: Pod metadata: name: pod-with-hooks spec: containers: - name: pod-hook-container image: nginx:latest lifecycle: preStop: httpGet: path: /startup scheme: HTTPS
HTTP hook handlers are considered successful if the HTTP response code is in the range 200-299.
Tuning your handlers
Hook handlers are managed independently of the Pods they are attached to. Their logs aren’t collected and stored alongside normal Pod logs, so you won’t see run commands like
echo Started while running
kubectl logs pod/pod-with-hooks.
You can fix hooks by looking at the Pod’s event history. It will be reported as failed calls
FailedPreStophook events. The error message contains a description of what caused the error.
Try adding this Pod to your cluster:
apiVersion: v1 kind: Pod metadata: name: pod-with-hooks spec: containers: - name: pod-hook-container image: nginx:latest lifecycle: postStart: exec: command: ["missing-command"]
A broken PostStart hook will cause Pod initialization to fail. use it
kubectl describe to access its event history:
$ kubectl describe pod/pod-with-hooks ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 30s default-scheduler Successfully assigned pod-with-hooks... Normal Created 10s (x2 over 11s) kubelet Created container pod-hook-container Normal Started 10s (x2 over 11s) kubelet Started container pod-hook-container Warning FailedPostStartHook 10s (x2 over 11s) kubelet Exec lifecycle hook ([missing-command]) for Container "pod-hook-container" in Pod "pod-with-hooks" failed - error: command 'missing-command' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "missing-command": executable file not found in $PATH: unknownrn" Normal Killing 10s (x2 over 11s) kubelet FailedPostStartHook Warning BackOff 5s (x2 over 6s) kubelet Back-off restarting failed container
FailedPostStartHook because the event handler failed
missing-command is not a valid executable inside the container. This caused the container to be killed and restarted in the return loop. It will be stuck like this forever
missing-command will never be executed.
Need to see
Hook calls have several features that can catch you off guard. Keeping these in mind can help you avoid strange behavior and unexpected failures.
- Hooks can be called more than once. Kubernetes guarantees you
PreStophandlers will be called “” at least once per container. In some cases, the hook may be called multiple times. Your handlers must be idempotent so that they can withstand this possibility.
- Failed hooks kill their containers. As shown in the debugging example above, failed hooks immediately kill their containers. To avoid unexpected issues with pod startup, you should ensure that your commands and HTTP endpoints are error-free. Hook handlers should be lightweight and dependency-free. Do not attempt to access a resource that may be unavailable immediately after your container is started.
PostStarthooks are the race of the container
PostStartfires at about the same time as the container is created. Kubernetes does not expect a hook – it will be called asynchronous next to the container.
ENTRYPOINT, which can be completed before your fork handler is started. This means your container’s entry point script will be start even if your handler reports an error and kills the container.
PreStopthe hooks will prevent the container from stopping. Kubernetes guarantees that your containers will not be stopped until they are shut down
PreStopforks are completed, up to the maximum time specified by the Pod’s timeout. When the grace period expires, the container will be terminated regardless of whether the hook is still running.
PreStophooks are not called completed Pods. This can be particularly effective depending on your use case. Current execution
PreStopfires when there is only one Pod stopped due to deletion, resource exhaustion, research failure or similar event. Naturally, the hook will not be called for containers that are stopped because their process finishes its task and exits with a zero error code.
Hooks have a direct impact on the lifecycle of your Pods. Cannot be registered as pods
Running up to them
PostStart hook completes; likewise, a Pod will get stuck
Terminating up to
Kubernetes lifecycle events are a way to notify containers of their own creation and pending deletion. By providing commands or API endpoints in your container, you can track critical lifecycle stages and communicate them to other components of your infrastructure.
Lifecycle events are easy to set up, but they also have some common pitfalls. If you need more reliable calling, you can use adjacency mechanisms such as initialization and preparation probes. These are a better choice for scripts that are essential when setting up a new container environment.