はじめに
GMOコネクトの森谷です。
ある日、開発環境のEKSクラスターでノードが1台NotReadyになり、複数のPodが停止しました。「そもそもなぜNotReadyになったのか」が分かっていない状態😇
NotReadyノードにはSSHできないし、kubeletのログも直接取れない。ただ、CloudWatchにメトリクスは残っている——ということで、Claude Codeを立ち上げて障害分析を始めました。デプロイログを貼ってスクリプトの該当箇所を特定してもらい、「CloudWatchにメトリクスがある」「復旧だけでなく原因を知りたい」といった方向づけはこちらでやる。調査コマンドの生成と結果の分析はClaudeに任せる。この役割分担で、原因特定から復旧まで進みました。
先にまとめ
- 「原因調査は可能か?」と聞いたら、CloudWatchメトリクスを使った調査コマンドを生成してくれた
- CPU使用率100%到達 → kubeletがハートビートを送れずNotReady、という直接原因を特定
- 原因特定後、Claude Codeが復旧手順(ノードTerminate → Pod強制削除 → Node削除 → ASG自動復旧)を提示し、そのまま実行して復旧
何が起きたか
開発環境のEKSクラスター(3ノード構成)で、1台のワーカーノードがNotReady状態になりました。そのノード上で動いていたPod(Elasticsearch、MongoDB、NFSサーバー等)がすべて停止し、サービスに影響が出ている状態です。
NotReadyになった原因が分からないまま復旧しても再発の可能性があるため、まずClaude Codeに状況を共有して原因調査から始めました。
Claude Codeで障害分析を進めたプロセス
Phase 1: 原因の特定
「EKSのワーカーノードがNotReadyになった。CloudWatchにメトリクスはあるが、原因を調査できるか?」と聞いたところ、「NotReadyノードにはSSHできないため取得できる情報に限りがありますが、CloudWatchにメトリクスがあれば調査可能です」という回答でした。そこからの調査フローは以下の通りです。
┌─────────────────────────────────────────────────────┐
│ Step 1: CloudWatchメトリクスの確認 │
│ Claude → CPUUtilizationの取得コマンドを生成 │
│ 結果 → 17:00 JST から急激にCPUが上昇し100%に到達 │
│ Claude → 「CPU飽和が原因です。メモリも確認しましょう」 │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ Step 2: メモリ使用率の確認 │
│ Claude → MemoryUtilizationの取得コマンドを生成 │
│ 結果 → メモリは正常範囲内 │
│ Claude → 「メモリではなくCPU起因です」 │
└──────────────────────┬──────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ Step 3: 直接原因の確定 │
│ Claude → 「CPU 100%到達により kubelet がハートビートを │
│ 送れなくなり、NotReady に遷移した」と判断 │
│ → 復旧手順の提示へ │
└─────────────────────────────────────────────────────┘
CPUが17:00 JSTから急激に上昇し100%に張り付いたこと、メモリには異常がないことから、CPU飽和によるkubeletのハートビート停止がNotReadyの直接原因であると特定できました。
Phase 2: 復旧
原因が特定できたため、Claude Codeに復旧手順を聞きました。提示された手順は以下の通りです。
- 問題のあるノードをAuto Scaling Group経由でTerminateする
- 旧ノード上のTerminating状態のPodを強制削除する
- Nodeオブジェクトを削除する
- ASGが新しいノードを自動作成するのを待つ
各ステップで必要なコマンドも生成してくれたので、そのまま実行して復旧しました。
# 1. ノードのTerminate
aws autoscaling terminate-instance-in-auto-scaling-group \
--instance-id <instance-id> \
--no-should-decrement-desired-capacity
# 2. Terminating状態のPodを強制削除
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
# 3. Nodeオブジェクトを削除
kubectl delete node <node-name>
# 4. 新ノードの起動を確認
kubectl get nodes -o wide
対話の中で起きていたこと
コマンド生成の正確さ
CloudWatchメトリクスの取得コマンド(aws cloudwatch get-metric-statistics)は、期間・ピリオド・統計タイプなどパラメータが多く、毎回ドキュメントを引きたくなる部分です。Claude Codeは障害発生時刻の前後を適切な範囲で指定したコマンドを生成してくれました。
原因特定から復旧手順への接続
「CPUが100%でkubeletが停止した」という原因を特定した後、そのまま「ではどう復旧するか」の手順とコマンドを出してくれました。原因調査と復旧が一つのセッションの中でシームレスに進んだのは、文脈を保持したまま対話できるClaude Codeの強みです。
文脈の保持
セッションの最初に貼ったPod一覧やノード情報を、復旧手順の提示時にも正確に覚えていて、どのPodを削除する必要があるかまで具体的に出してくれました。複数のコマンド結果を横断的に照合する作業を、文脈を保持したまま進めてくれるのは地味に助かります。
実行するのは人間
この記事で紹介した分析は、すべてClaude Codeがコマンドを生成し、人間が実行し、結果をフィードバックするサイクルで進めています。
Claude Codeに直接AWSやkubectlの実行権限を渡すこともできますが、開発環境とはいえ本番に近い構成のインフラに対しては、出力されたコマンドを人間の目で確認してから実行したい。Terminate操作やPodの強制削除など、取り消せないオペレーションが含まれる場合はなおさらです。
一方で、調査系のコマンド(describe、get、list系)であれば実行権限を渡して自動で回す運用も成立します。調査と変更で使い分けるのが落としどころかなと思います。
まとめ
- EKSノードのNotReady障害について、Claude Codeとの対話でコマンド生成→実行→結果分析のサイクルを回し、原因特定から復旧まで一気に進められた
- CloudWatchメトリクスからCPU飽和が直接原因であることを特定し、復旧手順もそのまま提示してもらえた
- 障害分析でのClaude Code活用は、「AWSコマンドの構文を覚えていなくてもいい」「原因調査から復旧まで文脈を保持したまま進められる」点で効率的
最後に、GMOコネクトではサービス開発支援や技術支援をはじめ、
幅広い支援を行っておりますので、何かありましたらお気軽にお問合せください。