k8s的容器監測探針

大部分的應用程序咱們在部署的時候都會適當的添加監控,對於運行載體容器則更應該如此。kubernetes提供了 liveness probes來檢查咱們的應用程序。它是由節點上的kubelet按期執行的。html

首先說一下Pod的整個生命階段:java

  • Pending:表示集羣系統正在建立Pod,可是Pod中的container尚未所有被建立,這其中也包含集羣爲container建立網絡,或者下載鏡像的時間;
  • Running:表示pod已經運行在一個節點商量,而且全部的container都已經被建立。可是並不表明全部的container都運行,它僅僅表明至少有一個container是處於運行的狀態或者進程出於啓動中或者重啓中;
  • Succeeded:全部Pod中的container都已經終止成功,而且沒有處於重啓的container;
  • Failed:全部的Pod中的container都已經終止了,可是至少還有一個container沒有被正常的終止(其終止時的退出碼不爲0)

對於Liveness Probe的結果也有幾個固定的可選項值:nginx

  • Success:表示經過檢測
  • Failure:表示沒有經過檢測
  • Unknown:表示檢測沒有正常進行

Liveness Probe的種類:docker

  • ExecAction:在container中執行指定的命令。當其執行成功時,將其退出碼設置爲0;
  • TCPSocketAction:執行一個TCP檢查使用container的IP地址和指定的端口做爲socket。若是端口處於打開狀態視爲成功;
  • HTTPGetAcction:執行一個HTTP默認請求使用container的IP地址和指定的端口以及請求的路徑做爲url,用戶能夠經過host參數設置請求的地址,經過scheme參數設置協議類型(HTTP、HTTPS)若是其響應代碼在200~400之間,設爲成功。

當前kubelet擁有兩個檢測器,他們分別對應不通的觸發器(根據觸發器的結構執行進一步的動做):後端

  • Liveness Probe:表示container是否處於live狀態。若是 LivenessProbe失敗,LivenessProbe將會通知kubelet對應的container不健康了。隨後kubelet將kill掉 container,並根據RestarPolicy進行進一步的操做。默認狀況下LivenessProbe在第一次檢測以前初始化值爲 Success,若是container沒有提供LivenessProbe,則也認爲是Success;
  • Readiness Probe:表示container是否以及處於可接受service請求的狀態了。如 果ReadinessProbe失敗,endpoints controller將會從service所匹配到的endpoint列表中移除關於這個container的IP地址。所以對於Service匹配到的 endpoint的維護其核心是Readiness Probe。默認Readiness的初始值是Failure,若是一個container沒有提供 Readiness則被認爲是Success。

對於Liveness Probe和Readiness Probe用法都同樣,擁有相同的參數和相同的監測方式。api

  • initialDelaySeconds:用來表示初始化延遲的時間,也就是告訴監測從多久以後開始運行,單位是秒
  • timeoutSeconds: 用來表示監測的超時時間,若是超過這個時長後,則認爲監測失敗

當前對每個Container均可以設置不一樣的restartpolicy,有三種值能夠設置:網絡

  • Always: 只要container退出就從新啓動
  • OnFailure: 當container非正常退出後從新啓動
  • Never: 從不進行從新啓動

若是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之配置保活探針與就緒探針

在kubernetes中,kubelet經過liveness探針決定在什麼時候從新啓動容器。例如,容器中的應用運行時進入死鎖狀態,liveness探針對容器進行健康檢查時檢測到這種狀況,那麼探針檢測失敗,則kubelet就會從新啓動容器。能夠看到從新啓動並無從根本上解決死鎖問題,只是忽略了問題使容器繼續運行。

kubelet經過readiness類型的探針決定container是否準備就緒處理流量,當pod中的全部container所有處於ready狀態時,pod被認爲能夠對外提供服務。readiness探針的典型應用是控制pod是否做爲service的backend。如下示例中都沒有爲容器指定"restart policy",因此均採用默認值"Always"。

Define a liveness command

有些程序由於長時間運行而進入崩壞的狀態,其中的一個解決辦法是從新啓動,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。

Define a liveness HTTP request 

如下是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殺死容器而後從新啓動。

Define a TCP liveness probe

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

Use a named port 

在定義探針時使用命名端口,示例以下:

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080
 
livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port

Define readiness probes

容器有時候會暫時沒法對外提供服務,好比容器在啓動階段須要下載大量數據配置文件等,此時容器沒法對外提供服務但又不能殺死它,而用戶也但願此時容器不要授受來自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狀態。

相關文章
相關標籤/搜索