k8s之Pod健康檢測
LivenessProbe:用於判斷容器是否存活,即running狀態,如果LivenessProbe探針探測到容器不健康,則kubelet將kill掉容器,並根據容器的重啟策略是否重啟,如果一個容器不包含LivenessProbe探針,則Kubelet認為容器的LivenessProbe探針的返回值永遠成功。
ReadinessProbe探針:用於判斷容器是否啟動完成,即容器的Ready是否為True,可以接收請求,如果ReadinessProbe探測失敗,則Pod的狀態將被修改,控制器將此Pod的Endpoint從 對應的service的Endpoint列表中移除,從此以後不再調度此Pod上。
每類探針都支持三種探測方法:
- exec: 通過執行命令來檢查服務是否正常,針對復雜檢測或無HTTP接口的服務,如果該命令的返回值為0表示,則表示容器健康。
- httpGet:通過http請求方式檢查服務是否正常,返回200-399狀態碼則容器健康。
- tcpSocket:通過容器的IP和Port執行TCP檢查,如果能夠建立TCP連接,則表明容器健康。
探針探測的結果有以下三者之一:
- Success:Container通過了檢查。
- Failure:Container未通過檢查。
- Unknown:未能執行檢查,因此不采取任何措施。
示例一:通過exec方式做健康探測
exec-liveness.yaml 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
在該配置文件中,對容器執行livenessProbe檢查,periodSeconds字段指定kubelet每5s執行一次檢查,檢查的命令為cat /tmp/healthy,initialDelaySeconds字段告訴kubelet應該在執行第一次檢查之前等待5秒,
如果命令執行成功,則返回0,那麽kubelet就認為容器是健康的,如果為非0,則Kubelet會Kill掉容器並根據重啟策略來決定是否需要重啟。
當容器啟動時,它會執行以下命令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
對於容器的前30秒,有一個/tmp/healthy
創建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事件:
kubectl describe pod liveness-exec
在輸出的中顯示探測失敗,並且容器已被殺死並重新創建。
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秒,確認Container已重新啟動:
kubectl get pod liveness-exec
下面輸出中RESTARTS的次數已增加:
AME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
示例二:通過HTTP方式做健康檢查
pods/probe/http-liveness.yaml
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
在配置文件中,使用k8s.gcr.io/liveness鏡像,創建出一個Pod,其中periodSeconds字段指定kubelet每3秒執行一次探測,initialDelaySeconds字段告訴kubelet延遲等待3秒,探測方式為向容器中運行的服務發送HTTP GET請求,請求8080端口下的/healthz, 任何大於或等於200且小於400的代碼表示成功。任何其他代碼表示失敗。
創建此Pod
kubectl create -f https://k8s.io/examples/pods/probe/http-liveness.yaml
10秒後,查看Pod事件以驗證liveness探測失敗並且Container已重新啟動:
kubectl describe pod liveness-http
示例三:通過HTTP方式做健康檢查
Kubelet將嘗試在指定的端口上打開容器上的套接字,如果能建立連接,則表明容器健康。
pods/probe/tcp-liveness-readiness.yaml
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
TCP檢查方式和HTTP檢查方式非常相似,示例中兩種探針都使用了,在容器啟動5秒後,kubelet將發送第一個readinessProbe探針,這將連接到容器的8080端口,
如果探測成功,則該Pod將被標識為ready,10秒後,kubelet將進行第二次連接。
除此之後,此配置還包含了livenessProbe探針,在容器啟動15秒後,kubelet將發送第一個livenessProbe探針,仍然嘗試連接容器的8080端口,如果連接失敗則重啟容器。
創建:
kubectl create -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
15秒後,查看Pod事件以驗證活動探測:
kubectl describe pod goproxy
當容器有多個端口時,通常會給每個端口命名,所以在使用探針探測時,也可以直接寫自定義的端口名稱
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
ReadinessProbe探針的配置:
有的時候應用程序可能暫時無法接受請求,比如在容器應用程序啟動期間加載一些數據或配置文件,在這種情況下,不希望終止應用程序也不讓它處理請求,則使用ReadinessProbe探針。
ReadinessProbe探針探測容器是否已準備就緒,如果未準備就緒則kubernetes不會將流量轉發給此Pod。
ReadinessProbe探針的配置與livenessProbe的配置方式相似,只不過是將livenessProbe字段修改為ReadinessProbe。
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
ReadinessProbe探針的HTTP、TCP的探測方式也與livenessProbe的基本一致。
配置探針(Probe)相關屬性
探針(Probe)有許多可選字段,可以用來更加精確的控制Liveness和Readiness兩種探針的行為(Probe)
- initialDelaySeconds: Pod啟動後延遲多久才進行檢查,單位:秒
- periodSeconds: 檢查的間隔時間,默認為10,單位:秒
- timeoutSeconds,默認為1,單位秒。
- successThreshold:探測失敗後認為成功的最小連接成功次數,默認為1,在Liveness探針中必須為1,最小值為1.
- failureThreshold:探測失敗的重試次數,重試一定次數後將認為失敗,在readiness探針中,Pod會被標記為未就緒,默認為3,最小值為1。
httpGe探測方式 t有如下可選的控制字段:
- host:要連接的主機名,默認為Pod IP,可以在http request head中設置host頭部。
- scheme: 用於連接host的協議,默認為HTTP。
- path:http服務器上的訪問URI
- httpHeaders:自定義HTTP請求headers,HTTP允許重復headers.
- port: 容器上要訪問端口的號或名稱。
對於HTTP的檢查方式,Kubelet發送HTTP請求到指定的path和port, kubelet發送給host(默認為Pod IP).
k8s之Pod健康檢測