存活探針
Kubernetes提供了自愈的能力,具體就是能感知到容器崩潰,然後能夠重啓這個容器。但是有時候例如Java程序內存泄漏了,程序無法正常工作,但是JVM進程卻是一直運行的,對於這種應用本身業務出了問題的情況,Kubernetes提供了Liveness Probe機制,通過檢測容器響應是否正常來決定是否重啓,這是一種很好的健康檢查機制。
毫無疑問,每個Pod最好都定義Liveness Probe,否則Kubernetes無法感知Pod是否正常運行。
Kubernetes支持如下三種探測機制。
- HTTP GET:向容器發送HTTP GET請求,如果Probe收到2xx或3xx,說明容器是健康的。
- TCP Socket:嘗試與容器指定端口建立TCP連接,如果連接成功建立,說明容器是健康的。
- Exec:Probe執行容器中的命令並檢查命令退出的狀態碼,如果狀態碼爲0則說明容器是健康的。
與存活探針對應的還有一個就緒探針(Readiness Probe),將在就緒探針(Readiness Probe)中會詳細介紹。
HTTP GET
HTTP GET方式是最常見的探測方法,其具體機制是向容器發送HTTP GET請求,如果Probe收到2xx或3xx,說明容器是健康的,定義方法如下所示。
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- name: liveness
image: nginx:alpine
livenessProbe: # liveness probe
httpGet: # HTTP GET定義
path: /
port: 80
imagePullSecrets:
- name: default-secret
創建這個Pod。
$ kubectl create -f liveness-http.yaml
pod/liveness-http created
如上,這個Probe往容器的80端口發送HTTP GET請求,如果請求不成功,Kubernetes會重啓容器。
查看Pod詳情。
$ kubectl describe po liveness-http
Name: liveness-http
......
Containers:
liveness:
......
State: Running
Started: Mon, 03 Aug 2020 03:08:55 +0000
Ready: True
Restart Count: 0
Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vssmw (ro)
......
可以看到Pod當前狀態是Running,Restart Count爲0,說明沒有重啓。如果Restart Count不爲0,則說明已經重啓。
TCP Socket
TCP Socket嘗試與容器指定端口建立TCP連接,如果連接成功建立,說明容器是健康的,定義方法如下所示。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-tcp
spec:
containers:
- name: liveness
image: nginx:alpine
livenessProbe: # liveness probe
tcpSocket:
port: 80
imagePullSecrets:
- name: default-secret
Exec
Exec即執行具體命令,具體機制是Probe執行容器中的命令並檢查命令退出的狀態碼,如果狀態碼爲0則說明健康,定義方法如下所示。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: nginx:alpine
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe: # liveness probe
exec: # Exec定義
command:
- cat
- /tmp/healthy
imagePullSecrets:
- name: default-secret
上面定義在容器中執行cat /tmp/healthy命令,如果成功執行並返回0,則說明容器是健康的。上面定義中,30秒後命令會刪除/tmp/healthy,這會導致Liveness Probe判定Pod處於不健康狀態,然後會重啓容器。
Liveness Probe高級配置
上面liveness-http的describe命令回顯中有如下行。
Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
這一行表示Liveness Probe的具體參數配置,其含義如下:
- delay:延遲,delay=0s,表示在容器啓動後立即開始探測,沒有延遲時間
- timeout:超時,timeout=1s,表示容器必須在1s內進行響應,否則這次探測記作失敗
- period:週期,period=10s,表示每10s探測一次容器
- success:成功,#success=1,表示連續1次成功後記作成功
- failure:失敗,#failure=3,表示連續3次失敗後會重啓容器
以上存活探針表示:容器啓動後立即進行探測,如果1s內容器沒有給出迴應則記作探測失敗。每次間隔10s進行一次探測,在探測連續失敗3次後重啓容器。
這些是創建時默認設置的,您也可以手動配置,如下所示。
apiVersion: v1
kind: Pod
metadata:
name: liveness-http
spec:
containers:
- image: k8s.gcr.io/liveness
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 10 # 容器啓動後多久開始探測
timeoutSeconds: 2 # 表示容器必須在2s內做出相應反饋給probe,否則視爲探測失敗
periodSeconds: 30 # 探測週期,每30s探測一次
successThreshold: 1 # 連續探測1次成功表示成功
failureThreshold: 3 # 連續探測3次失敗表示失敗
initialDelaySeconds一般要設置大於0,這是由於很多情況下容器雖然啓動成功,但應用就緒也需要一定的時間,需要等就緒時間之後才能返回成功,否則就會導致probe經常失敗。
另外failureThreshold可以設置多次循環探測,這樣在實際應用中健康檢查的程序就不需要多次循環,這一點在開發應用時需要注意。
配置有效的Liveness Probe
- Liveness Probe應該檢查什麼
一個好的Liveness Probe應該檢查應用內部所有關鍵部分是否健康,並使用一個專有的URL訪問,例如 /health,當訪問 /health 時執行這個功能,然後返回對應結果。這裏要注意不能做鑑權,不然 probe 就會一直失敗導致陷入重啓的死循環。
另外檢查只能限制在應用內部,不能檢查依賴外部的部分,例如當前端web server不能連接數據庫時,這個就不能看成web server不健康。
- Liveness Probe必須輕量
Liveness Probe不能佔用過多的資源,且不能佔用過長的時間,否則所有資源都在做健康檢查,這就沒有意義了。例如Java應用,就最好用HTTP GET方式,如果用Exec方式,JVM啓動就佔用了非常多的資源。