大部分的應用程序咱們在部署的時候都會適當的添加監控,對於運行載體容器則更應該如此。kubernetes提供了 liveness probes來檢查咱們的應用程序。它是由節點上的kubelet按期執行的。html
首先說一下Pod的整個生命階段:java
對於Liveness Probe的結果也有幾個固定的可選項值:nginx
Liveness Probe的種類:docker
當前kubelet擁有兩個檢測器,他們分別對應不通的觸發器(根據觸發器的結構執行進一步的動做):後端
對於Liveness Probe和Readiness Probe用法都同樣,擁有相同的參數和相同的監測方式。api
當前對每個Container均可以設置不一樣的restartpolicy,有三種值能夠設置:網絡
若是restartpolicy沒有設置,那麼默認值是Always。若是container須要重啓,僅僅是經過kubelet在當前節點進行container級別的重啓。app
最後針對Liveness Probe如何使用,請看下面的幾種方式,若是要使用ReadinessProbe只須要將livenessProbe修改成readinessProbe便可:socket
apiVersion: v1
kind: Pod
metadata:
name: probe-exec
namespace: coocla
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
exec:
command:
- cat
- /tmp/health
initialDelaySeconds: 5
timeoutSeconds: 1
---
apiVersion: v1
kind: Pod
metadata:
name: probe-http
namespace: coocla
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
httpGet:
path: /
port: 80
host: www.baidu.com
scheme: HTTPS
initialDelaySeconds: 5
timeoutSeconds: 1
---
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
namespace: coocla
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
關於kubectl資源建立的語法能夠參考: kubernetes技術學習之—Construct語法tcp
咱們使用上面的construct建立資源:
kubectl create -f probe.yaml
kubectl get event
在kubernetes中,kubelet經過liveness探針決定在什麼時候從新啓動容器。例如,容器中的應用運行時進入死鎖狀態,liveness探針對容器進行健康檢查時檢測到這種狀況,那麼探針檢測失敗,則kubelet就會從新啓動容器。能夠看到從新啓動並無從根本上解決死鎖問題,只是忽略了問題使容器繼續運行。
kubelet經過readiness類型的探針決定container是否準備就緒處理流量,當pod中的全部container所有處於ready狀態時,pod被認爲能夠對外提供服務。readiness探針的典型應用是控制pod是否做爲service的backend。如下示例中都沒有爲容器指定"restart policy",因此均採用默認值"Always"。
有些程序由於長時間運行而進入崩壞的狀態,其中的一個解決辦法是從新啓動,liveness探針專門用來解決此類問題。
下例是運行一個容器的pod,容器image是k8s.gcr.io/busybox,配置文件以下:
apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: k8s.gcr.io/busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
從以上配置文件看出,pod包含一個容器。每隔 periodSeconds秒執行一次liveness探針診斷,initialDelaySeconds表示kubelet在啓動容器後首次執行探針診斷的延遲時間。探針的具體實現是在容器內部執行cat /tmp/healthy命令,若是命令退出碼是0表示容器存活健康,若是非0則kubelet從新啓動容器。
容器啓動之後執行以下指令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
建立pod:
kubectl create -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
在30秒以內查看pod事件:
kubectl describe pod liveness-exec
輸出以下:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
35秒之後,再次查看pod事件,輸出以下:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
發現探針診斷失敗事件,此時容器被從新啓動,再等待30秒,肯定容器被重啓:
kubectl get pod liveness-exec
輸出結果:
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
restart次數被加1。
如下是HTTP GET類型的liveness探針示例,pod包含一個容器,image是k8s.gcr.io/liveness:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
注意探針中path、port、httpHeader的配置,kubelet經過這些信息,構建http get請求,並經過kuelet運行的網絡將請求發送到容器的指定端口、路徑上。當應答狀態碼大於等於200小於400時表示探針診斷經過,其它狀態碼錶示失敗。kubelet殺死容器而後從新啓動。
TCP類型是最簡單的探針,kubelet嘗試打開容器上的某個端口,若是鏈接成功創建則診斷經過,不然失敗,示例配置以下:
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
在定義探針時使用命名端口,示例以下:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
容器有時候會暫時沒法對外提供服務,好比容器在啓動階段須要下載大量數據配置文件等,此時容器沒法對外提供服務但又不能殺死它,而用戶也但願此時容器不要授受來自service的流量 ,readiness類型探針專門處理此種狀況。
readiness probe與liveness probe的配置相似,惟一不一樣的只是字段名稱,將livenessProbe換成readinessProbe,以下:
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
readiness probe暫時阻止pod成爲service的backend,當診斷經過時再將pod加入到相應service的後端。liveness探針影響的是單個容器,但readiness探針影響的是整個pod,即若是pod中有多個容器,只要有一個容器的readiness探針診斷失敗,那麼整個pod都會處於unready狀態。