
構成図で整理する Amazon EKS のモニタリング、状況別の設定からアラーム対応まで
こんにちは。製造ビジネステクノロジー部所属の hongkii です。
EKS を運用し始めると、どんなログやメトリクスがあって、日々何を見ればいいのかつかめず、何から手をつけるか迷いがちです。関連する機能もコントロールプレーンのログから Container Insights、Prometheus、Fluent Bit まで幅広く、サービスもドキュメントもばらばらに分かれているので、全体像がなかなか見えてきません。
私も実務で EKS を運用していて、Fluent Bit でコンテナログを CloudWatch Logs に送り、Prometheus と Grafana でメトリクスを見ています。新しい機能が出るたびに「今の構成と重ならないか」「うちでも有効にしたほうがいいのか」をドキュメントでひとつずつ確かめていました。ここ 1 年は、Container Insights の方式が変わるなど大きな変化がいくつもありました。
そこで、2026 年 10 月時点の EKS モニタリングの全体像を一度整理してみることにしました。これからモニタリングを組む方にも、すでに運用している構成を見直したい方にも役立てばうれしいです。
まず構成例で全体をざっと眺めてから、次の順番で話を進めます。
- モニタリングで扱うデータ(シグナル)の種類と流れ
- 自分の環境にいま何が必要か、状況別の整理
- どんなアラームを作り、鳴ったときに何を見るか
- ツールの選び方と、機能ごとに押さえておきたい仕様と注意点
- この 1 年の主なアップデート
詳しい設定手順はこの記事では扱っていません。その代わり、機能ごとに公式ドキュメントへのリンクを載せているので、実際に設定するときはそちらもあわせて見てもらえればと思います。
構成例で見る全体像
本題に入る前に、全体像を 1 枚の図でざっと眺めてみましょう。たとえば、EC2 マネージドノードグループでフロントエンドやバックエンド API などのサービスを動かし、夜間バッチだけを Fargate で実行しているクラスターがあるとします。このクラスターで、どのコンポーネントのデータがどこへ行くのかをまとめると、次のようになります。

色の付いた矢印がデータの通り道で、グレーの細い線は集めたデータを取り出して分析したり、通知を送ったりする流れです。全部を 1 枚に詰め込んだので、少し細かくなって読みづらかったらすみません…
初めて見る用語も多いと思いますが、このあと各章で図を使って詳しく説明するので、ここでは「何がどこへデータを送っているか」だけつかんでおけば十分です。番号ごとの中身を簡単に説明します。
| 番号 | 何を | どう送るか | 行き先 |
|---|---|---|---|
| 1 | コントロールプレーンのログ | コントロールプレーンのログ記録を有効にすると、EKS が直接送ります | CloudWatch Logs |
| 2 | コントロールプレーンのメトリクス | EKS が追加料金なしで自動的に送ります | CloudWatch メトリクス(AWS/EKS) |
| 3 | コンテナログとノードのログ | Fluent Bit が集めます。コンテナログはアプリケーションが標準出力と標準エラー出力に書いたログです | CloudWatch Logs |
| 4 | Pod とノードのメトリクス | CloudWatch エージェントが集めます(Container Insights) | CloudWatch メトリクス |
| 5 | トレース | Pod に自動で組み込まれた ADOT(AWS Distro for OpenTelemetry)SDK が CloudWatch エージェントへ送ります | Application Signals(保存先は X-Ray) |
| 6 | Fargate のログ | AWS が管理するログルーターが送ります。送り先は ConfigMap で指定します | CloudWatch Logs など |
| 7 | Prometheus 形式のメトリクス | マネージドコレクターが API サーバーと Pod から取得します | Amazon Managed Service for Prometheus(AMP、Grafana で確認) |
| 8 | Pod 間の通信 | Network Flow Monitor エージェントが集めます | CloudWatch Network Flow Monitor |
| 9 | ノードのランタイムの脅威 | GuardDuty エージェントが集めます(Runtime Monitoring) | GuardDuty |
| 10 | ノードの状態 | ノードモニタリングエージェントが異常を検出して記録します | ノード自動修復(ノードの置き換えや再起動) |
| 11 | Kubernetes イベント | イベント収集用の Fluent Bit が API サーバーから取得します(kubernetes_events) |
CloudWatch Logs |
| 12 | 監査ログ(脅威検出用) | GuardDuty が独自の経路で取得します(EKS Protection)。コントロールプレーンのログ記録を有効にする必要はありません | GuardDuty |
図で番号が付いていない 3 つの役割は、次のとおりです。
| 図の要素 | 役割 |
|---|---|
| アラーム・ダッシュボード | CloudWatch メトリクスと Application Signals の SLO でアラームを作ります。ログはメトリクスフィルターで数値に変換して使います |
| EKS コンソール | オブザーバビリティダッシュボードでコントロールプレーンの状態を、クラスターインサイトでアップグレード前の点検結果を見ます |
| AWS CloudTrail | クラスターやアドオンを変更した EKS API の呼び出しを記録します。kubectl での操作は audit ログに残ります |
図だけでは分かりにくい点もいくつか補足しておきます。
- Fluent Bit と CloudWatch エージェントは、CloudWatch Observability アドオンを入れると一緒にインストールされます。トレース用の ADOT SDK を Pod に自動で組み込むのもこのアドオンです
- Fargate では DaemonSet が使えないため、ログは AWS が管理するログルーターで送ります
- etcd にたまる Kubernetes イベントは、デフォルトでは 1 時間しか保持されません。長く残すには、図にあるイベント収集用の Fluent Bit のように、クラスターの外へ集める必要があります
- 図には注記だけ入れた cni-metrics-helper、ADOT Collector、Prometheus の自前運用は、後半の各章で取り上げます
とはいえ、この矢印を最初から全部揃える必要はありません。どんな状況で何が必要かは、このあとの「自分の環境には何が必要か」で整理しています。
モニタリングで扱う 4 つのシグナル
モニタリングで集めるデータのことをシグナルと呼びます。EKS ベストプラクティスガイドのコスト最適化にある「オブザーバビリティ」ページでは、ログ、メトリクス、トレースをオブザーバビリティの 3 つの柱として扱っています。EKS ではこれに Kubernetes が独自に残すイベントを加えて 4 つに分けておくと、このあと出てくるツールがそれぞれ何を担当しているのかがずっと見えやすくなります。
メトリクスで「いつから」が分かる
メトリクスは、ある値を一定の間隔で測り、時系列にためた数値です。Pod の CPU 使用率、ノードのメモリ使用量、API サーバーが受けたリクエスト数などがこれにあたります。
傾向を見たり、しきい値を超えたときに通知を送ったりするのに向いています。ただ、メトリクスからは「CPU 使用率がいつから上がったか」は分かっても、「なぜ上がったか」までは分かりません。原因はログやイベントから探すことになります。
ログで「何が起きたか」を追う
ログは、アプリケーションや Kubernetes のコンポーネントが残すメッセージです。アプリケーションのエラーメッセージ、コンテナの標準出力、API サーバーの監査ログはどれもログです。
エラーの原因を深掘りするときに、いちばんよく見るデータです。一方で、量が増えやすいので保存や検索にコストがかかり、全体の傾向を見るのにはあまり向いていません。
トレースで「どこが遅いか」を探す
トレースは、1 つのリクエストが複数のサービスを通っていく経路と、区間ごとにかかった時間を記録したものです。たとえばフロントエンドから API を経てデータベースまで届くリクエストなら、どの区間で時間がかかったのかが分かります。
サービスが複数に分かれた構成で、遅い箇所やエラーが起きた箇所を探すときに特に役立ちます。ただし、トレースを出力する仕組み(計装)をアプリケーションに組み込む必要があります。このあと紹介する Application Signals は、この計装を自動で組み込んでくれます。
Kubernetes イベントで「Kubernetes が何をしたか」を知る
Kubernetes イベントは、Kubernetes 自身が残す記録です。EKS のドキュメントには、Pod のスケジューリング、イメージの取得、ヘルスチェックの失敗、スケーリングといった例が挙がっています。「Pod を配置できるノードがない」「コンテナイメージを取得できなかった」のような情報がイベントとして残り、kubectl get events や kubectl describe pod で確認できます。
ただしログとは違ってクラスターの中に一時的にとどまるだけで、デフォルトでは 1 時間たつと消えます。もっと長く残したいなら、クラスターの外へ別に集めておくしかありません。
表で比べると
| シグナル | 形式 | 答えられる問い | EKS での例 | 主なツール |
|---|---|---|---|---|
| メトリクス | 数値の時系列 | どのくらい? いつから? | Pod の CPU 使用率 | CloudWatch メトリクス、Prometheus |
| ログ | テキストの記録 | 何が起きた? | アプリケーションのエラーメッセージ | Fluent Bit、CloudWatch Logs |
| トレース | リクエストの経路と所要時間 | どこが遅い? どこで失敗した? | API の遅い区間 | Application Signals、X-Ray |
| Kubernetes イベント | クラスター内の出来事 | Kubernetes は何をした? | Pod のスケジューリング失敗 | kubectl(長く残すには外部への収集が必要) |
実際に障害を追いかけていると、1 つのシグナルだけで片づくことはあまりありません。たいていはメトリクスのアラームで異常に気づき、イベントとログで何が起きたかを確かめ、トレースでどのサービスのどの処理で起きた問題なのかを絞り込んでいく流れになります。
データはどう流れるか
シグナルの多くは、「収集、保存、可視化と通知」という流れをたどります。

ノードごとに動くエージェントがデータを集めて保存先へ送り、それをダッシュボードで見たり、アラームで通知したりします。コントロールプレーンのログとメトリクスは例外で、エージェントなしで EKS が直接 CloudWatch へ送ります。
ただ、Kubernetes イベントはこの流れから外れています。収集と保存の仕組みが標準では用意されていないので、障害が収まってから原因を調べようとしても、もう消えていることが少なくありません。この点はぜひ覚えておきたいところです。
自分の環境には何が必要か
ここでは、よくある状況ごとに、何を有効にしてどんなアラームを設定すればよいかを整理しました。「うちの環境はまさにこれだ」と思う項目から拾い読みしてもらって構いません。機能ごとの詳しい内容は後半で取り上げます。
EKS の運用を始めたばかり
何から手をつければいいか分からないなら、まずは次の表の順に始めてみてはいかがでしょうか。特に 1 と 2 はエージェントもアドオンも要らないので、今日からでも取りかかれます。
| 順番 | やること | 理由 |
|---|---|---|
| 1 | コントロールプレーンのログ記録で、残すログタイプを決めて有効にする | デフォルトは無効で、有効にする前のログはあとから見られない |
| 2 | AWS/EKS メトリクスでアラームを作る |
無料ですでにたまっている |
| 3 | ノードモニタリングエージェントとノード自動修復を有効にする | 異常が起きたノードを、人が対応する前に置き換えられる |
| 4 | OTel Container Insights を有効にする | Pod とコンテナのメトリクス、コンテナログをまとめて収集できる |
ログタイプを何から有効にするか迷ったら、audit がおすすめです。誰がどのリソースを変更したかを追えますし、このあと紹介するオブザーバビリティダッシュボードの分析クエリも audit ログをもとに動くからです。ただしログは取り込んだ量に応じて料金がかかるので、本番以外のクラスターでは、ベストプラクティスガイドでも勧められているように必要なときだけ有効にしておくのがよいでしょう。
障害が収まったあと、原因を追い切れなかったことがある
深夜に Pod が再起動を繰り返していたのに、朝にはもう正常に戻っていたとします。出社して kubectl get events を実行しても、デフォルトの保持期間である 1 時間を過ぎたイベントは残っていません。
一度でもこういう経験があるなら、前もって用意しておきたいことがあります。
まず、Kubernetes イベントをクラスターの外へ集めておきます。Fluent Bit の kubernetes_events 入力プラグインを使えば、CloudWatch Logs などに送れます。
コンテナログは、障害を振り返るのに必要な期間を決めて保持期間を設定しておきます。CloudWatch Logs はデフォルトで無期限に保持するので、そのままだと保存料金が増え続けます。
そして audit ログを有効にしておけば、障害の直前に誰が何を変えたかをあとから確認できます。
サービスが複数あって、どこが遅いのか分からない
「レスポンスが遅い」という問い合わせは来るのに、フロントエンド、API、バックエンドのどこが原因なのか分からない状況です。こういうときに必要になるのがトレースです。
CloudWatch Observability アドオンの Application Signals を使うと、Java、Python、Node.js、.NET のアプリケーションに計装が自動で組み込まれ、サービス間の依存関係、レイテンシー、エラー率を確認できます。SLO も設定できます。
SLO(Service Level Objective、サービスレベル目標)は、「リクエストの 99.9% が成功する」「リクエストの 99% が 300ms 以内に応答する」のように、サービスが守るべき目標を決めたものです。サービスごとの目標が決まっているなら、SLO として定義して達成率を追いかけてみるのもよいと思います。
クラスターが大きく、コントローラーやオペレーターが多い
kubectl の応答がときどき遅かったり、コントローラーのログに処理の遅れが出ていたりする状況です。原因がアプリケーションではなく、コントロールプレーン側にあるかもしれません。
AWS のブログでは、こうした症状の原因として、リクエストを過剰に送るコントローラーやワークロードを挙げています。このとき API サーバーは 429(Too Many Requests)を返しますが、client-go が自動で再試行するため、原因になったワークロードのログには残らないことがあります。
こうしたクラスターでは、次のメトリクスでアラームを作っておきたいところです。どれも AWS/EKS に無料でたまるメトリクスなので、収集のために何かを追加する必要はありません(アラーム自体には CloudWatch アラームの料金がかかります)。
- API サーバーの 429 の数(
apiserver_request_total_429) - API 応答の P99 レイテンシー(
apiserver_request_duration_seconds_*_P99) - admission webhook の拒否数とレイテンシー
- etcd の使用量(
etcd_mvcc_db_total_size_in_use_in_bytes)
アラームが鳴ったときに何を見るかは、次の章で取り上げます。
断続的なタイムアウトがある、AZ 間の通信が気になる
アプリケーションでときどきタイムアウトが起きるのに原因が見えない、あるいはどのワークロードが AZ をまたいで大量のデータをやり取りしているのか知りたい、という状況です。
Container Network Observability を有効にすると、EKS コンソールでサービスマップとフローテーブルを見られます。データ転送量の多い通信がどこか、再送や再送タイムアウトの多い通信がどこかを確認できます。
すでに Prometheus と Grafana を使っている
私の環境もこのケースです。PromQL で作ったダッシュボードやアラートルールがすでにあるなら、その資産をそのまま活かせる構成を選ぶのがよいと思います。選択肢としては CloudWatch、AMP と Amazon Managed Grafana、自前での運用があり、課金の基準と向いている状況は後述の「ツールの選び方」で比べています。
AMP のマネージドコレクターや自前の Prometheus なら、API サーバーに加えて kube-scheduler と kube-controller-manager のメトリクスも Prometheus 形式で収集できます。OTel Container Insights が標準で集めるコントロールプレーンのメトリクスは、API サーバーと etcd のものです。
すでに別の仕組みでデータを集めている
新しく有効にする機能が既存の構成と重ならないか、まず確認しておきましょう。見落としやすいのは次のようなケースです。
Fluent Bit を自分で運用しているなら、CloudWatch Observability アドオンの設定に注意が必要です。アドオンはデフォルトで、アドオンに含まれる Fluent Bit を使ってコンテナログを収集します。私の環境のように Fluent Bit の DaemonSet をすでに動かしているクラスターでそのまま有効にすると、同じログを 2 回収集することになります。
Classic Container Insights を使っている場合も同じです。OTel Container Insights を有効にしただけだと、ログとメトリクスが従来の方式と OTel の両方で送られます。移行が終わったら片方を無効にしないと、料金が重複します。
ほかの APM や OpenTelemetry で計装しているなら、アドオンのアップグレードに気をつけます。v5.0.0 からは、アップグレードするだけで Application Signals が自動で有効になります。既存の計装と重ならないよう、アップグレードの前に設定を見直しておくと安心です。
Fargate も使っている
Fargate では DaemonSet が使えないため、EC2 ノードと同じやり方が通用しない部分があります。
| 項目 | EC2 ノード | Fargate |
|---|---|---|
| コンテナログ | Fluent Bit の DaemonSet | AWS が管理するログルーター(ConfigMap で設定) |
| ノードモニタリングエージェント、ノード自動修復 | 使える | 使えない |
Kubernetes イベントの外部収集(kubernetes_events) |
使える | ログルーターではできない |
| GuardDuty Runtime Monitoring | 使える | 使えない |
| Pod のメトリクス | Container Insights | ADOT Collector で Container Insights に送る |
アラームと対応
アラームは作っておくだけでは足りず、「鳴ったら何をするか」まで決めておいて初めて意味があります。この章では、アラームごとに、どんなときに鳴るのか、鳴ったらどこを見て何をすればよいのかをまとめました。しきい値の具体的な数字は環境によって違うので、決め方だけを書いています。
無料のコントロールプレーンメトリクスで作るアラーム
AWS/EKS 名前空間には、コントロールプレーンのメトリクスがすでに無料でたまっています。何もインストールしなくてよいので、アラームはここから作るのがいちばん早いです。
| メトリクス | 統計 | 鳴る状況 |
|---|---|---|
apiserver_request_total_429 |
Sum | API サーバーがリクエストを制限し始めた |
apiserver_request_duration_seconds_*_P99 |
Average | API の応答が遅くなってきている |
apiserver_admission_webhook_rejection_count |
Sum | admission webhook がリクエストを拒否している |
etcd_mvcc_db_total_size_in_use_in_bytes |
Maximum | etcd の使用量が上限に近づいている |
scheduler_pending_pods_UNSCHEDULABLE |
Sum | スケジュールできない Pod がたまっている |
apiserver_request_total_5XX |
Sum | API サーバー側でエラーが起きている |
「統計」の列は、ユーザーガイドのメトリクス表で「有効な統計」として挙がっているものです。P99 のメトリクスはすでに P99 として集計された値なので Average を、etcd の使用量は Maximum を使います。統計を取り違えるとアラームが意図どおりに鳴らないので、作るときにもう一度見直しておきましょう。
AWS/EKS のメトリクスは、クラスター内のすべての API サーバーをまとめた値です。EKS は API サーバーを 2 台以上動かしています。特定の API サーバーだけが遅くなる状況を見分けるには、Prometheus 形式のメトリクスを API サーバーごとに見る必要があります。ベストプラクティスガイドでも触れられているとおり、このとき複数の API サーバーの値を平均すると、遅くなったサーバーが埋もれてしまうので注意が必要です。
アラームを作る前にメトリクスのディメンションを確認しておくと、設定ミスを減らせます。
aws cloudwatch list-metrics \
--namespace AWS/EKS \
--metric-name etcd_mvcc_db_total_size_in_use_in_bytes
しきい値を決めにくい場合は、数週間ほど普段の値を見てから決める方法や、CloudWatch の異常検出を使う方法もあります。
429 が増えた
API サーバーが同時に処理できるリクエスト数(API Priority and Fairness(APF)のシート)を使い切り、リクエストを拒否している状態です。前述のとおり、原因はリクエストを過剰に送るコントローラーやワークロードであることが多いです。
原因を探すなら、EKS コンソールのオブザーバビリティダッシュボードから始めるのが早いです。audit ログを分析する CloudWatch Logs Insights のクエリが用意されていて、そのひとつがリクエストが制限されたクライアント(throttled clients)を探すクエリです。結果でリクエスト元のユーザー(サービスアカウントなど)を見れば、どのコントローラーが原因かを絞り込めます。ただし、audit ログを有効にしていないとこのクエリは使えません。
原因のクライアントが同じリソースを繰り返し LIST しているなら、WATCH で変更を受け取るように直すのが基本です。
APF のキューを深くしてしのぎたくなるかもしれませんが、深くしすぎるとかえってレイテンシーが増えます(ベストプラクティスガイド)。
API の応答が遅い
ベストプラクティスガイドによると、API のレイテンシーが 1 秒未満なら、コントロールプレーンはリクエストを時間内に処理できていると見てよいそうです。API サーバーのタイムアウトはデフォルトで 60 秒なので、しきい値はそれより十分に低い値にしておきます。基準を決めにくい場合は、upstream の Kubernetes の SLO が参考になります。
遅くなったら、admission webhook のレイテンシー(apiserver_admission_webhook_admission_duration_seconds_*_P99)と 429 が一緒に増えていないかを見ます。webhook が遅いなら次の項目へ、429 も増えているなら前の項目と同じ方法で原因のクライアントを探します。オブザーバビリティダッシュボードには、遅いリクエスト(slow requests)を探すクエリもあります。
admission webhook の拒否が増えた、応答が遅い
admission webhook は、ルールに一致するリソースの作成・更新・削除などのリクエストのたびに呼び出されます。設定を誤ると、クラスターの重要な操作まで止めてしまうことがあります。
影響の大きさは、拒否数(apiserver_admission_webhook_rejection_count)とレイテンシーのメトリクスで分かります。どの webhook が怪しいかは、オブザーバビリティダッシュボードの問題のある webhook(broken webhooks)を探すクエリが手がかりになります。
設定面では、すべてのリソースにかかる「catch-all」な webhook は避けたほうがよいでしょう。どうしても必要なら、webhook が応答しなくてもクラスターの重要な操作が止まらないようにフェイルオープンにして、タイムアウトを 30 秒より短くします(ベストプラクティスガイド)。
etcd の使用量が増えている
etcd の使用量がデータベースのクォータを超えると、etcd が書き込みを受け付けなくなり、クラスターが読み取り専用になります。Pod の作成も Deployment のスケールも拒否される状態なので、そうなる前に気づきたい値です。EKS の etcd データベースの上限は、標準のコントロールプレーンでは 8GB です。しきい値は対応する時間を残せるよう、たとえば上限の 80% くらいに設定してはいかがでしょうか(80% は私の目安です)。
使用量が増えてきたら、どの種類のオブジェクトが多いかを確認します。AWS のブログで紹介されているのは、リソースの種類ごとにオブジェクト数を数える次のコマンドです。
kubectl get --raw=/metrics | grep apiserver_storage_objects | awk '$2>100' | sort -g -k 2
不要なオブジェクトが見つかったら整理します。ベストプラクティスガイドでは、Deployment の revisionHistoryLimit を下げて古い ReplicaSet がたまらないようにする方法が例に挙がっています。バッチ処理や CronJob が多く、イベントが大量にたまるクラスターなら、イベントの保持期間(eventTtl)を短くするのも手です。
すでに読み取り専用になってしまったら、まずは 15 分ほど待ってみます。EKS には自動復旧のワークフローがあるからです。それでも解消しなければ、不要なオブジェクトのうち 20% 以上を削除します(AWS のブログ)。必要なオブジェクトが多くてどうしても減らせない場合は、より大きなクォータ(16GB)を使える Amazon EKS Provisioned Control Plane も選択肢になります。
スケジュールできない Pod がたまる
ノードのリソースが足りないか、Pod の配置条件を満たすノードがない状態です。
kubectl describe pod のイベントに出る FailedScheduling のメッセージを見ると、「Insufficient memory」のようなリソース不足なのか、affinity や taint の条件によるものなのかを見分けられます。
解決方法は、Karpenter のトラブルシューティングをまとめた AWS re:Post の記事で、メッセージごとに紹介されています。Pod のリソース要求を実際の使用量に合わせる、より大きなノードを追加する、配置条件を緩める、といった方法です。イベントは 1 時間で消えるので、時間がたってから調べるなら scheduler ログを見ます。
5XX が増えた
API サーバー側でエラーが起きている状態です。コントロールプレーンのログのうち api ログと、先ほど紹介した webhook 関連のメトリクスをあわせて確認します。
ログからアラームを作る
メトリクスにない情報は、CloudWatch Logs のメトリクスフィルターで数値に変換してからアラームを作ります。たとえば audit ログから非推奨の API を使うリクエストを数えたり、scheduler ログからスケジュールの失敗を数えたりします。この方法も、コントロールプレーンのログ記録を有効にしていることが前提です。
アプリケーションのアラーム
レイテンシーやエラー率は、Application Signals の SLO として定義すると、達成率とエラーバジェットで追いかけられます。
アラームではなく自動修復に任せる
すべての異常に、人が通知を受けて対応する必要はありません。ノードの異常のように、自動で直すほうがよいものもあります。ノードモニタリングエージェントとノード自動修復を有効にしておけば、ContainerRuntimeReady や NetworkingReady などの状態が異常になったノードを EKS が置き換えます。
問題が起きたらどこを見るか
次の表は、アラームが鳴ったときやユーザーから問い合わせが来たときに、どこから見ればよいかを、この記事の内容をもとに私がまとめたものです。障害対応中に開いて使ってもらえればと思います。
| こんなとき | まず見るもの | シグナル |
|---|---|---|
Pod が Pending のまま起動しない |
kubectl describe pod のイベント、scheduler_pending_pods |
イベント、メトリクス |
| Pod が再起動を繰り返す | kubectl describe pod のイベントと状態、コンテナログ、Pod のメモリ使用量 |
イベント、ログ、メトリクス |
| アプリケーションの応答が遅い、エラーが増えた | Application Signals のレイテンシーとエラー率、トレース、アプリケーションのログ | メトリクス、トレース、ログ |
kubectl や API の応答が遅い |
429 と P99 レイテンシーのメトリクス、オブザーバビリティダッシュボードのクエリ | メトリクス、ログ |
ノードが NotReady になった |
ノードの NodeCondition、ノード自動修復の状況、kubelet のログ(Fluent Bit で集めている場合は dataplane ロググループ) |
イベント、ログ |
| 誰がリソースを削除・変更したか知りたい | Kubernetes のリソースは audit ログ、クラスターやアドオンは CloudTrail |
ログ |
| アップグレードの前に問題がないか確かめたい | クラスターインサイト | - |
| Pod 間の通信が遅い、再送が多い | Container Network Observability のフローテーブル | メトリクス |
| Pod に IP アドレスが割り当てられない | kubectl describe pod のイベント、cni-metrics-helper のメトリクス |
イベント、メトリクス |
| 1 時間より前のイベントを見たい | クラスターの外へ集めたイベント | イベント |
ツールの選び方
メトリクスをどこに集めるかは、課金の基準と運用のしかたを並べて見ると判断しやすくなります。金額は変わることがあるので、課金の基準だけを整理しました。
| 選択肢 | 課金の基準 | 向いている状況 | 長所 |
|---|---|---|---|
| CloudWatch(OTel Container Insights) | メトリクスの取り込み量(GB)、PromQL の API とアラームでスキャンしたサンプル数、ログの取り込み量と保存量 | AWS だけで完結させたい。すぐに始めたい | アドオン 1 つでメトリクス、ログ、PromQL、アラームまで |
| AMP と Amazon Managed Grafana | サンプル数、保存量、クエリ量、コレクターの稼働時間、Grafana のアクティブユーザー数 | PromQL と Grafana に慣れている。複数のクラスターを 1 か所で見たい | サーバーを運用せずに Prometheus のエコシステムを使える |
| 自前で運用(kube-prometheus-stack) | インフラのコストと運用の負担 | 運用する人手があり、細かく調整したい | 自由度がいちばん高い |
どれを選んでも、ログは量が増えやすく、料金に大きく響きやすい項目です。減らす方法はベストプラクティスガイドのコスト最適化の章で紹介されています。ポイントだけ抜き出しておきます。
- 必要なログだけを集める。本番以外の環境では、必要なときだけログタイプを有効にする
- ログの保持期間を設定する
- 長く保存するログは S3 に送る
- 出力するログを重要度の高いものに絞り、フィルターで不要なログを落とす
コントロールプレーンのモニタリング
ここからは、これまでに出てきた機能の仕様と注意点を順に整理します。気になるところから読んでもらえれば大丈夫です。
コントロールプレーンは AWS が管理していますが、ログとメトリクスは利用者が取り出して見られます。データごとに行き先が違うので、まず図で見ると分かりやすいです。

番号は最初の構成図の番号と同じです
コントロールプレーンのログ記録
API サーバーの問題を調べたり、誰が何を変更したかを追ったりするのに欠かせません。ログタイプは 5 つです。
| ログタイプ | 内容 |
|---|---|
api |
API サーバーのログ |
audit |
Kubernetes の監査ログ。誰がどんな操作をしたかの記録 |
authenticator |
IAM 認証情報を使った RBAC 認証のログ。EKS 独自のログタイプ |
controllerManager |
コントローラーマネージャーのログ |
scheduler |
スケジューラーのログ |
デフォルトではどのログも CloudWatch Logs に送られないので、必要なログタイプを選んで有効にします。ログは /aws/eks/<クラスター名>/cluster ロググループに保存されます。次は公式ドキュメントの例で、5 つすべてを有効にするコマンドです。
aws eks update-cluster-config \
--region region-code \
--name my-cluster \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
ログストリームとログの中身
ロググループの中は、ログタイプごとにログストリームが分かれています。
| ログタイプ | ログストリーム名 |
|---|---|
api |
kube-apiserver-<ID> |
audit |
kube-apiserver-audit-<ID> |
authenticator |
authenticator-<ID> |
controllerManager |
kube-controller-manager-<ID> |
scheduler |
kube-scheduler-<ID> |
データが増えると、別の名前で新しいログストリームが作られます。同じログタイプのストリームが複数あるときは、最終イベント時刻がいちばん新しいストリームを見ます。
audit ログは JSON 形式で、主に見るフィールドはこのあたりです。
| フィールド | 内容 |
|---|---|
user.username |
誰が実行したか |
verb |
get、list、watch、create、update、delete など |
objectRef |
対象のリソース、API グループ、API バージョン |
responseStatus.code |
HTTP ステータスコード |
userAgent |
どのクライアントから来たか |
annotations |
認可の判断、非推奨 API かどうか |
annotations の "k8s.io/deprecated": "true" で絞り込むと、非推奨の APIをまだ使っているクライアントを探せます。
fields @message | filter `annotations.k8s.io/deprecated`="true"
scheduler ログは、イベントが消えたあとでもスケジュールの失敗を追うのに使えます。次のクエリで、スケジュールに失敗した回数を Pod とエラーの組み合わせごとに数えられます。ベストプラクティスガイドのクエリをもとに、元のクエリにはなかった stats を補っています。
fields timestamp, pod, err, @message
| filter @logStream like "scheduler"
| filter @message like "Unable to schedule pod"
| parse @message /^.(?<date>\d{4})\s+(?<timestamp>\d+:\d+:\d+\.\d+)\s+\S*\s+\S+\]\s\"(.*?)\"\s+pod=(?<pod>\"(.*?)\")\s+err=(?<err>\"(.*?)\")/
| stats count(*) as count by pod, err
| sort count desc
ほかにも、5xx エラーや、ノードを cordon・削除したユーザーの特定など、audit ログのクエリ例が re:Post にまとまっています。
コントロールプレーンのメトリクス
コントロールプレーンのメトリクスは、CloudWatch の AWS/EKS 名前空間に 1 分ごとに、追加料金なしで送られます。ドキュメントでは Kubernetes 1.28 以上が条件とされていますが、執筆時点で EKS がサポートしている最も古いバージョンは 1.31 なので、いま動いているクラスターならどれも対象です。アラームや調査でよく使うのは、次のメトリクスです。
| メトリクス | 内容 |
|---|---|
apiserver_request_total、apiserver_request_total_4XX、_429、_5XX |
API サーバーが受けたリクエスト数 |
apiserver_request_duration_seconds_GET_P99 など |
HTTP メソッドごとの P99 レイテンシー |
apiserver_current_inflight_requests_MUTATING、_READONLY |
処理中のリクエスト数 |
apiserver_flowcontrol_current_executing_seats |
API Priority and Fairness(APF)で実行中のシート数 |
apiserver_admission_webhook_rejection_count |
admission webhook が拒否したリクエスト数 |
apiserver_admission_webhook_admission_duration_seconds_ADMIT_P99、_VALIDATING_P99 |
サードパーティの webhook の P99 レイテンシー |
scheduler_pending_pods、scheduler_pending_pods_UNSCHEDULABLE |
スケジュール待ちの Pod 数、スケジュールに失敗して待っている Pod 数 |
etcd_mvcc_db_total_size_in_use_in_bytes |
etcd の実際の使用量 |
Prometheus 形式でも取得できます。API サーバーに加えて、kube-scheduler と kube-controller-manager のメトリクスも公開されています。
# API サーバー
kubectl get --raw /metrics
# kube-scheduler
kubectl get --raw "/apis/metrics.eks.amazonaws.com/v1/ksh/container/metrics"
# kube-controller-manager
kubectl get --raw "/apis/metrics.eks.amazonaws.com/v1/kcm/container/metrics"
kube-scheduler と kube-controller-manager のメトリクスを Prometheus などで収集する場合は、収集する側に次の権限が必要です。
- apiGroups: ["metrics.eks.amazonaws.com"]
resources: ["kcm/metrics", "ksh/metrics"]
verbs: ["get"]
オブザーバビリティダッシュボード
EKS コンソールのオブザーバビリティダッシュボードで、コントロールプレーンの状態をひと目で確認できます。[コントロールプレーンのモニタリング] タブに並んでいるのはこちらです。
- メトリクスのグラフ
auditログを分析する CloudWatch Logs Insights クエリの一覧。リクエストの多いクライアント、遅いリクエスト、リクエストが制限されたクライアント、問題のある webhook などを探せます。コントロールプレーンのログ記録が有効になっている必要があり、クエリの料金がかかります- CloudWatch のコントロールプレーンログへのリンク
クラスターインサイト
アップグレードを控えているときや、アップグレードしたあとにロールバックを考えるときに見ておきたい機能です。クラスターの設定とアップグレードの準備状況を、EKS が自動で点検してくれます。
| 種類 | API のカテゴリ | 内容 |
|---|---|---|
| アップグレードインサイト | UPGRADE_READINESS |
次のバージョンへのアップグレードを妨げる問題 |
| 設定インサイト | MISCONFIGURATION |
EKS Hybrid Nodes の設定ミス |
| ロールバックの準備状況インサイト | ROLLBACK_READINESS |
ロールバックを妨げる問題。アップグレードから 7 日以内のクラスターが対象 |
インサイトは 24 時間ごとに自動で更新され、aws eks start-insights-refresh ですぐに更新することもできます。
EKS のバージョンロールバックを実際に試した記事も書きました。ロールバックの準備状況インサイトの動きも、そちらで紹介しています。
ノードの異常検出と自動修復
ノードの異常は、見つける仕組み(ノードモニタリングエージェント)と、見つけた結果をもとに直す仕組み(ノード自動修復)を組み合わせて扱います。

ノードモニタリングエージェント
ノードのカーネル、ネットワーク、ストレージ、コンテナランタイムで起きた問題を検出するエージェントです。eks-node-monitoring-agent アドオンは DaemonSet として各ノードで動き、ノードのログを読み取って、問題の性質によって記録のしかたを分けています。
- 置き換えや再起動などの修復が必要な問題: NodeCondition として記録
- 一時的な問題や最適でないノードの設定: Kubernetes イベントとして記録。イベントとして記録された問題は自動修復の対象になりません
エージェントが追加する NodeCondition は、AcceleratedHardwareReady、ContainerRuntimeReady、KernelReady、NetworkingReady、StorageReady の 5 つです。Fargate と Windows では使えません。
ノード自動修復
ノードに異常が起きたとき、人が手を動かす前に EKS がノードを置き換えたり再起動したりしてくれる機能です。マネージドノードグループと Karpenter で使えます。条件ごとのデフォルトの動作を表にしました。
| NodeCondition | 修復までの待ち時間 | 修復の動作 |
|---|---|---|
AcceleratedHardwareReady |
10 分 | Replace または Reboot |
ContainerRuntimeReady、KernelReady、NetworkingReady、StorageReady、Ready |
30 分 | Replace |
DiskPressure、MemoryPressure |
- | 修復しない |
有効にする前に、次の点を確認しておきましょう。
- エージェントがない場合、自動修復が反応するのは kubelet の
Ready条件、手動で削除されたノードオブジェクト、クラスターへの参加に失敗したマネージドノードグループのインスタンスだけです。上の表の条件のほとんどは、エージェントがあって初めて検出されます - Reboot を使えるのは、マネージドノードグループと、
RebootForRepairフィーチャーゲートを有効にした Karpenter v1.15.0 以降です - マネージドノードグループでは、ノードが 5 台を超え、そのうち 20% を超えるノードが異常だと、新しい修復を始めません(進行中の修復は続きます)。ARC(Application Recovery Controller)のゾーンシフト中も同じです
- マネージドノードグループでは、異常なノード数のしきい値、同時に修復するノード数、条件ごとの動作も設定できます。設定できる値はドキュメントで確認してみてください
問題の検出からノードの置き換えまでの仕組みは、次のブログが詳しいです。EKS Auto Mode の記事ですが、検出の仕組みはマネージドノードグループや Karpenter でも同じです。
ノードの CPU やメモリの使用量そのものは、Container Insights や node-exporter で見ます。
コンテナログの収集(EC2 と Fargate)
EC2 ノードでは、Fluent Bit を DaemonSet として各ノードで動かします。Fargate では DaemonSet が使えないので、AWS が管理するログルーターを使います。

EC2 ノード
Fluent Bit の入れ方は、アドオンに任せるか、自分でデプロイするかのどちらかです。
- CloudWatch Observability アドオン(
amazon-cloudwatch-observability)を使う。デフォルトで Fluent Bit がすべての Pod のコンテナログを収集する - AWS 公式のイメージ
aws-for-fluent-bitを自分で DaemonSet としてデプロイする
アドオンを使うとロググループが 4 つ作られ、performance は CloudWatch エージェントが、残りの 3 つはアドオンの Fluent Bit が送ります。
| ロググループ | 内容 |
|---|---|
/aws/containerinsights/<クラスター名>/application |
/var/log/containers 配下のコンテナログ |
/aws/containerinsights/<クラスター名>/host |
/var/log/dmesg、/var/log/secure、/var/log/messages |
/aws/containerinsights/<クラスター名>/dataplane |
kubelet、kube-proxy、コンテナランタイムなどのログ |
/aws/containerinsights/<クラスター名>/performance |
CloudWatch エージェントが出力するパフォーマンスログ |
ここで集められるのは、アプリケーションが標準出力と標準エラー出力に書いたログです。コンテナの中のファイルにだけ書いているログはこの仕組みでは集められないので、出力先を /dev/stdout に変えるか、ファイルの内容を標準出力に流すサイドカーコンテナを置きます(Kubernetes のドキュメント)。Fargate のログルーターも同じです。
OTel Container Insights を有効にしたときのログ
OTel Container Insights を有効にすると、OpenTelemetry Collector のログパイプラインからもログが送られます。ただ、ここは少しややこしいところです。
まず、ログの送り先のロググループです。ドキュメントと Helm チャートのソースを突き合わせてみると、書かれている送り先が違っていました。有効にしたあとは、実際に作られたロググループを一度見ておくと確実です。
ドキュメントと実装の違い
- CloudWatch のドキュメントでは
/aws/containerinsights/<クラスター名>/applicationだけがサポートされていて、ホストとデータプレーンのログは今後のリリースでサポート予定とされています - 一方、Helm チャート 6.7.0 のソース(
templates/linux/_otel-container-insights-config.tpl)では、/aws/otel/containerinsights/<クラスター名>/applicationと/aws/otel/containerinsights/<クラスター名>/hostに送るよう設定されています
もう 1 つは、ログとメトリクスの重複です。ドキュメントだけ読んでいると気づきにくいのですが、アドオンの設定スキーマで各設定のデフォルト値を確認してみて分かったことがあります。ほかの設定をデフォルトのまま otelContainerInsights.enabled だけを true にすると、ログは Fluent Bit と OTel の両方から、メトリクスは Classic と OTel の両方から送られます。
アドオン設定のデフォルト値
アドオン v6.7.0-eksbuild.1 の設定スキーマを、aws eks describe-addon-configuration で実際に確認してみました。
| 設定 | デフォルト値 | スキーマの説明 |
|---|---|---|
containerLogs.enabled |
true |
Fluent Bit によるコンテナログの収集 |
otelContainerInsights.enabled |
false |
OTel Container Insights |
otelContainerInsights.logs.enabled |
true |
OTel のログパイプライン(application、host) |
containerInsights.enabled |
true |
従来の Container Insights(Classic) |
Fluent Bit をすでに自分で運用しているなら、アドオンの Fluent Bit は次の設定で無効にできます。
{ "containerLogs": { "enabled": false } }
ただ、この設定でどこまで止まるかは、ドキュメントと実装とで食い違っています。OTel Container Insights を有効にしているなら、otelContainerInsights.logs.enabled も一緒に見ておいてください。
この設定で無効になる範囲
- OTel Container Insights のログのドキュメントには、この設定でログの収集を完全に無効にできると書かれています
- 一方、アドオンの設定スキーマと Helm チャート 6.7.0 のソースでは、この設定で止まるのは Fluent Bit だけで、OTel のログパイプラインは
otelContainerInsights.logs.enabledで別に制御します
aws-for-fluent-bit を自分で運用する場合
イメージのバージョンは自分で管理する必要があります。現在の主流は Amazon Linux 2023 ベースの 3.x です。Amazon Linux 2 ベースの 2.x は、README では 2026 年 6 月 30 日にサポート終了とされていて、いまはベースイメージの更新に合わせた更新だけが出ています。README では 2028 年まで長期サポートされる 3.x への移行が勧められていますが、執筆時点でも stable タグは 2.x を指しています。stable や latest ではなく、README のガイダンスどおり固定のバージョンタグを指定しておくのが安全です。
CloudWatch Logs に送るときは、C で実装された cloudwatch_logs プラグインを使います。Go で実装された以前の cloudwatch プラグインを置き換えるものです。
Fluent Bit から CloudWatch Logs への送信で出る broken connection エラーを調べた記事も書きました。EC2 の DaemonSet と Fargate のログルーターを併用している環境での事例です。
Fargate
Fargate には Fluent Bit ベースのログルーターが組み込まれているので、サイドカーとして Fluent Bit を別に動かす必要はありません。設定は ConfigMap 1 つで行います。
aws-observability名前空間を作り、aws-observability: enabledラベルを付ける- この名前空間に
aws-loggingConfigMap を作る - ConfigMap に書けるのは
[FILTER]、[OUTPUT]、[PARSER]だけで、[SERVICE]と[INPUT]は AWS が管理する - ConfigMap は 5,300 文字まで書ける
- ConfigMap の変更は、新しく作られる Pod にだけ反映される
ログは CloudWatch Logs、Amazon Data Firehose、Kinesis Data Streams、Amazon OpenSearch Service に送れます。S3 などに送るには Firehose を経由します。送り先に応じた権限は Fargate の Pod 実行ロールに付与します。送り先ごとの IAM ポリシーの例は公式ドキュメントで確認できます。
EC2 と違って、ログルーターの Fluent Bit のバージョンは AWS が管理します。その代わり、使えるプラグインは限られています。
使える出力とフィルター
| 種類 | 使えるもの |
|---|---|
| 出力 | cloudwatch_logs、cloudwatch、firehose、kinesis_firehose、kinesis、es |
| フィルター | grep、parser、record_modifier、rewrite_tag、throttle、nest、modify、kubernetes |
ログが出ないときは、Pod のアノテーションとイベントを確認します。ConfigMap が見つからない場合は、次のように表示されます。
Annotations: CapacityProvisioned: 0.25vCPU 0.5GB
Logging: LoggingDisabled: LOGGING_CONFIGMAP_NOT_FOUND
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning LoggingDisabled <unknown> fargate-scheduler Disabled logging because aws-logging configmap was not found. configmap "aws-logging" not found
ConfigMap は読み込まれているのにログが期待どおりに出ない場合は、ConfigMap に flb_log_cw: "true" を指定してみてください。ログルーター自身のプロセスログが CloudWatch Logs に送られます。ロググループは <クラスター名>-fluent-bit-logs です。取り込みと保存の料金が余分にかかるので、原因が分かったら "false" に戻し、既存の Pod を再起動しておきましょう(ConfigMap の変更は新しい Pod にしか反映されません)。
ログルーター用のメモリは 50MB、ログが非常に多い場合は 100MB ほどを見込んでおきます(ユーザーガイド)。
Fargate のログ設定を最初から試してみたい方は、こちらの記事が参考になります。
Kubernetes イベントの保持と収集
イベントがどこで作られていつ消えるのか、外へ集めるにはどんな経路が必要なのかを、まず図で見てみます。

保持期間は eventTtl で短くできる
kube-apiserver は、一定の時間がたったイベントを削除します。この時間は --event-ttl で決まり、upstream のデフォルトは 1 時間です。
EKS では 2026 年 8 月 12 日から、Kubernetes 1.31 以上のクラスターでこの保持期間を変更できるようになりました。高度な Kubernetes コントロールプレーン設定のひとつ、eventTtl で設定します。
- 設定できる範囲は 10 分から 60 分で、デフォルトは 60 分です。つまり、デフォルトより短くすることしかできません
- 変更した値は、新しく作られるイベントにだけ適用されます
- 追加料金はかかりません
デフォルト値と設定範囲は aws eks describe-cluster-versions でも確認でき、ドキュメントでもこの API の結果を基準にするよう書かれています。Kubernetes 1.35 を指定して実行すると、次の結果が返ってきました。
"eventTtl": {"defaultValue": "60m", "constraints": {"min": "10m", "max": "60m"}}
ドキュメントでは、保持期間を短くするのに向いているケースとして、バッチや CI/CD、CronJob などでイベントが大量に生まれる場合や、イベントを外部のシステムに保管していて kubectl get events で過去を追わない場合などが挙がっています。一方で、保持期間は 60 分より長くできないので、1 時間より前のイベントを見たいならクラスターの外へ集める仕組みが必要です。ノードモニタリングエージェントが残すイベントも Kubernetes イベントなので、同じ保持期間が適用されます。
Fluent Bit の kubernetes_events でクラスターの外へ集める
Fluent Bit には、API サーバーから Kubernetes イベントを取得する入力プラグイン kubernetes_events があります。取得したイベントはログとして扱われるので、コンテナログと同じように CloudWatch Logs などに送れます。
ただし、aws-for-fluent-bit は 2.x と 3.x のどちらを使うかによって、このプラグインを使えるかどうかが違います。3.x にはこのプラグインが入っていますが、2.x に含まれる Fluent Bit 1.9.10 にはプラグイン自体がありません。以前 broken connection の件で調べた私の環境も、EC2 側の Fluent Bit は 1.9.10 でした。前述のとおり執筆時点では stable タグが 2.x を指しているので、このプラグインを使うには 3.x のバージョンタグを指定する必要があります。
Fargate のログルーターは [INPUT] を AWS が管理しているので、この方法は使えません。
CloudWatch Container Insights
Container Insights は、Pod とコンテナのメトリクスやコンテナログをまとめて集めてくれる機能です。
OTel 方式と Classic 方式
現在は OTel 方式と Classic 方式の 2 つがあります。どちらも同じ amazon-cloudwatch-observability アドオンを使い、違うのはアドオンのバージョンと設定だけです。OTel Container Insights は 2026 年 4 月 2 日にプレビューとして公開され、2026 年 6 月 23 日に一般提供が開始されました。

| 項目 | OTel Container Insights(推奨) | Enhanced Container Insights(Classic) |
|---|---|---|
| 状態 | 開発が続いている | メンテナンスモード。セキュリティパッチと重大なバグ修正のみ |
| 条件 | アドオン v6.2.0 以上。デフォルトは無効 | - |
| 収集間隔 | 30 秒 | 60 秒 |
| メトリクス名 | 元の名前のまま(例: container_cpu_usage_seconds_total) |
CloudWatch 独自の名前 |
| クエリ | PromQL | CloudWatch メトリクス |
| ログ | OpenTelemetry Collector | Fluent Bit |
| 料金 | メトリクスは取り込み量(GB)ベース | オブザベーション数ベース |
OTel 方式には node-exporter と kube-state-metrics が含まれていて、cAdvisor と API サーバーのメトリクスまで一緒に収集します。メトリクス名が元の名前のままなので、既存の PromQL のダッシュボードやコミュニティのドキュメントも参考にしやすいです。ただし、PromQL を API やアラームで使うと、スキャンしたサンプル数に応じてクエリの料金がかかります。コンソール(ダッシュボードを含む)で実行するクエリは無料です。
有効にするのに必要な IAM ロールや Pod Identity の設定などの準備は、クイックスタートにひととおり載っています。
Classic から移行するとき
アドオン v6.2.0 からは、Classic と OTel を同時に有効にできます。移行の前に新しいメトリクスを確認するための方法で、公式ドキュメントに次の例があります。
aws eks update-addon \
--cluster-name my-cluster \
--addon-name amazon-cloudwatch-observability \
--configuration-values '{"containerInsights":{"enabled":true},"otelContainerInsights":{"enabled":true}}'
containerInsights.enabled のデフォルト値が true なので、otelContainerInsights.enabled だけを指定しても結果は同じです。OTel だけを使うなら、公式ドキュメントのとおり Classic を明示的に無効にする必要があります。
aws eks update-addon \
--cluster-name my-cluster \
--addon-name amazon-cloudwatch-observability \
--configuration-values '{"containerInsights":{"enabled":false},"otelContainerInsights":{"enabled":true}}'
なお、containerInsights.enabled を false にして止まるのは Classic のメトリクスだけです。アドオンの Fluent Bit(containerLogs.enabled、デフォルトは true)は動き続けるので、OTel だけに切り替えたあともログは両方から送られます。前述の「OTel Container Insights を有効にしたときのログ」を参考に、containerLogs.enabled か otelContainerInsights.logs.enabled のどちらかを false にしておきましょう。
Prometheus と Grafana
Prometheus 形式のメトリクスは、AMP のマネージドコレクター、CloudWatch managed Prometheus collector、自前で運用する Prometheus のどれでも集められます。
集め方の違い
どの方法も同じ /metrics エンドポイントからメトリクスを取得しますが、保存先と見るツールが違います。マネージドコレクターはすでにあるエンドポイントから取得するだけなので、kube-state-metrics や node-exporter のメトリクスが必要なら、これらをクラスターに別途インストールしておきます。kube-prometheus-stack には両方とも含まれています。

Amazon Managed Service for Prometheus(AMP)のマネージドコレクター
クラスターにエージェントをインストールしなくても、AWS が管理するスクレイパーがメトリクスを集めて AMP のワークスペースに保存します。API サーバーだけでなく、kube-scheduler と kube-controller-manager のメトリクスも収集できます。
- EKS コンソールからスクレイパーを追加するか、
aws amp create-scraperで作成します - クラスターのエンドポイントアクセスに、プライベートアクセスが含まれていることが条件です
- 認証モードが
APIまたはAPI_AND_CONFIG_MAPなら、アクセスエントリで権限を付与するのがいちばん簡単です。aws-authConfigMap も引き続き使えます - 別のアカウントのワークスペースにも保存できます
- クラスターを削除するときにスクレイパーも一緒に削除しないと、料金がかかり続けます(EKS ユーザーガイド)
マネージドコレクターの制限
設計の段階で引っかかりやすい制限です。
- クラスター、スクレイパー、AMP ワークスペースは同じリージョンにある必要があります(アカウントは別でも構いません)
- スクレイパーはリージョンとアカウントごとに 10 個まで(引き上げ申請が可能)
- スクレイプ間隔は 30 秒より短くできません
/metricsエンドポイント 1 つあたりの応答は 50MB まで- スクレイパー 1 つでスクレイプできるエンドポイントは 30,000 個まで
- サブネットは 2 つ以上、アベイラビリティーゾーンは 2 つ以上を指定する必要があります
- VPC で DNS を有効にしておきます
メトリクスが入ってこないときは up メトリクスを見ます。up 自体がなければエンドポイントを見つけられていない状態で、up が 0 なら見つけたものの Prometheus 形式のメトリクスを取得できていない状態です。0 より大きければ正常に送られています。
CloudWatch managed Prometheus collector
2026 年 7 月 31 日にリリースされた機能です。AMP と同じ aws amp create-scraper コマンドで、送り先に CloudWatch を指定します。
機能の紹介とハンズオンをあわせた記事もあります。ハンズオンの対象は EC2 の node_exporter です。
自前で運用する(kube-prometheus-stack など)
Helm チャート kube-prometheus-stack を使うと、Prometheus Operator、Prometheus、Alertmanager に加えて、kube-state-metrics、node-exporter、Grafana までまとめてインストールされます。
- kube-state-metrics は、API サーバーから情報を受け取り、Deployment や Pod などのオブジェクトの状態をメトリクスとして公開します
- node-exporter は、ハードウェアと OS のメトリクスを公開します
自由度がいちばん高い代わりに、Prometheus のストレージや可用性まで自分で面倒を見ることになります。
Grafana で可視化する
Amazon Managed Grafana では、AMP と CloudWatch をビルトインのデータソースとして使えます。
自前で運用するなら、kube-prometheus-stack に含まれる Grafana を使えます。

出典: Grafana Labs
トレースと Application Signals
トレースを見るには、アプリケーションに計装を組み込み、エージェントで集めて AWS X-Ray に保存します。EKS では、計装と収集を CloudWatch Observability アドオンにまとめて任せる方法(Application Signals)と、OpenTelemetry の SDK と Collector を自分で構成する方法があります。

Application Signals
アプリケーションのレイテンシー、エラー率、サービス間の依存関係(Application Map)、SLO を見る機能です。
- CloudWatch Observability アドオン v5.0.0(2026 年 2 月)から、新規インストールでもアップグレードでも自動で有効になります
- 自動計装の対象言語は Java、Python、Node.js、.NET です
kube-systemとamazon-cloudwatchの名前空間は、デフォルトで対象から外れます
X-Ray SDK とデーモンはメンテナンスモードに
これから計装を組み込むなら、先にこの変化を押さえておきましょう。X-Ray SDK とデーモンは、2026 年 2 月 25 日にメンテナンスモードに入りました。今後はセキュリティ修正だけがリリースされ、新機能は追加されません。
AWS が勧める代替は、計装には OpenTelemetry SDK や ADOT、収集には CloudWatch エージェントや OpenTelemetry Collector です。OpenTelemetry に切り替えても、CloudWatch コンソールのトレースとトレースマップはそのまま使え、X-Ray API でトレースを取得することもできます。
すでに X-Ray SDK で計装しているアプリケーションなら、この移行ガイドで Java、Python、Node.js、.NET、Go、Ruby ごとの手順を確認できます。Application Signals の自動計装も OpenTelemetry ベースなので、自動計装で足りるなら Application Signals に移行するのもひとつの手だと思います。
自分で構成するなら ADOT
ADOT(AWS Distro for OpenTelemetry)のアドオン adot は今も提供されていて、使うには cert-manager が必要です。
ただ、EKS のアドオン一覧で Container Insights と Application Signals 向けに挙がっているのは CloudWatch Observability アドオンです。ADOT は、Fargate の Pod のメトリクス収集のように、OpenTelemetry Collector を自分で構成したい場合の選択肢です。
Fargate で ADOT を使って Container Insights のメトリクスを集める手順は、re:Post にまとまっています。
Pod 間の通信(Container Network Observability)
Pod 間の通信が遅いときや、AZ をまたぐトラフィックが気になるときに見る機能です。2025 年 11 月に発表された EKS の Container Network Observability は、CloudWatch Network Flow Monitor をベースに、パフォーマンスメトリクス、サービスマップ、フローテーブル(再送、再送タイムアウト、データ転送量)を提供します。

エージェントは DaemonSet として各ノードで動き、データ転送量の多い上位 500 のフローを 30 秒ごとに集めます。Pod の情報まで付けたい場合は、Pod がホストのネットワーク名前空間ではなく、Pod 独自のネットワーク名前空間で動いていることが条件です。
アドオン名は aws-network-flow-monitoring-agent です。EKS コンソールで有効にすると、Network Flow Monitor(NFM)の Scope と Monitor が自動で作られます。Terraform などの IaC で構成するなら、必要な条件とエージェントの IAM 権限をドキュメントの前提条件で事前に確認しておくと安心です。
フローテーブルで AZ 間や NAT ゲートウェイを通る通信を見つけ、コストを減らすまでを紹介したブログもあります。
ネットワークまわりでもう 1 つ、VPC CNI の IP アドレスの割り当て状況は、cni-metrics-helper で CloudWatch に送れます。EKS ユーザーガイドの専用ページはなくなっているので、GitHub のリポジトリで確認できます。
脅威検出(GuardDuty)
モニタリングとは目的が違いますが、EKS の脅威検出には GuardDuty を使います。
EKS の監査ログを分析するのが EKS Protection です。GuardDuty が独自のストリームで監査ログを取得するので、コントロールプレーンのログ記録を有効にしなくても使えます。
ノード上の動きまで見たいなら Runtime Monitoring を使います。aws-guardduty-agent アドオンで、ノード上のファイルへのアクセスやプロセスの実行、ネットワーク接続を監視する機能です。EC2 ノードはサポートされていますが、EKS on Fargate はサポートされていません。
2026 年 10 月には、Runtime Monitoring に 50 を超えるオプションの検出ルールが加わりました。ある環境ではふつうの操作でも、別の環境では侵害の兆候になりうる動きを検出するルールです。ドライランでどのくらい検出されるかを確かめてから有効にできます。
以前の EKS Runtime Monitoring をまだ使っているなら、ドキュメントの手順に沿って今の Runtime Monitoring に移行できます。
GuardDuty の拡張脅威検出(Extended Threat Detection)は、関連する検出内容をまとめて、AttackSequence:EKS/CompromisedCluster という 1 つの「重大」な検出結果にしてくれる機能です。EKS Protection と Runtime Monitoring のどちらか一方を有効にしていれば使えますが、ドキュメントでは両方の有効化が勧められています。監査ログとノード上の動きを組み合わせて関連付けられるからです。追加料金はかかりません。
最近は脆弱性や設定ミスといった情報も関連付けに使われるようになっていて、実際に観測された EKS への攻撃を例に解説した AWS のブログもあります。
この 1 年の主なアップデート
この 1 年で、EKS のモニタリングに関わるアップデートがいくつかあったので、まとめておきます。
- EKS の Container Network Observability が発表されました(2025 年 11 月)
- CloudWatch Observability アドオン v5.0.0 から Application Signals がデフォルトで有効になります(2026 年 2 月)
- X-Ray SDK とデーモンがメンテナンスモードに移行しました(2026 年 2 月)
- Container Insights の OpenTelemetry ベースの方式(推奨)が一般提供になり、従来の方式は Classic(メンテナンスモード)という扱いになりました(2026 年 6 月)
- CloudWatch managed Prometheus collector がリリースされました(2026 年 7 月)
- EKS で Kubernetes イベントの保持期間(
eventTtl)を設定できるようになりました(2026 年 8 月) - Amazon CloudWatch Omni が一般提供になりました(2026 年 9 月)
- 2026 年 10 月から東京リージョンでも使えるようになりました
- Amazon DevOps Guru のサポート終了が発表されました(2026 年 9 月)
- 2026 年 10 月 29 日以降は新規顧客が利用を開始できなくなり、AWS は代替として CloudWatch と Amazon DevOps Agent を挙げています
おわりに
整理してみると、機能が多く見える EKS のモニタリングも、4 つのシグナルと「収集、保存、可視化と通知」の流れに分ければ、各ツールの役割がすっきり見えてきました。そのうえで、すべての機能を有効にするより、自分の環境がいまどんな状況にあるかに合わせて、必要なものから揃えていくのが現実的だと思います。
まだ何も用意していないなら、エージェントやアドオンなしで使えるコントロールプレーンのログ記録と、無料のメトリクスによるアラームから始めてみてはいかがでしょうか。アラームを作る際に、鳴ったらどこを見るかもあわせて決めておくと、実際に問題が起きたときにずっと早く対応できます。
私自身にとっても、運用している構成を見直すよいきっかけになりました。皆さんの環境を見直すときの参考になれば幸いです。
長い記事になりましたが、最後まで読んでいただきありがとうございました。







