只要將pod調度到某個節點,Kubelet就會運行pod的容器,若是該pod的容器有一個或者全部的都終止運行(容器的主進程崩潰),Kubelet將重啓容器,因此即便應用程序自己沒有作任何特殊的事,在Kubemetes中運行也能自動得到自我修復的能力。html
自動重啓容器以保證應用的正常運行,這是使用Kubernetes的優點,不過在某些狀況,即便進程沒有崩潰,有時應用程序運行也會出錯。默認狀況下Kubernetes只是檢查Pod容器是否正常運行,但容器正常運行並不必定表明應用健康,在如下兩種狀況下Kubernetes將不會重啓容器:node
- 1.訪問Web服務器時顯示500內部錯誤
- 該報錯多是系統超載,也多是資源死鎖,不過此時httpd進程依舊運行,重啓容器多是最直接有效的辦法。
- 2.具備內存泄漏的Java應用程序將開始拋出OutOfMemoryErrors
- 此時JVM進程會一直運行,Kubernetes也不會重啓容器,但此時對應用來說是異常的。
此時能夠考慮從外部檢查應用程序的運行情況:nginx
Kubemetes能夠經過存活探針(liveness probe)檢查容器是否還在運行。能夠爲pod中的每一個容器單獨指定存活探針。若是探測失敗,Kubemetes將按期執行探針並從新啓動容器。後端
Kubernetes 支持三種方式來執行探針:api
exec類型的探針經過在目標容器中執行由用戶自定義的命令來判斷容器的監控狀態,若命令狀態返回值爲0則表示「成功」經過檢測,其餘值則均爲「失敗」狀態。bash
[root@master ~]# more liveness-exec.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness-exec name: liveness-exec spec: restartPolicy: OnFailure containers: - name: liveness-exec image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: ["test","-e","/tmp/healthy"] initialDelaySeconds: 5 #探測延時時長,第一次探測前等待5秒,默認爲0 periodSeconds: 5 #每5秒執行一次liveness探測,默認值10秒,最小1秒 timeoutSeconds: 2 #超長時長,默認爲1s,最小值也爲1s failureThreshold: 3 #處於成功狀態時,探測操做至少連續多少次的失敗才被視爲檢測不經過,默認爲3,最小爲1 [root@master ~]# kubectl apply -f liveness-exec.yaml pod/liveness-exec created
[root@master ~]# kubectl get po -o wide [root@master ~]# kubectl describe po liveness-exec
pod運行正常,10秒內文件/tmp/healthy還存在,probe檢測正常。服務器
第15秒,probe再次檢測,因爲文件被刪,檢測失敗,此後容器會進行屢次重啓操做。app
基於HTTP的探測(HTTPGetAction)向目標容器發起一個HTTP請求,根據其相應碼進行結果斷定,響應碼如2xx或3xx時表示檢測經過。curl
[root@master ~]# more liveness-http.yaml apiVersion : v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness-http image: nginx ports: - name: http containerPort: 80 lifecycle: postStart: exec: command: ["/bin/sh" ,"-c","echo liveness-http test > /usr/share/nginx/html/health"] livenessProbe: httpGet: path: /health port: http scheme: HTTP [root@master ~]# kubectl apply -f liveness-http.yaml pod/liveness-http created
[root@master ~]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES liveness-http 1/1 Running 0 5s 10.244.2.206 node02 <none> <none> [root@master ~]# curl 10.244.2.206/health liveness-http test
[root@master ~]# kubectl exec -it liveness-http rm /usr/share/nginx/html/health
探測失敗,返回碼404,重啓容器。tcp
基於TCP的存活性探測(TCPSocketAction)用於向容器的特定端口發起TCP請求並嘗試創建鏈接,鏈接成功即爲經過檢測。
```bash [root@master ~]# more liveness-tcp.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-tcp spec: containers: - name: liveness-tcp image: nginx ports: - name: http containerPort: 80 livenessProbe: tcpSocket: port: http [root@master ~]# kubectl apply -f liveness-tcp.yaml pod/liveness-tcp created [root@master ~]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES liveness-tcp 1/1 Running 0 4s 10.244.2.217 node02 <none> <none> [root@master ~]# curl 10.244.2.217:80
[root@master ~]# kubectl exec -it liveness-tcp -- sed -i 's/^ *listen 80/ listen 81/g' /etc/nginx/conf.d/default.conf
若是kubectl exec在容器內執行命令時若是帶參數則需加上'--'
[root@master ~]# kubectl exec -it liveness-tcp -- nginx -s reload
[root@master ~]# kubectl describe po liveness-tcp
80是nginx的默認端口,開始發起TCP鏈接的端口也是80,默認端口改爲81後鏈接報錯,容器重啓。
用於容器的自定義準備狀態檢查。若是ReadinessProbe檢查失敗,Kubernetes會將該Pod從服務代理的分發後端去除,再也不分發請求給該Pod。
Pod對象啓動後,容器應用一般須要一段時間才能完成其初始化過程,例如加載配置或數據,甚至有些程序須要運行某類的預熱過程,若在此階段完成以前接入客戶端的請求,勢必會由於等待過久而影響用戶體驗,這時就須要就緒探針。
若是沒有將就緒探針添加到pod中,它們幾乎會當即成爲服務端點。若是應用程序須要很長時間才能開始監聽傳入鏈接,則在服務啓動但還沒有準備好接收傳入鏈接時,客戶端請求將被轉發到該pod。所以,客戶端會看到"鏈接被拒絕"類型的錯誤。
與存活探針機制相同,就緒探針也支持Exec、HTTP GET和TCP Socket三種探測方式,且各自的定義機制相同,將容器定義中的livenessProbe字段名替換爲readinessProbe便可定義出就緒探測的配置,這裏再也不贅述。
本文以exec方式爲例實踐
[root@master ~]# more liveness-exec.yaml apiVersion: v1 kind: Pod metadata: labels: test: liveness-exec name: liveness-exec spec: restartPolicy: OnFailure containers: - name: liveness-exec image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: ["test","-e","/tmp/healthy"] initialDelaySeconds: 5 #探測延時時長,第一次探測前等待5秒,默認爲0 periodSeconds: 5 #每5秒執行一次liveness探測,默認值10秒,最小1秒 timeoutSeconds: 2 #超長時長,默認爲1s,最小值也爲1s failureThreshold: 3 #處於成功狀態時,探測操做至少連續多少次的失敗才被視爲檢測不經過,默認爲3,最小爲1 [root@master ~]# kubectl apply -f readiness-exec.yaml pod/readiness-exec created
[root@master ~]# kubectl get po readiness-exec -w NAME READY STATUS RESTARTS AGE readiness-exec 0/1 ContainerCreating 0 2s readiness-exec 0/1 Running 0 3s readiness-exec 1/1 Running 0 9s readiness-exec 0/1 Running 0 24s
'-w'選項能夠監視pod資源變更,剛開始儘管pod處於Running狀態,但知道就緒探測命令執行成功後pod資源才ready
剛開始處於'預熱'階段,pod爲running狀態但不可用;當10秒後(initialDelaySeconds + periodSeconds),readinessprobe開始第一次探測,成功後pod處於ready狀態,45秒後(sleep30 + periodSeconds * failureThreshold)探測失敗,pod再次爲running但not ready狀態。