Liveness プローブと Readiness プローブの設定

KubernetesBeginner
オンラインで実践に進む

はじめに

ログ、イベント、exec、ポートフォワーディングは、アプリケーションの調査に役立ちます。プローブを使用すると、Kubernetes が継続的にアプリケーションを検査できるようになります。Readiness プローブは「この Pod はトラフィックを受け入れるべきか?」という問いに答え、Liveness プローブは「このコンテナを再起動すべきか?」という問いに答えます。

この実験では、Readiness プローブと Liveness プローブを個別に設定します。まず、/ready エンドポイントが作成された後にのみ「Ready(準備完了)」状態になるアプリケーションを作成します。次に、Liveness プローブを持つ別のアプリケーションを作成し、kubectl exec でヘルスチェック用のファイルを削除することで、Kubernetes がコンテナを再起動する様子を観察します。

プローブ練習用の名前空間の準備

このステップでは、プローブの練習用にクリーンな名前空間を準備します。

/home/labex/project から開始します。プローブのマニフェストファイルはこのディレクトリに保存します。

mkdir -p /home/labex/project
cd /home/labex/project

Kubernetes API サーバーに接続できるか確認します。VM が起動した直後でノードがまだ準備できていない場合は、数秒待ってから再度コマンドを実行してください。

kubectl get nodes --request-timeout=5s

期待される出力例:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

クラスターのネットワーク Pod が Ready になるまで待ちます。プローブと Service は、Pod のネットワークが正常に動作していることに依存しています。

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

期待される出力:

pod/calico-node-... condition met

ckad-prep-probes という名前空間を作成し、現在の名前空間として設定します。

kubectl create namespace ckad-prep-probes
kubectl config set-context --current --namespace=ckad-prep-probes

現在の名前空間を確認します。

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

期待される出力:

ckad-prep-probes

Readiness プローブの設定

このステップでは、Readiness プローブを設定し、Service が Ready 状態の Pod にのみトラフィックを送信することを確認します。

コンテナは起動直後に HTTP サーバーを開始しますが、/www/ready ファイルは数秒後に作成されます。Readiness プローブはポート 8080 の GET /ready をチェックします。そのパスが存在するまで、Pod は Running 状態であっても Ready 状態にはならず、Service はトラフィックを送信しません。

readiness-web.yaml を作成します。

cat > readiness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: readiness-web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: readiness-web
  template:
    metadata:
      labels:
        app: readiness-web
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - |
          mkdir -p /www
          echo readiness-ok > /www/index.html
          (sleep 12; echo ready > /www/ready) &
          httpd -f -p 8080 -h /www
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 1
          periodSeconds: 2
          failureThreshold: 1
---
apiVersion: v1
kind: Service
metadata:
  name: readiness-web
spec:
  selector:
    app: readiness-web
  ports:
  - port: 80
    targetPort: 8080
EOF

マニフェストを適用し、作成直後の Pod を確認します。

kubectl apply -f readiness-web.yaml
sleep 3
kubectl get pods -l app=readiness-web

期待される出力では、Running 状態でもまだ Ready ではない Pod が表示される場合があります。

NAME                             READY   STATUS    RESTARTS   AGE
readiness-web-...                0/1     Running   0          ...

Deployment が利用可能になるまで待ちます。

kubectl rollout status deployment/readiness-web --timeout=120s

期待される出力:

deployment "readiness-web" successfully rolled out

EndpointSlice を通じて Service のエンドポイントを調査します。Readiness プローブが成功した後、Service は 2 つの Ready なエンドポイントを持つはずです。

kubectl get endpointslice -l kubernetes.io/service-name=readiness-web

期待される出力例:

NAME                ADDRESSTYPE   PORTS   ENDPOINTS
readiness-web-...   IPv4          8080    ... + 1 more...

クライアント Pod を作成し、Service をテストします。

kubectl run probe-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/probe-client --timeout=120s
kubectl exec probe-client -- wget -qO- http://readiness-web

期待される出力:

readiness-ok

Liveness プローブの設定

このステップでは、ヘルスチェック用ファイルをチェックする Liveness プローブを設定します。

Liveness プローブは、Kubernetes がコンテナを再起動すべきかどうかを判断します。この例では、コンテナ内で test -f /tmp/healthy を実行する exec プローブを使用します。コンテナは起動時にこのファイルを作成するため、最初は正常(Healthy)な状態から始まります。

liveness-web.yaml を作成します。

cat > liveness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: liveness-web
  template:
    metadata:
      labels:
        app: liveness-web
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - |
          touch /tmp/healthy
          mkdir -p /www
          echo liveness-ok > /www/index.html
          httpd -f -p 8080 -h /www
        ports:
        - containerPort: 8080
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /tmp/healthy
          initialDelaySeconds: 3
          periodSeconds: 3
          failureThreshold: 1
EOF

マニフェストを適用し、Deployment が完了するのを待ちます。

kubectl apply -f liveness-web.yaml
kubectl rollout status deployment/liveness-web --timeout=120s

期待される出力例:

deployment.apps/liveness-web created
deployment "liveness-web" successfully rolled out

Pod 名を保存し、ヘルスチェック用ファイルが存在することを確認します。

LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"
kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file exists"

期待される出力には Pod 名と以下が含まれます。

health file exists

Pod を詳細表示(describe)し、Liveness プローブの設定を確認します。

kubectl describe pod "$LIVE_POD" | grep -A3 'Liveness:'

期待される出力例:

Liveness:  exec [test -f /tmp/healthy] delay=3s timeout=1s period=3s

Liveness による再起動のトリガー

このステップでは、ヘルスチェック用ファイルを削除し、Liveness プローブによってコンテナが再起動される様子を観察します。

コンテナが再起動しても Pod オブジェクト自体は維持されます。そのため、新しい Pod 名を待つのではなく、コンテナの再起動回数(restart count)を監視します。

現在の Pod 名を保存します。

LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"

コンテナ内からヘルスチェック用ファイルを削除します。

kubectl exec "$LIVE_POD" -- rm /tmp/healthy

再起動回数が 0 より大きくなるまで監視します。Liveness プローブは 3 秒ごとに実行されるため、少し時間がかかる場合があります。

for i in $(seq 1 20); do
  RESTARTS="$(kubectl get pod "$LIVE_POD" -o jsonpath='{.status.containerStatuses[0].restartCount}')"
  echo "restart-count=$RESTARTS"
  if [ "$RESTARTS" != "0" ]; then
    break
  fi
  sleep 3
done

期待される出力には最終的に以下が含まれます。

restart-count=1

コンテナが再起動すると、起動コマンドによって /tmp/healthy が再作成されます。ファイルが戻ったことを確認します。

kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file recreated"

期待される出力:

health file recreated

Pod のイベントを読み取り、Liveness プローブの失敗を確認します。

kubectl describe pod "$LIVE_POD" | sed -n '/Events:/,$p'

期待される出力例:

Warning  Unhealthy  ...  Liveness probe failed
Normal   Killing    ...  Container web failed liveness probe

まとめ

アプリケーションの主要な 2 つのプローブを設定しました。Readiness プローブは Pod が Service エンドポイントに参加するタイミングを制御し、Liveness プローブはヘルスチェック用ファイルが削除された後にコンテナを再起動させました。また、EndpointSlice、Pod の詳細情報、再起動回数、イベントを確認することで、プローブの設定が Kubernetes の実際の動作にどのように反映されるかを理解しました。