Kubernetes Pod鉤子
- 2020 年 4 月 11 日
- 筆記
1、Pod容器鉤子最終目的
之前在生產環境中使用dubbo框架,由於服務更新的過程中,容器直接被停止了,部分請求仍會被分發到終止的容器,導致有用戶會訪問服務出現500錯誤,這部分錯誤請求數據佔用的比較少,因為Pod是滾動一對一更新。由於這個問題出現了,考慮使用優雅的終止方式,將錯誤請求將至到最低,直至滾動更新完全不會影響到用戶。
簡單分析一下優雅的停止Pod
微服務中,網關會把流量分配給每個Pod節點,如:我們線上更新Pod的時候
1、如果我們直接把Pod給殺死,那這部分流量就無法得到正確的處理,會影響到部分用戶訪問,一般來說網關或者註冊中心會將我們的服務保持一個心跳,過了心跳超時後就會自動摘除我們的服務,但是有一個問題就是超時時間可能是10s、30s、甚至是60s,雖然不會大規模的影響我們業務系統,但是一定會對用戶產生輕微的抖動。
2、如果我們在停止服務前執行一條命令,通知網關或註冊中心這台Pod,即服務進行下線,那麼註冊中心就會標記這個Pod/服務已經下線,不進行流量轉發,用戶也就不會有任何的影響,這就是優雅停止,將滾動更新的影響最小化。
2、何為Pod容器鉤子
Kubernetes最小調度單位為Pod,它為Pod中的容器提供了生命周期鉤子,鉤子能夠使得容器感知其生命周期內的所有事件,並且當相應的生命周期的鉤子被調用時運行執行的程式碼,而Pod 鉤子是由Kubelet發起的。
容器鉤子兩類觸發點:
- PostStart:容器創建後
- PreStop:容器終止前
PostStart
這個鉤子在容器創建後立即執行。
但是,並不能保證鉤子將在容器ENTRYPOINT之前運行。
沒有參數傳遞給處理程式。
容器ENTRYPOINT和鉤子執行是非同步操作。
如果鉤子花費太長時間以至於容器不能運行或者掛起, 容器將不能達到running狀態
PreStop
這個鉤子在容器終止之前立即被調用。
它是阻塞的,意味著它是同步的, 所以它必須在刪除容器的調用發出之前完成
如果鉤子在執行期間掛起, Pod階段將停留在running狀態並且永不會達到failed狀態。
如果PostStart或者PreStop鉤子失敗, 容器將會被kill。
用戶應該使他們的鉤子處理程式儘可能的輕量。
3、基於PostStart演示
如果PostStart或者PreStop鉤子失敗,它會殺死容器。所以我們應該讓鉤子函數儘可能的輕量。當然有些情況下,長時間運行命令是合理的,比如在停止容器之前預先保留狀態。
1.我們echo一段話追加到/tmp/message,在Pod啟動前操作
cat >>hook_test.yaml<<EOF apiVersion: v1 kind: Pod metadata: name: hook-demo1 spec: containers: - name: hook-demo1 image: nginx lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo 1 > /tmp/message"] EOF
2.應用hook_test.yaml
$ kubectl apply -f hook_test.yaml
3.可以通過下面查看結果
$ kubectl get pods | grep hook-demo1 hook-demo1 1/1 Running 0 49s $ kubectl exec -it hook-demo1 /bin/bash root@hook-demo1:/# cat /tmp/message 1
4、基於PreStop演示
下面示例中,定義一個Nginx Pod,設置了PreStop鉤子函數,即在容器退出之前,優雅的關閉Nginx。
cat >>hook_test.yaml<<EOF apiVersion: v1 kind: Pod metadata: name: hook-demo2 spec: containers: - name: hook-demo2 image: nginx lifecycle: preStop: exec: command: ["/usr/sbin/nginx","-s","quit"] EOF
5、優雅停止Java應用
我們都知道java應用的啟動和停止都需要時間,為了更加優雅的停止,可以通過pidof
獲取到java進程ID,循環通過kill
命令往PID發送SIGTERM訊號。
lifecycle: preStop: exec: command: ["/bin/bash","-c","PID=`pidof java` && kill -SIGTERM $PID && while ps -p $PID > /dev/null;do sleep 1; done;"]