Kubernetes中Pod生命週期
在 Kubernetes
中Pod
是容器管理的最小單位, 有著各種各樣的Pod
管理器. 那麼一個Pod
從啟動到釋放, 在這期間經歷了哪些過程呢?
Pod
自開始建立, 到正常執行, 再到釋放, 其時間跨度及經歷的階段大致如下:
說一下各個階段的作用以及是為了解決什麼問題. 容器排程和下載映象的過程就忽略了, 也沒什麼好說的.
init
在Pod
啟動一個容器時, 可以有一組init
容器先行啟動(當然也可以沒有), 這些init
容器會依次執行, 且前一個成功之後, 後一個才會執行. 同時還會監控init
容器的退出狀態, 若init
容器異常退出, 則會根據配置restartPolicy
的重啟策略選擇重新啟動或退出(這裡的退出, 說明Pod
pod.spec.initContainers
進行配置, 其配置項與containers
相同
init
容器可應用與如下場景:
- 可以將服務的建立和部署進行解耦. 以防止主容器過於臃腫
- 檢測依賴. 比如服務 A 必須要等服務 B 啟動成功之後才能執行, 那麼就可以在服務 A 的 init 階段進行迴圈檢測等待, 直到服務 B 啟動成功了, 才開始啟動服務 A
- 具有訪問
Secret
的許可權.Secret
是用來儲存一些敏感資料的, 會進行加密處理. 主容器是沒有許可權訪問的, 這也很好理解, 如果一個容器被攻破了, 如果能夠拿到Secret
的資料, 很可能會導致一串服務都被攻破. 而init
Pod
提供服務之前就退出了, 可以提高資料的安全. - 等等
Pod
在init
容器啟動完成之前, 是不會對外提供服務的, 其狀態一直為Pending
start/stop
容器啟動和釋放時執行的鉤子. 通過配置檔案的pod.spec.containers.lifecycle.postStart
和pod.spec.containers.lifecycle.preStop
進行配置. 配置相同, 這裡用postStart
舉例了. 具體配置可通過kubectl explain pod.spec.containers.lifecycle.postStart
檢視, 官方文件很詳細.
# 執行一組命令 postStart: command: ["/bin/sh", "-c", "sleep 1"] --- # 呼叫 http 介面通知 postStart: host: baidu.com path: /start port: 80
readiness
既就緒探針. 檢測容器中的服務是否已經啟動成功並可以對外提供訪問了. 只有檢測成功後, 才會將狀態改為就緒狀態(Running). 定義在配置檔案的pod.spec.containers.readinessProbe
位置. 預設success
readiness
是為了解決服務的啟動時間問題, 比如容器已經啟動成功了, 但是提供服務的程序還沒有啟動完畢, 此時對外提供服務的話就會有問題. Kubernetes
提供瞭如下三種探針:
- ExecAction: 在容器中執行指定命令. 若命令返回0, 則成功
- TCPSocketAction: 對指定埠進行 TCP 檢查, 若埠開放, 則認為成功
- HTTPGetAction: 對指定埠進行 HTTP Get 請求, 若響應碼區間為[200, 400), 則認為成功
其配置檔案大致如下:
# 命令探針
readinessProbe:
exec:
command: ["cat", "/tmp/file"]
# 以下這些欄位為通用欄位, 下面不再重複
# 探針失敗的最大重試次數, 超過這個次數則認為本次探測失敗, 容器啟動失敗. 預設3
failureThreshold: 3
# 探測的迴圈週期, n秒後進行下一次探測. 與 failureThreshold 配合確定啟動時間. 預設10s
periodSeconds: 1
# 執行第一次探測前需要等待5s. 預設0s
initialDelaySeconds: 5
# 探測超時時間. 預設1s
timeoutSeconds: 1
# 當探測失敗後, 需要連續探測成功3次才認為成功. 預設1
successThreshold: 3
# 當探測失敗後, 優雅釋放可等待的時間. 超過則會被強制釋放
terminationGracePeriodSeconds: 5
---
# tcp 探針
readinessProbe:
tcpSocket:
host: baidu.com
port: 80
---
# http 探針
readinessProbe:
httpGet:
host: baidu.com
path: /
port: 80
# 設定請求的 header, 是個物件陣列
httpHeaders:
- name: headerName
value: headerValue
# 請求方式. HTTP 或 HTTPS. 預設 HTTP
scheme: HTTP
liveness
既存活探測, 在容器執行的這段時間, 探測容器是否存活, 若已經無法提供服務, 則需要重啟容器. 定義在配置檔案的pod.spec.containers.livenessProbe
位置. 其配置項與readiness
相同, 不再贅述. 預設success
在容器執行過程中, 可能容器還活著, 但裡面提供服務的程序已經死了(例如死鎖). 這時容器其實已經無法對外提供服務了. 需要這樣一種機制來檢測是否還能正常提供服務.
注意, liveness
並不是在readiness
探測完畢後才會啟動.而是幾乎同時啟動, 而liveness
探測失敗後, 會導致容器重啟, 因此liveness
的initialDelaySeconds
配置就需要稍微花點心思了, 要延時一些時間, 等待服務啟動成功後再開始. 否則可能導致readiness
還沒有完成探測任務, 就被liveness
探測失敗而重啟了.
startup
上面說liveness
與readiness
是同時執行的, 通過配置liveness
的initialDelaySeconds
引數來等待. 但對於一些服務, 我們並不能確定其啟動需要多久呀, 如果一味延長等待時間就太不划算了.
而startup
就是為了解決liveness
與readiness
執行順序的問題, 將服務就緒探測和服務的存活探測徹底分開. 定義在配置檔案的pod.spec.containers.startupProbe
位置, 探針項與readiness
相同.
startup
探針會在探測成功後, 再將探測任務交由後續的探測任務. 預設success
所以一般使用liveness
和startup
配合探測即可, readiness
貌似沒有什麼用武之地了.