Amazon EKS 向けにオブザーバビリティが強化された Container Insights でNodeとDeploymentの監視を設定する

Container Insights の強化されたオブザーバビリティは、NodeやDeploymentのCPU・メモリなどのリソース使用率を手軽に可視化できます。本ドキュメントでは、強化されたオブザーバビリティを使用して、リソース使用率に基づくメトリクス監視を設定する方法を説明します。

# 環境

本ドキュメントで説明する設定は、以下の環境で実施したものです。他のバージョンでも同様に設定が可能だと思いますが、細かい部分は異なるかもしれません。

- EKS: v1.31
- amazon-cloudwatch-observability: v3.6.0-eksbuild.2

# Nodeのメトリクス監視

以下画面の様に Container Insights で**ノード**を選択すると、ノード毎のCPU・メモリ使用率が可視化されます。しかし、このグラフには**InstanceId**や**NodeName**の指定が含まれます。EKSではノードの入れ替えが発生するため、**InstanceId**や**NodeName**を指定したアラーム設定だとノードの入れ替えに対応できません。そのため別の方法を考えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/acfc3f62-728b-4fab-a3ee-3107be97e595.png)

以下画面の様に Container Insights で**クラスター**を選択すると、クラスタ内全ノードのCPU・メモリ使用率が可視化され、**平均使用率**と**最大使用率**が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/43d8fe0c-a440-48b3-95cd-ef6f1ade7553.png)

今回は異常を検知したいモチベーションを想定して、最大使用率が閾値を上回る場合を想定したアラームを設定します。

## マネコンで設定

グラフにカーソルを移すと**四方の矢印**があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/a7d980db-2dc1-4527-b33c-2835ac24d9d5.png)
大きな画面でグラフが表示さるので**メトリクスで表示**します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/539f1050-685d-4b7c-9b41-898998273fb7.png)
するとCloudWatchメトリクスの画面が表示されます。アラームを設定したいグラフの**ベルマーク**を押します。(今回は下の[max: ${MAX}]～のラベルが付いた方)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/72d050b0-dea4-4601-91d8-a2d7844f81fd.png)
CloudWatchのアラーム作成で以下の様に設定します。以下の設定だと1分間隔でCPU使用率が80%より大きいNodeが一台でもあった場合にアラート状態となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/81617fd8-e089-456e-94d7-059607954cc7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/7c51b3d9-175a-4930-8ca5-1ca0530a33b9.png)

## Terraformで設定

同じ設定をTerraformで書くと以下の通りです。

```hcl
resource "aws_cloudwatch_metric_alarm" "eks_node_cpu_utilization" {
  alarm_name          = "eks-node-high-cpu-utilization"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "node_cpu_utilization"
  namespace           = "ContainerInsights"
  period              = "60" # 1分間隔で監視
  statistic           = "Maximum"
  threshold           = "80"
  alarm_description   = "EKSクラスタのノードCPU使用率がいずれかのノードで80%を超えました。"
  alarm_actions       = [aws_sns_topic.eks_alarm_topic.arn]
  treat_missing_data  = "ignore" # メトリクスの欠落を無視

  dimensions = {
    ClusterName = "mori-eks-test"
  }
}
```

# Deploymentのメトリクス監視

Container Insights で**ワークロード**を選択すると、DeploymentなどのCPU・メモリ使用率が可視化されます。ややこしいですが`ポッド CPU 使用率`と`ポッド CPU 使用率 (ポッド制限超過)`の2つのグラフがあります。これらは以下の通り全くことなるグラフです。

- **ポッド CPU 使用率**：`pod_cpu_usage_total / node_cpu_limit`
  Deploymentで展開したPodが平均どれくらいのノードCPUを消費しているかを表します。
- **ポッド CPU 使用率 (ポッド制限超過)**：`pod_cpu_usage_total / pod_cpu_limit`
  Podのresources.limitsに設定した値に対し、Deploymentで展開したPodが平均どれくらいのCPUを消費しているかを表します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/a66122d5-1219-4851-91c3-d20a12028eb6.png)

今回はDeploymentのリソース監視として`ポッド CPU 使用率 (ポッド制限超過)`に対するアラームを設定します。

## マネコンで設定

Nodeの時と同じように Container Insights のグラフからCloudWatchメトリクスを表示し、監視したいグラフのベルマークを押します。
CloudWatchのアラーム作成で以下の様に設定します。以下の設定だと一分間隔でNamespace:defaultのDeployment:nginxで展開されたPod群の平均CPU使用率が80%より大きかった場合にアラート状態となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/26601139-bfb8-431d-be1f-777738f21f03.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1356950/96002a87-ee5f-4897-a3fd-14aa9a645927.png)

## Terraformで設定

同じ設定をTerraformで書くと以下の通りです。

```hcl
resource "aws_cloudwatch_metric_alarm" "eks_deployment_cpu_utilization" {
  alarm_name          = "eks-deployment-high-cpu-utilization"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "pod_cpu_utilization_over_pod_limit"
  namespace           = "ContainerInsights"
  period              = "60"
  statistic           = "Average"
  threshold           = "80"
  alarm_description   = "EKSクラスタのDeploymentのCPU使用率（ポッド制限超過）が80%を超えました。"
  alarm_actions       = [aws_sns_topic.eks_alarm_topic.arn]
  treat_missing_data  = "ignore"

  dimensions = {
    ClusterName = "mori-eks-test"
    Namespace   = "default"  # 監視対象のNamespaceを指定
    Deployment  = "your-deployment-name"  # 監視対象のDeployment名を指定
  }
}
```

# その他の重要なメトリクス

上記ではCPU使用率を例に設定しました。他にも以下のメトリクスを監視してもいいと思います。

- Node
  - メモリ使用率(`node_memory_utilization`)：メモリの枯渇を防ぎ、アプリケーションのパフォーマンス問題を特定します。
  - ディスク使用率(`node_filesystem_utilization`)：ストレージの枯渇を防ぎ、データ損失のリスクを軽減します。
  - ネットワークトラフィック(`node_network_total_bytes`)：通信の異常や過負荷を検出し、アプリケーションのパフォーマンス問題を特定します。
  - 異常ノード数(`cluster_failed_node_count`)：リソース不足やスケジューリングの問題を早期に発見できます。
- Deployment
  - メモリ使用率(`pod_memory_utilization_over_pod_limit`)：メモリの枯渇を防ぎ、アプリケーションのパフォーマンス問題を特定します。
  - 異常Pod数（`pod_status_pending`、`pod_status_unknown`、`pod_status_failed`）：リソース不足やスケジューリングの問題を早期に発見できます。

その他にも多数のメトリクスがあります。詳細は公式のドキュメントを確認ください。

[Amazon EKS およびオブザーバビリティが強化された Kubernetes Container Insights](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Container-Insights-metrics-enhanced-EKS.html)