Kubernetes Container lifecycle hooks
- 2021 年 3 月 4 日
- 筆記
- Kubernetes, Hook, Lifecycle
簡介
在kubernetes中,容器hooks旨在解決服務進程啟動與停止時的一些優雅操作需求。比如說進程停止時要給進程一個清理數據的時間,保證服務的請求正常結束,而不是強行中斷服務的運行,這樣在生產環境中可能會造成不優雅的結果。
截止kubernetes v1.20版本,實現了PostStart和PreStop兩種容器hooks。
如果hooks執行失敗,容器將會被kill。
容器hooks由kubelet組件管理並啟動執行。
名詞解釋
hook 鉤子,軟體行業中指程式中在某一個地方定義的預留介面,而介面的實現可以後續指定。
容器Hooks介紹
-
PostStart
PostStart hook在容器啟動的時候運行,但並不保證該hook一定會比容器指定的ENTRYPOINT命令先運行。就是說PostStart和ENTRYPOINT都會在容器啟動後運行,至於誰先運行,誰先結束,並不一定,是隨機的。如果容器啟動的時候,PostStart沒有成功,容器不會處於running狀態。 -
PreStop
PreStop會在kubelet給Pod發送TERM訊號之前執行。一般API Server會給kubelet發送結束Pod的訊號,或者Pod的liveness/startup探針失敗,或其它原因導致Pod失敗,kubelet會嘗試發送TERM訊號給Pod里主進程。如果PreStop存在,kubelet則會優先啟動PreStop,待PreStop結束之後再發送TERM訊號給Pod。但從API Server將Pod標記為Terminating狀態開始,整個Pod停止時間不能超過terminationGracePeriodSeconds所設置的時間,如果超過,kubelet需要發送KILL訊號給Pod所有的進程。
舉例:
如果一個Pod設置terminationGracePeriodSeconds=60,PreStop執行需要55s,服務進程停止需要10s。API Server首先將需要停止的Pod標記為Terminating狀態,並且開始計算terminationGracePeriodSeconds時間。kubelet開始啟動PreStop,等待55s後執行完畢,kubelet給Pod的主進程發送TERM訊號,這時主進程開始清理退出,5s之後,terminationGracePeriodSeconds時間到達,kubelet將發送KILL訊號給Pod所有進程,強制停止。這一通操作之後,發現主服務進程沒有清理完畢就被強制停止了。面對這種情況,我們需要增加terminationGracePeriodSeconds=65。
Hooks類型
Exec 指定一個可執行命令或腳本,在容器內執行
HTTP 發送一個http請求給容器,由kubelet發送請求
Hooks執行的次數
hook至少會調用一次,意思說如果有多個觸發事件,hooks可能會被調用多次。
一般情況下hooks只會調用一次,只在很少的異常時候才會調用多次。比如在Pod停止的過程中kubelet被重啟,重啟後的kubelet會再次發送hooks調用。
Debug Hooks
PostStart執行失敗時會記錄FailedPostStartHook事件,PreStop執行失敗時會記錄FailedPreStopHook事件。可以通過kubectl describe pod <pod_name>查看。
容器Hooks配置示例
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
