深夜2時のインシデント:サーバーはオールグリーンなのにサービスがダウンしている理由
午前2時15分、決済ゲートウェイが502 Bad Gatewayエラーを連発し、PagerDutyのアラートが鳴り響きました。インフラダッシュボードを急いで確認したものの、クラスタ全体のCPU使用率はわずか18%、メモリは半分以上空いており、Disk I/Oも極めて安定していて、一見すると何の問題もないように見えました。
しかし、本番環境でPodの状態を確認するコマンドを実行してみると状況は一変しました。
kubectl get pods -n production -l app=payment-service
決済サービスの全4台のPodがCrashLoopBackOff状態に陥っていたのです。メモリ不足(OOMKilled)によって、わずか30分間で再起動回数は37回にまで達していました。さらに同時刻、ステージング環境のネームスペースでは、新しく更新されたDeploymentが2時間もの間0/3 Pod利用可能のまま放置されていました。原因はネームスペースのCPU ResourceQuotaの上限に達してしまい、Kubernetes Schedulerが静かにPodのスケジューリングを拒絶していたことでした。
ここから得られる教訓は明確です。node-exporterやcAdvisorなどのツールは、ホストのハードウェア負荷を測定するに過ぎません。これらではKubernetesオブジェクトの論理的な状態までは把握できません。Podの再起動回数、Deploymentのレプリカ数の乖離、リソースクォータの消費状況を正確に監視するには、kube-state-metricsが不可欠です。
kube-state-metricsの仕組み
Kubernetesの監視エコシステムにおいて、各ツールはそれぞれ異なるデータレイヤーを担当しています。
- cAdvisor / metrics-server: コンテナが実際に消費しているリソース(CPUのミリコア数、メモリ使用量MB、ネットワークI/Oバイト数など)を測定します。このデータは
kubectl topコマンドやHPA(Horizontal Pod Autoscaler)の自動スケーリングで利用されます。 - kube-state-metrics (KSM):
client-goのWatchメカニズムを通じてKubernetes API Serverに直接接続します。KSMは実際のCPU/メモリ使用量を測定するのではなく、宣言された状態とオブジェクトの健全性を反映します。たとえば、PodがPendingなのかRunningなのか、コンテナが何回再起動したか、Deploymentに必要なPod数が揃っているか、ResourceQuotaが何パーセント消費されているかなどを可視化します。
これらのメタデータはすべてKSMによってPrometheusメトリクス形式に標準化され、ポート:8080/metricsで公開されます。Prometheusはここから定期的にメトリクスをスクレイピング(収集)します。
ダッシュボードに追加すべき3つの重要メトリクス群
kube_pod_container_status_restarts_total: コンテナが再起動された累計回数をカウントします。メモリリークや未ハンドルの例外によるクラッシュを早期に検知するための重要指標です。kube_deployment_status_replicas_availableおよびkube_deployment_spec_replicas: 実際にトラフィックを処理しているPod数と、YAML設定で指定された期待値(レプリカ数)の乖離を測定します。kube_resourcequota: ネームスペースごとのリソース消費量を監視し、クラスタ側で新しいPodの作成が静かにブロックされる事態を防ぎます。
kube-state-metricsのインストールと設定手順
障害が発生するたびに手動でkubectl describeを実行する代わりに、Helmを使ってKSMをデプロイし、わずか数分で自動アラートルールを構築できます。
ステップ1:Helmを使用したkube-state-metricsのインストール
Prometheus Community公式のHelmチャートを使用して、クラスタにデプロイします。
# 公式リポジトリの追加
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# kube-systemネームスペースにデプロイ
helm install kube-state-metrics prometheus-community/kube-state-metrics \
--namespace kube-system \
--set replicas=1 \
--set metricLabelsAllowlist.pods="[app,version,tier]"
パラメータmetricLabelsAllowlist.podsを使用すると、保持するラベルを限定できます。デフォルトでは時系列データの爆発(ハイカーディナリティ)を防ぐためにラベルの収集が無効化されています。アラートのフィルタリングに必要なappやversionなどのラベルのみを保持することをお勧めします。
ステップ2:出力データの動作確認
まず、KSMのPodが正常に起動しているか確認します。
kubectl get pods -n kube-system -l app.kubernetes.io/name=kube-state-metrics
PodがRunning状態になったら、ポートフォワードを実行してメトリクスの出力を確認します。
kubectl port-forward -n kube-system svc/kube-state-metrics 8080:8080
別のターミナルウィンドウでcurlコマンドを実行します。
curl -s http://localhost:8080/metrics | grep kube_pod_container_status_restarts_total | head -n 5
以下のような出力結果が返ってくれば正常です。
kube_pod_container_status_restarts_total{container="payment-api",namespace="production",pod="payment-service-789f6d4d5-x8k2l"} 37
ステップ3:Prometheusでのスクレイプジョブの設定
スタンドアロンのPrometheusクラスタを使用している場合は、prometheus.ymlに以下のジョブを追加します。
scrape_configs:
- job_name: 'kube-state-metrics'
static_configs:
- targets: ['kube-state-metrics.kube-system.svc.cluster.local:8080']
scrape_interval: 30s
Prometheusをリロードした後、Web UIのStatus > Targetsにアクセスしてターゲットの状態を確認します。エンドポイントが緑色でUPと表示されていれば完了です。
ステップ4:アラートシステムで設定すべき3つの必須PromQLクエリ
ユーザーから障害の連絡が来る前に問題を検知できるよう、以下の3つのPromQL式をAlertmanagerに設定しておくことをお勧めします。
1. コンテナの急激な再起動を検知(15分間に2回超)
increase(kube_pod_container_status_restarts_total[15m]) > 2
関数increase()は、指定した15分間の増加数を計算します。メモリ不足やコードのパニックによってPodがクラッシュを繰り返した場合、このルールによって即座にアラートがトリガーされます。
2. Deploymentのレディ状態Pod不足を検知
(kube_deployment_spec_replicas - kube_deployment_status_replicas_available) > 0
この式は、期待されるPod数と実際にリクエストを処理可能なPod数との乖離を検出します。これにより、ImagePullBackOffエラーやPodがreadinessProbeに失敗している状態を即座にキャッチできます。
3. ネームスペースのCPU Resource Quotaが85%に到達した際のアラート
kube_resourcequota{type="used", resource="requests.cpu"}
/ on(namespace, resourcequota)
kube_resourcequota{type="hard", resource="requests.cpu"} > 0.85
この式は、リクエスト済みリソース量とネームスペースに設定されたハードリミットを比較します。使用率が85%に達した段階でアラートを受け取ることで、Kubernetesが新規Podの作成を拒絶する前に、運用チームがクォータを拡張する猶予を確保できます。
まとめ
Kubernetesの監視は、サーバーのCPUやメモリの測定にとどまるべきではありません。kube-state-metricsを導入することで、クラスタ内の各Pod、Deployment、Resource Quotaの状態を細かく追跡できるようになります。サービスの停止を未然に防ぐためにも、システム構築の初期段階からこれらのアラートルールを整備しておくことを強くお勧めします。

