0. 參考
- Kubernetes容器生命周期 —— 鉤子函數詳解(postStart、preStop) - 人艱不拆_zmc - 博客園
- 詳解Kubernetes Pod優雅退出 - 人艱不拆_zmc - 博客園
1. Kubernetes 生命周期鉤子概述
在 Kubernetes 中,生命周期鉤子(Lifecycle Hooks) 是容器啟動和終止時執行的自定義操作。它們允許你在容器的生命周期中插入“定制邏輯”,比如初始化、資源清理、通知外部系統等。
Kubernetes 為每個容器提供兩個主要的生命周期鉤子(hooks):
生命周期鉤子 | 觸發時機 | 作用示例 |
---|---|---|
postStart | 容器啟動完成后立即 | 日志初始化、加載緩存、通知系統 |
preStop | 容器被終止前 | 優雅下線、關閉連接、清理資源等 |
2. 使用示例
lifecycle:postStart:exec:command: ["/bin/sh", "-c", "echo Container started at $(date) >> /var/log/start.log"]preStop:exec:command: ["/bin/sh", "-c", "echo Shutting down >> /var/log/shutdown.log && sleep 10"]
3. 生命周期流程圖(簡化)
Pod 創建└──> 容器啟動└──> postStart Hook└──> 運行主進程...└──> SIGTERM (優雅終止)└──> preStop Hook└──> 容器停止
4. 應用場景舉例
Hook 類型 | 應用場景 |
---|---|
postStart | - 通知注冊中心上線 - 初始化緩存 - 自定義日志記錄 |
preStop | - 通知下游服務斷開連接 - 等待請求處理完畢 - 注銷注冊中心 |
5. 注意事項
- 兩個鉤子都 運行在容器內,使用
exec
。 postStart
會 阻塞容器運行(直到命令完成);若失敗會導致容器崩潰。preStop
默認最多等待 30 秒(由terminationGracePeriodSeconds
控制)。- 不能保證 preStop 一定成功執行(例如容器被 kill -9)
6. 總結理解
生命周期鉤子 = 容器級別的定制啟動/退出腳本,用于插入優雅上線、下線、清理、注冊、通知等邏輯,是構建高可用服務的重要工具之一。
7. 示例1
? 目標場景
當容器被終止時,執行以下步驟:
- 通知外部系統(通過 curl 發出“下線”請求)
- 等待 5 秒,讓請求完成
- 再由 Kubernetes 終止容器
🧩 示例:使用 preStop
實現優雅下線
apiVersion: apps/v1
kind: Deployment
metadata:name: graceful-shutdown-demo
spec:replicas: 1selector:matchLabels:app: graceful-demotemplate:metadata:labels:app: graceful-demospec:terminationGracePeriodSeconds: 10 # 容器 SIGTERM 后有最多 10 秒來執行 preStopcontainers:- name: appimage: busyboxcommand: ["/bin/sh", "-c", "while true; do echo 'Running...'; sleep 5; done"]lifecycle:preStop:exec:command:- /bin/sh- -c- |echo "[preStop] Notifying external system..."curl -X POST http://example.com/deregister -d 'pod=graceful-demo'echo "[preStop] Waiting for in-flight requests to complete..."sleep 5
🔍 關鍵點說明
字段/參數 | 含義 |
---|---|
preStop.exec.command | 容器內執行 shell 腳本,通知外部系統并等待 |
terminationGracePeriodSeconds | 容器被終止前最大等待時間(默認 30 秒) |
curl -X POST | 模擬通知外部系統(如服務注冊中心) |
sleep 5 | 給上游時間處理關閉流程,確保不中斷服務 |
8. 示例2
? 示例:包含 postStart
和 preStop
的容器
yaml復制編輯
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:terminationGracePeriodSeconds: 15 # 為 preStop 提供充足時間containers:- name: demo-containerimage: busyboxcommand: ["/bin/sh", "-c", "echo 'App running...'; sleep 3600"]lifecycle:postStart:exec:command:- /bin/sh- -c- |echo "[postStart] Initializing container..." >> /tmp/startup.logdate >> /tmp/startup.logpreStop:exec:command:- /bin/sh- -c- |echo "[preStop] Cleaning up before shutdown..." >> /tmp/shutdown.logsleep 5 # 模擬等待資源釋放或通知外部系統
🧠 解釋每一部分
🔹 postStart
- 觸發時機:容器啟動完成后立即執行
- 作用:
- 可做初始化動作,如寫日志、預熱緩存、啟動守護進程等
- 示例邏輯:
- 在
/tmp/startup.log
記錄“啟動”信息和時間戳
- 在
🔹 preStop
- 觸發時機:容器收到終止信號(如刪除 Pod 或更新鏡像)前執行
- 作用:
- 用于優雅下線,如關閉連接、注銷注冊、等待請求處理完畢等
- 示例邏輯:
- 寫一條“即將關閉”的日志
sleep 5
模擬清理或等待請求完成
?? terminationGracePeriodSeconds
- 告訴 Kubelet:給容器最多
15s
時間完成preStop
- 若
preStop
沒完成,時間一到仍會強制終止容器