Container Insights with enhanced observability for Amazon EKS が利用可能になったので試してみた

EKS on EC2 環境での Container Insights が大幅に使いやすくなりました。

EKS on EC2 で Container Insights with enhanced observability for Amazon EKS を利用可能になりました。

日本語版

これまでも FluentBit と CloudWatch エージェントをインストールすれば Container Insights によってコンテナレベルのメトリクスを利用可能でしたが、今回複数のメリットがある形でアップデートされました。

メリットとして挙げられるのは下記になります。

  • プリセットされた複数の新しいダッシュボードビューが利用可能になった。
  • 今まで利用できなかったメトリクスが追加された。
  • 個別に FluentBit と CloudWatch Agent をインストールしなくてもよくなった。
    • amazon-cloudwatch-observability アドオンが追加された。
  • より明快な価格体系になった。

ただし、Fargate には対応していないのでこの点は注意する必要があります。

Container Insights with enhanced observability for Amazon EKS で新しく利用可能なメトリクスを確認してみた

以前から確認可能なメトリクスおよび新しいメトリクスは Amazon EKS and Kubernetes Container Insights metrics に記載があります。

以前から確認可能なメトリクス

  • cluster_failed_node_count
  • cluster_node_count
  • namespace_number_of_running_pods
  • node_cpu_limit
  • node_cpu_reserved_capacity
  • node_cpu_usage_total
  • node_cpu_utilization
  • node_filesystem_utilization
  • node_memory_limit
  • node_memory_reserved_capacity
  • node_memory_utilization
  • node_memory_working_set
  • node_network_total_bytes
  • node_number_of_running_containers
  • node_number_of_running_pods
  • pod_cpu_reserved_capacity
  • pod_cpu_utilization
  • pod_cpu_utilization_over_pod_limit
  • pod_memory_reserved_capacity
  • pod_memory_utilization
  • pod_memory_utilization_over_pod_limit
  • pod_network_rx_bytes
  • pod_network_tx_bytes
  • pod_number_of_container_restarts
  • service_number_of_running_pods

Container Insights with enhanced observability for Amazon EKS でのみ確認可能なメトリクス

  • node_filesystem_inodes
  • node_filesystem_inodes_free
  • node_status_allocatable_pods
  • node_status_capacity_pods
  • node_status_condition_ready
  • node_status_condition_memory_pressure
  • node_status_condition_pid_pressure
  • node_status_condition_disk_pressure
  • node_status_condition_unknown
  • node_interface_network_rx_dropped
  • node_interface_network_tx_dropped
  • node_diskio_io_service_bytes_total
  • node_diskio_io_serviced_total
  • pod_cpu_request
  • pod_memory_request
  • pod_cpu_limit
  • pod_memory_limit
  • pod_status_failed
  • pod_status_ready
  • pod_status_running
  • pod_status_scheduled
  • pod_status_unknown
  • pod_status_pending
  • pod_status_succeeded
  • pod_number_of_containers
  • pod_number_of_running_containers
  • pod_container_status_terminated
  • pod_container_status_running
  • pod_container_status_waiting
  • pod_interface_network_rx_dropped
  • pod_interface_network_tx_dropped
  • container_cpu_utilization
  • container_cpu_utilization_over_container_limit
  • container_memory_utilization
  • container_memory_utilization_over_container_limit
  • container_memory_failures_total
  • container_filesystem_usage
  • container_filesystem_available
  • container_filesystem_utilization
  • replicas_desired
  • replicas_ready
  • replicas_available
  • replicas_unavailable
  • apiserver_storage_objects
  • apiserver_request_total
  • apiserver_request_duration_seconds
  • apiserver_admission_controller_admission_duration_seconds
  • rest_client_request_duration_seconds
  • rest_client_requests_total
  • etcd_request_duration_seconds
  • apiserver_storage_size_bytes
  • apiserver_longrunning_requests
  • apiserver_current_inflight_requests
  • apiserver_admission_webhook_admission_duration_seconds
  • apiserver_admission_step_admission_duration_seconds
  • apiserver_requested_deprecated_apis
  • apiserver_request_total_5XX
  • apiserver_storage_list_duration_seconds
  • apiserver_current_inqueue_requests
  • apiserver_flowcontrol_rejected_requests_total

Container Insights with enhanced observability for Amazon EKS を使うことで、 Kubernetes リソースのステータスに関するメトリクスやコントロールプレーン関連のメトリクスが多数利用可能になりました。

amazon-cloudwatch-observability アドオンをインストールしてみた

FluentBit と CloudWatch Agent をまとめた形でインストールできる、 amazon-cloudwatch-observability アドオンを利用してみます。
まず、下記 ClusterConfig を利用して eksctl で検証用クラスターを作成しました。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: test-cluster
  region: ap-northeast-1
  version: "1.27"

iam:
  withOIDC: true

nodeGroups:
  - name: test-cluster-ng
    amiFamily: AmazonLinux2
    privateNetworking: true
    instanceType: t3.medium
    desiredCapacity: 2
    minSize: 1
    maxSize: 2

cloudWatch:
  clusterLogging:
    enableTypes:
      - "audit"
eksctl create cluster -f cluster.yaml

Install the CloudWatch agent by using the Amazon CloudWatch Observability EKS add-on に沿って進めていきます。
ServiceAcount から利用可能な IAM ロールを作成します。

$ eksctl create iamserviceaccount \
          --name cloudwatch-agent \
          --namespace amazon-cloudwatch \
          --cluster test-cluster \
          --role-name AmazonEKS_Observability_Role \
          --role-only \
          --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
          --approve

今利用できる amazon-cloudwatch-observability アドオンは v1.1.1-eksbuild.1 だけでしたので、こちらをインストールします。

$ eksctl utils describe-addon-versions --kubernetes-version 1.27 --name amazon-cloudwatch-observability | grep AddonVersion
			"AddonVersions": [
					"AddonVersion": "v1.1.1-eksbuild.1",

アドオンを追加します。

$ eksctl create addon \
        --cluster test-cluster \
        --name amazon-cloudwatch-observability \
        --version v1.1.1-eksbuild.1 \
        --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_Observability_Role \
        --force

Fluent Bit と CloudWatch エージェントが daemonset としてインストールされていました。

$ kubectl get pod -n amazon-cloudwatch
NAME                                                              READY   STATUS    RESTARTS   AGE
amazon-cloudwatch-observability-controller-manager-7448bbf4psst   1/1     Running   0          21h
cloudwatch-agent-4nlzf                                            1/1     Running   0          21h
cloudwatch-agent-lk2pv                                            1/1     Running   0          21h
fluent-bit-2fxhj                                                  1/1     Running   0          21h
fluent-bit-f92sx                                                  1/1     Running   0          21h

eksctl の場合、設定ファイルに追記する形でもアドオンを利用可能です。

addons:
  - name: amazon-cloudwatch-observability
    version: v1.1.1-eksbuild.1
    tags:
      team: eks
    attachPolicyARNs:
      - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

ちなみに Amazon EKS add-ons の Amazon CloudWatch Observability agent と記載された部分を見ると、 AWSXrayWriteOnlyAccess も付与して下さいと記載されておりますが、とりあえず Container Insights with Enhanced Observability を利用する分には不要のようです。
付与してみた場合でも今回メトリクスを確認する際には利用されていませんでした。

CloudWatchAgentServerPolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData",
                "ec2:DescribeVolumes",
                "ec2:DescribeTags",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams",
                "logs:DescribeLogGroups",
                "logs:CreateLogStream",
                "logs:CreateLogGroup"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameter"
            ],
            "Resource": "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
        }
    ]
}

AWSXrayWriteOnlyAccess

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "xray:PutTraceSegments",
                "xray:PutTelemetryRecords",
                "xray:GetSamplingRules",
                "xray:GetSamplingTargets",
                "xray:GetSamplingStatisticSummaries"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

また、今回は楽なので amazon-cloudwatch-observability アドオンを利用しましたが、従来通り Fluent Bit と CloudWatch エージェントをインストールしても、新しいダッシュボードビューを閲覧可能でした。
アドオンを使うかどうかではなく、CloudWatch エージェントの設定ファイルにある logs.metrics_collected.kubernetes.enhanced_container_insights が true になっているかどうかがポイントのようです。
今までの CloudWatch エージェントでも Upgrading to Container Insights with enhanced observability for Amazon EKS に沿って、パラメータを true にすれば Container Insights with enhanced observability for Amazon EKS を利用可能です。

新しいダッシュボードビューを見てみた

CloudWatch の Container Insights 欄から確認します。
パフォーマンスダッシュビューをクリックすることで各切り口ごとの細かいメトリクスを確認可能です。(名前空間ごと、Service ごと、Pod ごとなど)

パフォーマンスダッシュボードは、下記切り口で確認可能です。

  • Clusters
  • Namespaces
  • Nodes
  • Services
  • Workloads
  • Pods
  • Containers

下記は Clusters 全体の状況を確認するためのダッシュボードになります。

名前空間ごとでメトリクスを確認するダッシュボードもありました。

ノード単位でメトリクスを確認するダッシュボードもあります。

各ダッシュボードビューごとにフィルタが使えるので、ノードごとの Pod 一覧も確認できます。

Service ごとのメトリクスも確認可能です。
Service そのものというよりは、各 Service ごとのバックエンドにあたる Pod のメトリクスが確認可能という形のようです。(平均 CPU/ メモリ使用率, Pod 数)

Workloads ダッシュボードでは Kubernetes の workload リソースごとに各種メトリクスを確認可能です。

Pod のダッシュボードに関しては stress コマンドを利用して負荷をかける Pod をデプロイしつつ確認してみます。

FROM ubuntu:20.04
RUN apt-get update && apt-get install -y stress
ENTRYPOINT ["stress"]
CMD ["--verbose", "--vm", "1", "--vm-bytes", "512M"]

こんな感じで OOM に殺されます。

Containers:
  stress-container:
    Container ID:  containerd://7bbe99646507862ff6364ed9886d74f6e4c09f7e43c51e7f9ce437155dd6e7d7
    Image:         xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/stress-container
    Image ID:      xxxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/stress-container@sha256:f30d1f75896edeceef091385e695b04a0009d0defaed97c79eccfe1cc8e96ef8
    Port:          <none>
    Host Port:     <none>
    Args:
      --verbose
      --vm
      1
      --vm-bytes
      512M
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    1
      Started:      Sat, 11 Nov 2023 12:49:12 +0900
      Finished:     Sat, 11 Nov 2023 12:49:13 +0900
    Ready:          False
    Restart Count:  3
    Limits:
      cpu:     500m
      memory:  500Mi
    Requests:
      cpu:        100m
      memory:     400Mi

ダッシュボードで見ると、下記のようになります。

コンテナ再起動あたりは良い感じに見れているので、アラームを仕込んでも良いですね。
ちなみに、アドオンを追加しただけでもアプリケーションログを CloudWatch ロググループ /aws/containerinsights/クラスター名/application に転送できています。

$ kubectl logs stress-container-78fdffc677-klkqg -n apps
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 536870912 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (415) <-- worker 6 got signal 9
stress: WARN: [1] (417) now reaping child worker processes
stress: FAIL: [1] (421) kill error: No such process
stress: FAIL: [1] (451) failed run completed in 1s

ただ、現時点ではアプリケーションログを全部出力するか全部出力しないかの 2 択の様子なので、細かい設定が必要ならアドオンに頼らず Fluent Bit をインストールする必要があります。

By default, the add-on uses Fluent Bit to collect container logs from all pods and then sends the logs to CloudWatch Logs. For information about which logs are collected, see Setting up Fluent Bit. To disable the collection of container logs, pass the following option when you create or update the add-on: --configuration-values '{ "containerLogs": { "enabled": false } }'
Install the CloudWatch agent by using the Amazon CloudWatch Observability EKS add-on

コンテナマップも利用可能で、視覚的にわかりやすい形で負荷が高い部分を確認可能です。

コストについて

Amazon CloudWatch Pricing に記載されている通りですが、カスタムメトリクスの料金とログの取り込み料金を個別に考える必要がなくなりました。
どれだけのコンポーネントをデプロイしているかどうかでコストを見積もりやすくなっております。
価格体系が変わっているので比較し辛いですが、AWS 公式ブログに記載されている通り基本的には安くなるようです。
既に Container Insights を利用している場合は、現在デプロイしているコンポーネント数からの試算と現在かかっている料金を一度比較してみると良いかもしれません。

We are introducing a new unified pricing model for Amazon CloudWatch Container Insights on Amazon EKS that bundles metric storage and log ingestion into a single low-cost observation price point. This competitive pricing enables to provide enhanced observability by default, with no extra cost to collect additional metrics that fully monitor your clusters.
Announcing Amazon CloudWatch Container Insights with Enhanced Observability for Amazon EKS on EC2

まとめ

EKS on EC2 の監視については、要件に合ったダッシュボードを作成するには Prometheus + Grafana の方が楽と感じる場面もあったかと思います。
ただ、今回のアップデートで CloudWatch Container Insights の使い勝手が大きく向上しているので興味がある方は是非試してみて下さい!