Kubernetes應用健康檢查


目錄貼:Kubernetes學習系列

  在實際生產環境中,想要使得開發的應用程序完全沒有bug,在任何時候都運行正常,幾乎 是不可能的任務。因此,我們需要一套管理系統,來對用戶的應用程序執行周期性的健康檢查和修復操作。這套管理系統必須運行在應用程序之外,這一點非常重要一一如果它是應用程序的一部分,極有可能會和應用程序一起崩潰。因此,在Kubernetes中,系統和應用程序的健康檢查是由Kubelet來完成的。

1、進程級健康檢查

  最簡單的健康檢查是進程級的健康檢查,即檢驗容器進程是否存活。這類健康檢查的監控粒 度是在Kubernetes集群中運行的單一容器。Kubelet會定期通過Docker Daemon獲取所有Docker進程的運行情況,如果發現某個Docker容器未正常運行,則重新啟動該容器進程。目前,進程級的健康檢查都是默認啟用的。

2.業務級健康檢查

  在很多實際場景下,僅僅使用進程級健康檢查還遠遠不夠。有時,從Docker的角度來看,容器進程依舊在運行;但是如果從應用程序的角度來看,代碼處於死鎖狀態,即容器永遠都無法正常響應用戶的業務

  為了解決以上問題,Kubernetes引人了一個在容器內執行的活性探針(liveness probe)的概念,以支持用戶自己實現應用業務級的健康檢查。這些檢查項由Kubelet代為執行,以確保用戶的應用程序正確運轉,至於什么樣的狀態才算“正確”,則由用戶自己定義。Kubernetes支持3種類型的應用健康檢查動作,分別為HTTP Get、Container Exec和TCP Socket。個人感覺exec的方式還是最通用的,因為不是每個服務都有http服務,但每個服務都可以在自己內部定義健康檢查的job,定期執行,然后將檢查結果保存到一個特定的文件中,外部探針就不斷的查看這個健康文件就OK了。

2.1 Container Exec

  Kubelet將在用戶容器內執行一次命令,如果命令執行的退出碼為0,則認為容器運轉正常,否則認為容器運轉不正常。其中執行命令的默認目錄是容器文件系統的根目錄/,要執行的命令在Pod配置文件中定義。每進行一次Container Exec健康檢查,都會執行一次livenessprobe:exec:command段下的Shell命令。以下給出exec探針的示例:

[root@k8s-master livenessProbe]# cat test-livenessprobe-hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: test-livenessprobe-hostpath
  name: test-livenessprobe-hostpath
spec:
  containers:
    - name: test-livenessprobe-hostpath
      image: registry:5000/back_demon:1.0
      volumeMounts:
       - name: testhost
         mountPath: /home/laizy/test/hostpath
         readOnly: false
      livenessProbe:
        exec:
          command:
          - cat
          - /home/laizy/test/hostpath/healthy
        initialDelaySeconds: 5
        periodSeconds: 5
      command:
      - /run.sh
  volumes:
  - name: testhost
    hostPath:
     path: /home/testhost

  由yaml的配置可以看出,健康探針主要探測的是/home/laizy/test/hostpath/下是否存在healthy文件,對應的是宿主機上/home/testhost這個文件夾。若不存在則判定不健康,若存在則健康。筆者在實驗的過程中發現,當在宿主機上刪除這個文件的時候,大概需要40S的時間,系統才會判定pod失敗,並將其刪除;之后一直不斷重啟,且不會將pod調度到別的node上;當在宿主機上重新生成這個文件之后,大概需要四五分鍾的時間,pod一直處於CrashLoopBackOff的狀態,之后才正常提供服務。對於這兩個時間的產生,還需要進一步的探究其原理。

2.1 HTTP Get

  Kubelet將調用容器內Web應用的web hook,如果返回的HTTP狀態碼在200和399之間,則認為容器運轉正常,否則認為容器運轉不正常。每進行一次HTTP健康檢查都會訪問一次指定的URL。給出httpGet的簡單示例如下:

[root@k8s-master livenessProbe]# cat test-livenessprobe.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: test-livenessprobe
  name: test-livenessprobe
spec:
  containers:
    - name: test-livenessprobe
      image: registry:5000/back_demon:1.0
      livenessProbe:
        httpGet:
          path: /starott_cloud_client/test/overview-frontend
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 5
        timeoutSeconds: 1
      command:
      - /run.sh

在容器內部kill掉jboss進程之后(我的鏡像用腳本run.sh啟動,kill掉業務主進程之后,還可以通過其他的程序將容器“卡住”),模擬出調用http接口返回不在200~399之間,在node的/var/log/messages下會出現如下日志,並隨后將pod創建。

Apr  6 13:22:03 k8s-node-1 kubelet: I0406 13:22:03.470882   19861 docker_manager.go:2015] pod "test-livenessprobe_default(77b73469-1a88-11e7-b3d5-fa163ebba51b)" container "test-livenessprobe" is unhealthy, it will be killed and re-created.
Apr  6 13:22:03 k8s-node-1 dockerd-current: time="2017-04-06T13:22:03.471442565+08:00" level=info msg="{Action=stop, LoginUID=4294967295, PID=19861}"
Apr  6 13:22:33 k8s-node-1 dockerd-current: time="2017-04-06T13:22:33.472842885+08:00" level=info msg="Container 77c700d8564f2d7b8b0b455563b7530f5657df9b8a0de528587c6e0fb8a28237 failed to exit within 30 seconds of signal 15 - using the force"

2.3 TCP Socket

  理論上Kubelet將會嘗試打開一個到用戶容器的Socket連接。如果能夠建立這條連接,則可以認為容器運轉正常,否則認為容器運轉不正常。

  不論哪種檢查類型,一旦Kubelet發現容器運轉不正常,就會重新啟動該容器。容器的健康檢查行為在容器配置文件的livenessprobe字段下配置。需要注意的是,livenessprobe:initialDelaySecods字段代表了一個從容器啟動到執行健康檢查的延遲時間,設計這個延遲時間的目的是讓容器進程有時間完成必要的初始化工作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM