Kubernetes Lifecycle
You probably read or heard in the cloud native world we are supposed to gracefully shutdown. What does it mean really? I mean if something bad happened and we had to exit the container what can we really do? Thats where lifecycle hooks are pretty useful.
Lifecycle Hooks
There are two hooks that are exposed to containers
PostStart
PreStop
PostStart
This hook executes right after the container is created. It doesn't however guarantee execution before container ENTRYPOINT. This does not take any parameter.
PreStop
This hook is called right before a container is terminated.
We have a example app that we can deploy
kubectl apply -f k8s/lifecycle/deployment-lifecycle.yamlWe will see that the application is stuck at container creating for about 30 seconds. If you cat the yaml file we just ran,
...
env:
- name: WAIT_FOR_POST_START
value: "true"
imagePullPolicy: Always
lifecycle:
postStart:
exec:
command:
- sh
- -c
- sleep 30 && echo "Wake up!" > /tmp/poststart
preStop:
httpGet:
port: 8080
path: shutdown
...So for post start we are running a shell script that has a 30 second sleep than it creates a file. In our application we check for the existence of the file before we start our server. You can read the application code at src/lifecycle/main.go .
At this point it will be useful to be able to split our terminal window.
If you are running this workshop on the cloudshell you can use the tmux shorcut
ctrl+b %to split the screen. And to move between panes usectrl+b <arrow>
On one tab lets run the log to see whats going on
kubectl logs -f -l name=lifecycle-podThis would print the log from the poststart state
2019/08/01 05:51:52 file creation has not completed yet...
2019/08/01 05:51:57 file creation has not completed yet...
2019/08/01 05:52:02 file creation has not completed yet...
2019/08/01 05:52:07 file creation has not completed yet...
2019/08/01 05:52:12 file creation has not completed yet...
2019/08/01 05:52:17 file creation has not completed yet...
2019/08/01 05:52:22 file creation has not completed yet...
2019/08/01 05:52:27 file created. starting application.
2019/08/01 05:52:27 starting application in por 8080We also have the preStop hook set. We set that to a http call to the path /shutdown which we made in our code and simulate some clean up work.
On the other pane
kubectl delete po -l name=lifecycle-podWe will see in our log the "cleanup work" we simulate in our code. It will take about 10 seconds you will the pod in terminating state while that happens. In our log we should see
...
2019/08/01 05:52:27 file created. starting application.
2019/08/01 05:52:27 starting application in por 8080
2019/08/01 05:53:54 shutdown initiated!
2019/08/01 05:53:54 doing some cleanup work
2019/08/01 05:54:04 done!OS-Signals
Sigterm
When a pod is getting evicted or user calls delete on the pod or the deployment the sigterm signal is sent to the container. We can actually listen for the sigterm signal and do things with it.
Lets deploy the pod with sigterm catch enabled.
kubectl apply -f k8s/lifecycle/deployment-sigterm.yamlThe code that corresponds to this version of pod is available at src/os-signal/main.go . In the application we basically listen for os signals, and when the sigterm signal comes in we start our "clean up" process. Which right now is just sleeping for 10 seconds and exiting.
To see this in action,
Lets first start a tail on the log
kubectl logs -f -l name=signal-podWe should see
2019/08/01 05:56:40 awaiting signalThen run on the other pane
kubectl delete po -l name=signal-podYour delete command would seemingly hang until the whole delete process ends.
In the log pane we will see the clean up messages. This means we caught the sigterm signal.
2019/08/01 05:58:39 Doing all sorts of cleanup work!
2019/08/01 05:58:49 exitingSigkill
We could also choose to ignore the sigterm signal by caching and not exiting. We can see how that is achieved by deploying
kubectl apply -f k8s/lifecycle/deployment-rouge.yamlLets see the log
kubectl logs -f -l name=rouge-podThis looks just like our previous pod
2019/08/01 06:01:37 awaiting signalBut this pod is rouge. When a delete command is sent it just ignores it.
kubectl delete po -l name=rouge-podOn the log you will see the print out. The delete command would just hang there.
2019/08/01 06:01:57 going rouge
2019/08/01 06:01:57 i am invincibleBut fear not! Kubernetes scheduler has a way to deal with such issue as well. After a sigterm is sent if the pod does not exit in 30 second (default) or a time set by the operator sigkill command is sent to the container. This is the kill -9 for those of us familiar with the linux command. A process has no way to stop and sigkill and the process is terminated.
Last updated
Was this helpful?