Help us understand the problem. What is going on with this article?

[Kubernetes]Liveness Probeの動作を確認する

はじめに

KubernetesではPodの正常性判断のため、以下の3種類のヘルスチェック機構があります。

ヘルスチェック機構 概要 失敗時(チェックに引っかかった時)の動作
Liveness Probe Podが正常に動作しているかの確認 Podを再起動する
Readiness Probe Podがトラフィックの受け入れをできる状態になっているかの確認 LoadBalancerなどのサービスの転送先から削除される(トラフィックを流さない)
Startup Probe コンテナアプリケーションがいつ起動したかの確認 Liveness ProbeとReadiness Probeを無効にする

今回はそのうち、Liveness Probeの動作を確認したいと思います。
なお、Startup Probeは現時点でα版ですので、詳細は割愛します。

ヘルスチェック方式

Liveness Probe/Readiness Probeともに以下の3種類のチェック方式が利用できます。

方式 失敗となる条件
exec 指定したコマンドを実行し、終了コードが0でない場合
httpGet HTTP GETリクエストを実行し、Status Codeが200-399ではない場合
tcpSocket TCPセッションが確立できない場合

ヘルスチェック間隔

Liveness Probe/Readiness Probeともにヘルスチェックの間隔には、以下5種類のパラメータがあります。

パラメータ 設定内容
initialDelaySeconds 初回ヘルスチェックまでの遅延時間(秒)
periodSeconds ヘルスチェックとヘルスチェックの間隔(秒)
timeoutSeconds タイムアウトまでの時間(秒)
successThreshold 成功と判断するしきい値(回数)
failureThreshold 失敗と判断するしきい値(回数)

動作確認

それでは実際にやってみましょう。

exec

まずはexecからです。
以下のマニフェストのPodで動作を確認します。

ヘルスチェックは「spec.containers.LivenessProbe」以下にヘルスチェックの方式と間隔を指定します。

liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness-exec
    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
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 1

この例では、/tmp/healthyファイルがあるかどうかをチェックしています。
Podデプロイ時に/tmp/healthyファイルを作成しますが、30秒後に削除します。
ヘルスチェックを5秒待ってから開始し、5秒間隔で、1回失敗したらPodを再起動する動作になります。

このマニフェストをapplyします。

$ kubectl apply -f liveness-exec.yaml
pod/liveness-exec created

Podの状態を監視します。

$ kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   0/1     Pending   0          0s
liveness-exec   0/1     Pending   0          0s
liveness-exec   0/1     ContainerCreating   0          0s
liveness-exec   0/1     ContainerCreating   0          1s
liveness-exec   1/1     Running             0          3s
liveness-exec   1/1     Running             1          67s
liveness-exec   1/1     Running             2          2m11s
liveness-exec   1/1     Running             3          3m16s
liveness-exec   1/1     Running             4          4m21s
liveness-exec   1/1     Running             5          5m26s
liveness-exec   0/1     CrashLoopBackOff    5          6m30s
liveness-exec   1/1     Running             6          7m55s
liveness-exec   0/1     CrashLoopBackOff    6          9m1s
liveness-exec   1/1     Running             7          11m
liveness-exec   0/1     CrashLoopBackOff    7          12m
liveness-exec   1/1     Running             8          18m

RESTARTSの数字が上がっていくのがわかりますね。

kubectl describe podで詳細を確認できます。

$ kubectl describe pod liveness-exec
Name:         liveness-exec

Events:
  Type     Reason     Age                   From                   Message
  ----     ------     ----                  ----                   -------
  Normal   Scheduled  18m                   default-scheduler      Successfully assigned default/liveness-exec to k8s-worker01
  Normal   Pulled     15m (x4 over 18m)     kubelet, k8s-worker01  Successfully pulled image "k8s.gcr.io/busybox"
  Normal   Created    15m (x4 over 18m)     kubelet, k8s-worker01  Created container liveness-exec
  Normal   Started    15m (x4 over 18m)     kubelet, k8s-worker01  Started container liveness-exec
  Warning  Unhealthy  14m (x4 over 17m)     kubelet, k8s-worker01  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    14m (x4 over 17m)     kubelet, k8s-worker01  Container liveness-exec failed liveness probe, will be restarted
  Normal   Pulling    13m (x6 over 18m)     kubelet, k8s-worker01  Pulling image "k8s.gcr.io/busybox"
  Warning  BackOff    3m18s (x35 over 11m)  kubelet, k8s-worker01  Back-off restarting failed container

httpGet

次にhttpGetの動作を確認します。

今回の例では、自分自身のindex.html(http://localhost:80/index.html)へのhttpGetを設定しています。
Podが起動して30秒後にindex.htmlファイルを削除するようにしています。

liveness-http.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    args:
    - /bin/sh
    - -c
    - sleep 30; rm /usr/share/nginx/html/index.html; sleep 600
    livenessProbe:
      httpGet:
        path: /index.html
        port: 80
        scheme: HTTP
      initialDelaySeconds: 3
      periodSeconds: 3

このマニフェストをapplyして確認します。

$ kubectl apply -f liveness-http.yaml
pod/liveness-http created

Podの状態を監視します。

$ kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
liveness-http   0/1     Pending   0          0s
liveness-http   0/1     Pending   0          0s
liveness-http   0/1     ContainerCreating   0          0s
liveness-http   0/1     ContainerCreating   0          1s
liveness-http   1/1     Running             0          6s
liveness-http   1/1     Running             1          50s
liveness-http   1/1     Running             2          95s
liveness-http   1/1     Running             3          2m19s
liveness-http   1/1     Running             4          3m4s
liveness-http   1/1     Running             5          3m51s
liveness-http   0/1     CrashLoopBackOff    5          4m31s
liveness-http   1/1     Running             6          6m5s

再起動を繰り返すことによって、RESTARTSの値が増えていくことがわかりますね。

kubectl describeでもPodが再起動してる動作が確認できます。

$ kubectl describe pod liveness-http
Name:         liveness-http
・・・
Events:
  Type     Reason     Age                    From                   Message
  ----     ------     ----                   ----                   -------
  Normal   Scheduled  6m10s                  default-scheduler      Successfully assigned default/liveness-http to k8s-worker01
  Normal   Pulled     4m36s (x3 over 6m6s)   kubelet, k8s-worker01  Successfully pulled image "nginx:latest"
  Normal   Created    4m36s (x3 over 6m5s)   kubelet, k8s-worker01  Created container nginx
  Normal   Started    4m36s (x3 over 6m5s)   kubelet, k8s-worker01  Started container nginx
  Warning  Unhealthy  4m25s (x9 over 6m1s)   kubelet, k8s-worker01  Liveness probe failed: Get http://192.168.79.88:80/index.html: dial tcp 192.168.79.88:80: connect: connection refused
  Normal   Killing    4m25s (x3 over 5m55s)  kubelet, k8s-worker01  Container nginx failed liveness probe, will be restarted
  Normal   Pulling    3m55s (x4 over 6m9s)   kubelet, k8s-worker01  Pulling image "nginx:latest"
  Warning  BackOff    60s (x5 over 100s)     kubelet, k8s-worker01  Back-off restarting failed container

tcpSocket

最後にtcpSocketの動作を確認します。

今回の例ではnginxのポート80に対して、チェックするポートを77にしています。
Podが起動してから15秒待ってチェックを開始します。

liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-tcp
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 77
      initialDelaySeconds: 15
      periodSeconds: 3
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 1
$ kubectl apply -f liveness-tcp.yaml
pod/liveness-tcp created

Podの状態を確認します。
こちらも再起動を繰り返していることがわかります。

$ kubectl get pod -w
NAME           READY   STATUS    RESTARTS   AGE
liveness-tcp   0/1     Pending   0          0s
liveness-tcp   0/1     Pending   0          0s
liveness-tcp   0/1     ContainerCreating   0          0s
liveness-tcp   0/1     ContainerCreating   0          2s
liveness-tcp   1/1     Running             0          6s
liveness-tcp   1/1     Running             1          26s
liveness-tcp   1/1     Running             2          48s
liveness-tcp   1/1     Running             3          69s
liveness-tcp   1/1     Running             4          90s

kubectl describeで詳細を確認できます。

$ kubectl describe pod liveness-tcp
Name:         liveness-tcp

Events:
  Type     Reason     Age                 From                   Message
  ----     ------     ----                ----                   -------
  Normal   Scheduled  115s                default-scheduler      Successfully assigned default/liveness-tcp to k8s-worker01
  Normal   Pulled     47s (x4 over 109s)  kubelet, k8s-worker01  Successfully pulled image "nginx:latest"
  Normal   Created    47s (x4 over 109s)  kubelet, k8s-worker01  Created container nginx
  Normal   Started    47s (x4 over 109s)  kubelet, k8s-worker01  Started container nginx
  Warning  Unhealthy  30s (x4 over 93s)   kubelet, k8s-worker01  Liveness probe failed: dial tcp 192.168.79.97:77: connect: connection refused
  Normal   Killing    30s (x4 over 93s)   kubelet, k8s-worker01  Container nginx failed liveness probe, will be restarted
  Normal   Pulling    29s (x5 over 113s)  kubelet, k8s-worker01  Pulling image "nginx:latest"

まとめ

今回はKubernetesのヘルスチェック機能のLiveness Probeの動作を確認しました。
機能としては比較的わかりやすいですが、何をどうやってチェックするかは業務に依存してくると思いますので、その設計が難しそうですね。

dingtianhongjie
好きなOSはSolaris 最近はKubernetesを勉強してるので、勉強した結果を自分なりの理解でまとめています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした