1. 程式人生 > >pod配置Liveness和Readiness探針

pod配置Liveness和Readiness探針

本文將向您展示如何配置容器的存活和可讀性探針。

kubelet 使用 liveness probe(存活探針)來確定何時重啟容器。例如,當應用程式處於執行狀態但無法做進一步操作,liveness 探針將捕獲到 deadlock,重啟處於該狀態下的容器,使應用程式在存在 bug 的情況下依然能夠繼續執行下去。

Kubelet 使用 readiness probe(就緒探針)來確定容器是否已經就緒可以接受流量。只有當 Pod 中的容器都處於就緒狀態時 kubelet 才會認定該 Pod處於就緒狀態。該訊號的作用是控制哪些 Pod應該作為service的後端。如果 Pod 處於非就緒狀態,那麼它們將會被從 service 的 load balancer中移除。

定義 liveness 命令

許多長時間執行的應用程式最終會轉換到 broken 狀態,除非重新啟動,否則無法恢復。Kubernetes 提供了 liveness probe 來檢測和補救這種情況。

在本次練習將基於 gcr.io/google_containers/busybox映象建立執行一個容器的 Pod。以下是 Pod 的配置檔案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

該配置檔案給 Pod 配置了一個容器。periodSeconds 規定 kubelet 要每隔5秒執行一次 liveness probe。 initialDelaySeconds 告訴 kubelet 在第一次執行 probe 之前要的等待5秒鐘。探針檢測命令是在容器中執行 cat /tmp/healthy 命令。如果命令執行成功,將返回0,kubelet 就會認為該容器是活著的並且很健康。如果返回非0值,kubelet 就會殺掉這個容器並重啟它。

定義 liveness HTTP請求

我們還可以使用 HTTP GET 請求作為 liveness probe。下面是一個基於gcr.io/google_containers/liveness映象運行了一個容器的

Pod 的例子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

該配置檔案只定義了一個容器,livenessProbe 指定 kubelet 需要每隔3秒執行一次 liveness probe。initialDelaySeconds 指定 kubelet 在該執行第一次探測之前需要等待3秒鐘。該探針將向容器中的 server 的8080埠傳送一個HTTP GET 請求。如果server的/healthz路徑的 handler 返回一個成功的返回碼,kubelet 就會認定該容器是活著的並且很健康。如果返回失敗的返回碼,kubelet 將殺掉該容器並重啟它。

任何大於200小於400的返回碼都會認定是成功的返回碼。其他返回碼都會被認為是失敗的返回碼。

定義 TCP liveness probe

第三種 liveness probe 使用 TCP Socket。 使用此配置,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

如您所見,TCP 檢查的配置與 HTTP 檢查非常相似。 此示例同時使用了 readiness 和 liveness probe。 容器啟動後5秒鐘,kubelet 將傳送第一個 readiness probe。 這將嘗試連線到埠8080上的 goproxy 容器。如果探測成功,則該 pod 將被標記為就緒。Kubelet 將每隔10秒鐘執行一次該檢查。

除了 readiness probe之外,該配置還包括 liveness probe。 容器啟動15秒後,kubelet 將執行第一個 liveness probe。 就像readiness probe一樣,這將嘗試連線到 goproxy 容器上的8080埠。如果 liveness probe 失敗,容器將重新啟動。

使用命名的埠

可以使用命名的 ContainerPort 作為 HTTP 或 TCP liveness檢查:

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080

livenessProbe:
  httpGet:
  path: /healthz
  port: liveness-port

定義readiness probe

有時,應用程式暫時無法對外部流量提供服務。 例如,應用程式可能需要在啟動期間載入大量資料或配置檔案。 在這種情況下,您不想殺死應用程式,也不想傳送請求。 Kubernetes提供了readiness probe來檢測和減輕這些情況。 Pod中的容器可以報告自己還沒有準備,不能處理Kubernetes服務傳送過來的流量。

Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe 而不是livenessProbe。

readinessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

Readiness probe 的 HTTP 和 TCP 的探測器配置跟 liveness probe 一樣。

Readiness 和 livenss probe 可以並行用於同一容器。 使用兩者可以確保流量無法到達未準備好的容器,並且容器在失敗時重新啟動。

Configure Probes配置探針

配置 Probe

Probe 中有很多精確和詳細的配置,通過它們您能準確的控制 liveness 和 readiness 檢查:

  • initialDelaySeconds:容器啟動後第一次執行探測是需要等待多少秒。
  • periodSeconds:執行探測的頻率。預設是10秒,最小1秒。
  • timeoutSeconds:探測超時時間。預設1秒,最小1秒。
  • successThreshold:探測失敗後,最少連續探測成功多少次才被認定為成功。預設是 1。對於 liveness 必須是 1。最小值是 1。
  • failureThreshold:探測成功後,最少連續探測失敗多少次才被認定為失敗。預設是 3。最小值是 1。

HTTP probe 中可以給 httpGet設定其他配置項:

  • host:連線的主機名,預設連線到 pod 的 IP。您可能想在 http header 中設定 “Host” 而不是使用 IP。
  • scheme:連線使用的 schema,預設HTTP。
  • path: 訪問的HTTP server 的 path。
  • httpHeaders:自定義請求的 header。HTTP執行重複的 header。
  • port:訪問的容器的埠名字或者埠號。埠號必須介於 1 和 65525 之間。

對於 HTTP 探測器,kubelet 向指定的路徑和埠傳送 HTTP 請求以執行檢查。 Kubelet 將 probe 傳送到容器的 IP 地址,除非地址被httpGet中的可選host欄位覆蓋。 在大多數情況下,您不想設定主機欄位。 有一種情況下您可以設定它。 假設容器在127.0.0.1上偵聽,並且 Pod 的hostNetwork欄位為 true。 然後,在httpGet下的host應該設定為127.0.0.1。 如果您的 pod 依賴於虛擬主機,這可能是更常見的情況,您不應該是用host,而是應該在httpHeaders中設定Host頭。