TL;DR
- StartupProbe:起動が遅いアプリが「生きる準備ができるまで」監視を保留する安全装置。
- ReadinessProbe:外部からのトラフィックを受けられる状態かを判定(未準備ならServiceから外す)。
- LivenessProbe:ハング検知→再起動の最終手段。乱用すると再起動ループの地獄。
まずは Startup → Readiness → Liveness の順に設計し、閾値は厳しすぎず緩すぎず。
なぜ重要?
ローリング更新や障害復旧時、準備できていないPodにリクエストが殺到してSLOを落とす事故が頻発。特にモデル読込・JIT・マイグレーションなど時間のかかる初期化があるサービスは、適切なプローブ設計が安定稼働の鍵。
最小実装スニペット(例:HTTPアプリ)
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
startupProbe:
httpGet: { path: /startup, port: 8080 }
periodSeconds: 5
failureThreshold: 30 # 例: 最大150秒まで待つ
設計ポイント
- /startup:DB接続確立、モデルロード、マイグレーション完了など「初期化OK」を返すまで
200
にしない。 - /ready:下流(DB/キャッシュ/外部API等)に実際にアクセス可能になってから
200
。 - /healthz:軽量&自己診断。重い依存先はなるべく参照しない(誤検知で再起動しないため)。
ありがち落とし穴 → 回避策
- Livenessで依存先を叩く
→ 一時的なDB障害でもPod再起動連打→さらに復旧遅延。Livenessは軽量に。 - Startup未設定のままReadiness失敗
→ 起動直後にNotReady
が続いてHPA/デプロイが不安定。起動が重いならStartup必須。 - 閾値が厳しすぎ(
periodSeconds=2
、failureThreshold=1
等)
→ ネットワーク揺らぎで即再起動。5–10秒/2–3回から試す。
運用チェックリスト(5分)
startupProbe
は重い初期化の完了を正しく判定しているreadinessProbe
は依存先到達性まで含めてOKを返すlivenessProbe
は軽量で誤検知しにくい- 本番のタイムアウト/リトライと整合(Ingress/Service/Client側)
- ローリング更新中に
Ready
なPodが常に閾値以上確保される(maxUnavailable
設定含む)
監視すべきメトリクス & 事後解析
- Pod再起動回数(急増はLiveness誤設定のサイン)
- probe失敗数(
kubelet_probe_*
系、失敗の種類と時刻相関) - rollout時間とReady遷移の遅さ(デプロイ粒度/閾値を見直す)
- エラーレート/レイテンシp95(Readiness誤判定でトラフィック流入してないか)
トラブル時の即席コマンド
# 現在のRollout進捗
kubectl rollout status deploy/your-app -n your-ns
# プローブ失敗の痕跡(Events)
kubectl describe pod <pod> -n your-ns | sed -n '/Events/,$p'
# 連続再起動の確認
kubectl get po -n your-ns -o custom-columns=NAME:.metadata.name,RESTARTS:.status.containerStatuses[*].restartCount
仕上げのひとこと
まずはStartupで重い初期化を吸収し、Readinessで依存確認、Livenessは最小限。これだけで「起動直後の事故」と「無限再起動」の多くは防げます。