構成図で整理する Amazon EKS のモニタリング、状況別の設定からアラーム対応まで

構成図で整理する Amazon EKS のモニタリング、状況別の設定からアラーム対応まで

2026 年 10 月時点の EKS モニタリングを、CloudWatch、Prometheus、Fluent Bit などの役割とあわせて構成図で整理しました。状況別に何から用意するか、アラームが鳴ったときにどこを見るかまでまとめます。
2026.10.20

こんにちは。製造ビジネステクノロジー部所属の hongkii です。

EKS を運用し始めると、どんなログやメトリクスがあって、日々何を見ればいいのかつかめず、何から手をつけるか迷いがちです。関連する機能もコントロールプレーンのログから Container Insights、Prometheus、Fluent Bit まで幅広く、サービスもドキュメントもばらばらに分かれているので、全体像がなかなか見えてきません。

私も実務で EKS を運用していて、Fluent Bit でコンテナログを CloudWatch Logs に送り、Prometheus と Grafana でメトリクスを見ています。新しい機能が出るたびに「今の構成と重ならないか」「うちでも有効にしたほうがいいのか」をドキュメントでひとつずつ確かめていました。ここ 1 年は、Container Insights の方式が変わるなど大きな変化がいくつもありました。

そこで、2026 年 10 月時点の EKS モニタリングの全体像を一度整理してみることにしました。これからモニタリングを組む方にも、すでに運用している構成を見直したい方にも役立てばうれしいです。

まず構成例で全体をざっと眺めてから、次の順番で話を進めます。

  1. モニタリングで扱うデータ(シグナル)の種類と流れ
  2. 自分の環境にいま何が必要か、状況別の整理
  3. どんなアラームを作り、鳴ったときに何を見るか
  4. ツールの選び方と、機能ごとに押さえておきたい仕様と注意点
  5. この 1 年の主なアップデート

詳しい設定手順はこの記事では扱っていません。その代わり、機能ごとに公式ドキュメントへのリンクを載せているので、実際に設定するときはそちらもあわせて見てもらえればと思います。

構成例で見る全体像

本題に入る前に、全体像を 1 枚の図でざっと眺めてみましょう。たとえば、EC2 マネージドノードグループでフロントエンドやバックエンド API などのサービスを動かし、夜間バッチだけを Fargate で実行しているクラスターがあるとします。このクラスターで、どのコンポーネントのデータがどこへ行くのかをまとめると、次のようになります。

EKS モニタリングの構成例
色の付いた矢印がデータの通り道で、グレーの細い線は集めたデータを取り出して分析したり、通知を送ったりする流れです。全部を 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 が管理していますが、ログとメトリクスは利用者が取り出して見られます。データごとに行き先が違うので、まず図で見ると分かりやすいです。

コントロールプレーンのログ、メトリクス、監査ログの行き先と CloudTrail との違い
番号は最初の構成図の番号と同じです

コントロールプレーンのログ記録

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 にまとまっています。

https://repost.aws/ja/knowledge-center/eks-get-control-plane-logs

コントロールプレーンのメトリクス

コントロールプレーンのメトリクスは、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 のバージョンロールバックを実際に試した記事も書きました。ロールバックの準備状況インサイトの動きも、そちらで紹介しています。

https://dev.classmethod.jp/articles/eks-version-rollback-terraform/

ノードの異常検出と自動修復

ノードの異常は、見つける仕組み(ノードモニタリングエージェント)と、見つけた結果をもとに直す仕組み(ノード自動修復)を組み合わせて扱います。

ノードモニタリングエージェントが問題を NodeCondition とイベントに分けて記録し、ノード自動修復がノードを置き換える流れ

ノードモニタリングエージェント

ノードのカーネル、ネットワーク、ストレージ、コンテナランタイムで起きた問題を検出するエージェントです。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 でも同じです。

https://aws.amazon.com/blogs/containers/under-the-hood-how-amazon-eks-auto-mode-detects-repairs-and-diagnoses-node-failures/

ノードの CPU やメモリの使用量そのものは、Container Insights や node-exporter で見ます。

コンテナログの収集(EC2 と Fargate)

EC2 ノードでは、Fluent Bit を DaemonSet として各ノードで動かします。Fargate では DaemonSet が使えないので、AWS が管理するログルーターを使います。

EC2 ノードの Fluent Bit と Fargate のログルーターでログを集める経路

EC2 ノード

Fluent Bit の入れ方は、アドオンに任せるか、自分でデプロイするかのどちらかです。

  1. CloudWatch Observability アドオン(amazon-cloudwatch-observability)を使う。デフォルトで Fluent Bit がすべての Pod のコンテナログを収集する
  2. 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 のログルーターを併用している環境での事例です。

https://dev.classmethod.jp/articles/fluent-bit-cloudwatch-logs-broken-connection/

Fargate

Fargate には Fluent Bit ベースのログルーターが組み込まれているので、サイドカーとして Fluent Bit を別に動かす必要はありません。設定は ConfigMap 1 つで行います。

  • aws-observability 名前空間を作り、aws-observability: enabled ラベルを付ける
  • この名前空間に aws-logging ConfigMap を作る
  • 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 のログ設定を最初から試してみたい方は、こちらの記事が参考になります。

https://dev.classmethod.jp/articles/eksonfagate-cloudwatchlogs-builtinfluentbit/

Kubernetes イベントの保持と収集

イベントがどこで作られていつ消えるのか、外へ集めるにはどんな経路が必要なのかを、まず図で見てみます。

Kubernetes イベントが etcd に残ってから削除される流れと、Fluent Bit で集める経路

保持期間は 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 日に一般提供が開始されました。

Classic 方式と OTel 方式で、メトリクスとコンテナログを集めるコンポーネントと送り先の違い

項目 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 には両方とも含まれています。

Prometheus 形式のメトリクスを AMP、CloudWatch、自前の Prometheus に集める 3 つの方法

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-auth ConfigMap も引き続き使えます
  • 別のアカウントのワークスペースにも保存できます
  • クラスターを削除するときにスクレイパーも一緒に削除しないと、料金がかかり続けます(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 です。

https://dev.classmethod.jp/articles/cloudwatch-managed-prometheus-collector/

自前で運用する(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 のダッシュボードの例
出典: Grafana Labs

トレースと Application Signals

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

アドオンが計装を組み込み、CloudWatch エージェントが Application Signals と X-Ray に送るトレースの経路

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 をベースに、パフォーマンスメトリクス、サービスマップ、フローテーブル(再送、再送タイムアウト、データ転送量)を提供します。

Network Flow Monitor エージェントが Pod 間のフローを集め、EKS コンソールや Prometheus で確認する経路

エージェントは DaemonSet として各ノードで動き、データ転送量の多い上位 500 のフローを 30 秒ごとに集めます。Pod の情報まで付けたい場合は、Pod がホストのネットワーク名前空間ではなく、Pod 独自のネットワーク名前空間で動いていることが条件です。

アドオン名は aws-network-flow-monitoring-agent です。EKS コンソールで有効にすると、Network Flow Monitor(NFM)の Scope と Monitor が自動で作られます。Terraform などの IaC で構成するなら、必要な条件とエージェントの IAM 権限をドキュメントの前提条件で事前に確認しておくと安心です。

フローテーブルで AZ 間や NAT ゲートウェイを通る通信を見つけ、コストを減らすまでを紹介したブログもあります。

https://aws.amazon.com/blogs/containers/track-inter-az-and-nat-gateway-traffic-with-eks-container-network-observability/

ネットワークまわりでもう 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 のブログもあります。

https://aws.amazon.com/jp/blogs/news/guardduty-extended-threat-detection-has-added-five-new-indicators-to-surface-attack-sequences/

この 1 年の主なアップデート

この 1 年で、EKS のモニタリングに関わるアップデートがいくつかあったので、まとめておきます。

おわりに

整理してみると、機能が多く見える EKS のモニタリングも、4 つのシグナルと「収集、保存、可視化と通知」の流れに分ければ、各ツールの役割がすっきり見えてきました。そのうえで、すべての機能を有効にするより、自分の環境がいまどんな状況にあるかに合わせて、必要なものから揃えていくのが現実的だと思います。

まだ何も用意していないなら、エージェントやアドオンなしで使えるコントロールプレーンのログ記録と、無料のメトリクスによるアラームから始めてみてはいかがでしょうか。アラームを作る際に、鳴ったらどこを見るかもあわせて決めておくと、実際に問題が起きたときにずっと早く対応できます。

私自身にとっても、運用している構成を見直すよいきっかけになりました。皆さんの環境を見直すときの参考になれば幸いです。

長い記事になりましたが、最後まで読んでいただきありがとうございました。

この記事をシェアする

関連記事