はじめに
ログ、イベント、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 の実際の動作にどのように反映されるかを理解しました。


