k8s實踐(五):容器探針(liveness and readiness probe)

環境說明:html

主機名 操做系統版本 ip docker version kubelet version 配置 備註
master Centos 7.6.1810 172.27.9.131 Docker 18.09.6 V1.14.2 2C2G master主機
node01 Centos 7.6.1810 172.27.9.135 Docker 18.09.6 V1.14.2 2C2G node節點
node02 Centos 7.6.1810 172.27.9.136 Docker 18.09.6 V1.14.2 2C2G node節點

 

k8s集羣部署詳見:Centos7.6部署k8s(v1.14.2)集羣
k8s學習資料詳見:基本概念、kubectl命令和資料分享
k8s高可用集羣部署詳見:Centos7.6部署k8s v1.16.4高可用集羣(主備模式)
k8s集羣高可用部署詳見:lvs+keepalived部署k8s v1.16.4高可用集羣  node

1、爲何須要容器探針

如何保持Pod健康

  只要將pod調度到某個節點,Kubelet就會運行pod的容器,若是該pod的容器有一個或者全部的都終止運行(容器的主進程崩潰),Kubelet將重啓容器,因此即便應用程序自己沒有作任何特殊的事,在Kubemetes中運行也能自動得到自我修復的能力。nginx

 

  自動重啓容器以保證應用的正常運行,這是使用Kubernetes的優點,不過在某些狀況,即便進程沒有崩潰,有時應用程序運行也會出錯。默認狀況下Kubernetes只是檢查Pod容器是否正常運行,但容器正常運行並不必定表明應用健康,在如下兩種狀況下Kubernetes將不會重啓容器:git

  • 1.訪問Web服務器時顯示500內部錯誤
  • 該報錯多是系統超載,也多是資源死鎖,不過此時httpd進程依舊運行,重啓容器多是最直接有效的辦法。
     
  • 2.具備內存泄漏的Java應用程序將開始拋出OutOfMemoryErrors
  • 此時JVM進程會一直運行,Kubernetes也不會重啓容器,但此時對應用來說是異常的。

此時能夠考慮從外部檢查應用程序的運行情況:github

  • Kubemetes能夠經過存活探針(liveness probe)檢查容器是否還在運行;
  • 經過就緒探針(readiness probe)保證只有準備好了請求的Pod才能接收客戶端請求。

2、LivenessProbe

1. 概念

  Kubemetes能夠經過存活探針(liveness probe)檢查容器是否還在運行。能夠爲pod中的每一個容器單獨指定存活探針。若是探測失敗,Kubemetes將按期執行探針並從新啓動容器。docker

Kubernetes 支持三種方式來執行探針:後端

  • exec:在容器中執行一個命令,若是命令退出碼返回0則表示探測成功,不然表示失敗
  • tcpSocket:對指定的容IP及端口執行一個TCP檢查,若是端口是開放的則表示探測成功,不然表示失敗
  • httpGet:對指定的容器IP、端口及路徑執行一個HTTP Get請求,若是返回的狀態碼在 [200,400)之間則表示探測成功,不然表示失敗

2. exec探針

exec類型的探針經過在目標容器中執行由用戶自定義的命令來判斷容器的監控狀態,若命令狀態返回值爲0則表示「成功」經過檢測,其餘值則均爲「失敗」狀態。api

2.1 建立liveness-exec.yaml

[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

2.2 查看Pod

[root@master ~]# kubectl get po -o wide
[root@master ~]# kubectl describe po liveness-exec

k8s實踐(五):容器探針(liveness and readiness probe)

pod運行正常,10秒內文件/tmp/healthy還存在,probe檢測正常。bash

k8s實踐(五):容器探針(liveness and readiness probe)

第15秒,probe再次檢測,因爲文件被刪,檢測失敗,此後容器會進行屢次重啓操做。服務器

k8s實踐(五):容器探針(liveness and readiness probe)

3. HTTP探針

基於HTTP的探測(HTTPGetAction)向目標容器發起一個HTTP請求,根據其相應碼進行結果斷定,響應碼如2xx或3xx時表示檢測經過。

3.1 建立liveness-http.yaml

[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

3.2 查看Pod

[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

k8s實踐(五):容器探針(liveness and readiness probe)

3.3 刪除測試頁面health

[root@master ~]# kubectl exec -it liveness-http rm  /usr/share/nginx/html/health

k8s實踐(五):容器探針(liveness and readiness probe)

探測失敗,返回碼404,重啓容器。

4. TCP探針

基於TCP的存活性探測(TCPSocketAction)用於向容器的特定端口發起TCP請求並嘗試創建鏈接,鏈接成功即爲經過檢測。

4.1 建立liveness-tcp.yaml

```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

k8s實踐(五):容器探針(liveness and readiness probe)

4.2 修改默認端口

[root@master ~]# kubectl exec -it liveness-tcp -- sed -i  's/^ *listen       80/    listen       81/g' /etc/nginx/conf.d/default.conf

若是kubectl exec在容器內執行命令時若是帶參數則需加上'--'

加載nginx

[root@master ~]# kubectl exec -it liveness-tcp -- nginx -s reload

k8s實踐(五):容器探針(liveness and readiness probe)

4.3 查看Pod

[root@master ~]# kubectl describe po liveness-tcp

k8s實踐(五):容器探針(liveness and readiness probe)

80是nginx的默認端口,開始發起TCP鏈接的端口也是80,默認端口改爲81後鏈接報錯,容器重啓。

3、ReadinessProbe

1. 概念

   用於容器的自定義準備狀態檢查。若是ReadinessProbe檢查失敗,Kubernetes會將該Pod從服務代理的分發後端去除,再也不分發請求給該Pod。

2. readinessprobe使用場景

   Pod對象啓動後,容器應用一般須要一段時間才能完成其初始化過程,例如加載配置或數據,甚至有些程序須要運行某類的預熱過程,若在此階段完成以前接入客戶端的請求,勢必會由於等待過久而影響用戶體驗,這時就須要就緒探針。

 

   若是沒有將就緒探針添加到pod中,它們幾乎會當即成爲服務端點。若是應用程序須要很長時間才能開始監聽傳入鏈接,則在服務啓動但還沒有準備好接收傳入鏈接時,客戶端請求將被轉發到該pod。所以,客戶端會看到"鏈接被拒絕"類型的錯誤。

3. 機制

   與存活探針機制相同,就緒探針也支持Exec、HTTP GET和TCP Socket三種探測方式,且各自的定義機制相同,將容器定義中的livenessProbe字段名替換爲readinessProbe便可定義出就緒探測的配置,這裏再也不贅述。

4. 建立readiness-exec.yaml

本文以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

5. 查看Pod

[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

k8s實踐(五):容器探針(liveness and readiness probe)

剛開始處於'預熱'階段,pod爲running狀態但不可用;當10秒後(initialDelaySeconds + periodSeconds),readinessprobe開始第一次探測,成功後pod處於ready狀態,45秒後(sleep30 + periodSeconds * failureThreshold)探測失敗,pod再次爲running但not ready狀態。

6. 與livenessprobe區別

  • 若是容器中的進程可以在遇到問題或不健康的狀況下自行崩潰,則不必定須要存活探針; kubelet 將根據Pod的restartPolicy自動執行正確的操做。
  • 若是您但願容器在探測失敗時被殺死並從新啓動,那麼請指定一個存活探針,並指定restartPolicy爲Always或OnFailure。
  • 若是要僅在探測成功時纔開始向 Pod 發送流量,請指定就緒探針。在這種狀況下,就緒探針可能與存活探針相同,可是spec中的就緒探針的存在乎味着Pod將在沒有接收到任何流量的狀況下啓動,而且只有在探針探測成功後纔開始接收流量。
  • 兩種探測的配置方法徹底同樣,支持的配置參數也同樣,既可單獨探測又可結合者一塊兒執行。

 
 

本文全部腳本和配置文件已上傳github:https://github.com/loong576/k8s-liveness-and-readiness-probe.git

相關文章
相關標籤/搜索