How to Monitor Amazon EKS with CloudWatch: Metrics, Logs, and Alerts

EKS does not send metrics or logs to CloudWatch by default. Once you deploy workloads, you are blind until you install the right agents. This guide shows you the AWS-native path: what to install, what each component collects, how to verify the setup is actually working, and which five alerts to create first.

What EKS monitoring actually means#

Think of it this way

Imagine running a warehouse with no cameras, no temperature sensors, and no shift reports. Products ship, forklifts move, and workers show up — but if something breaks down, nobody knows until a customer calls to complain. EKS without monitoring is exactly that warehouse. Your pods start, containers crash, nodes run out of memory, and the only signal is a user ticket saying “the site is down.”

Monitoring a Kubernetes cluster is not one thing. It is four distinct concerns that are easy to blur together:

A useful monitoring setup covers all four. The CloudWatch Observability EKS add-on with Fluent Bit gives you the first three in one step. Alerts are a separate, intentional step on top.

When to use this approach#

Good fit for you if…

Your team works in the AWS Console, you are running a small to medium cluster (roughly 1 to 30 nodes), and you want full visibility without managing a self-managed Prometheus server. This is the lowest-friction path to EKS observability.

The AWS-native CloudWatch setup is the right starting point when:

If you eventually need application-level metrics (request rate, error rate, latency percentiles from your own services) or PromQL-style querying, Prometheus or Amazon Managed Service for Prometheus (AMP) can layer on top. CloudWatch is still the right place to start. For the broader tool-choice decision, see the EKS Monitoring Guide: CloudWatch, Prometheus and Grafana.

How EKS monitoring in AWS works#

Five components work together to give you full visibility:

The add-on handles the agent and Fluent Bit. kube-state-metrics and control plane logs are separate steps. For more background on EKS itself, see the Amazon EKS Overview.

ComponentWhat it collectsHow to install
CloudWatch agent (DaemonSet)Node and pod utilization metricsCloudWatch Observability add-on
Fluent Bit (DaemonSet)Container logs to CloudWatch LogsCloudWatch Observability add-on
kube-state-metricsKubernetes state signalsHelm chart (separate step)
EKS control plane logsAPI server, audit, scheduler logsaws eks update-cluster-config
CloudWatch AlarmsAlerts when metrics cross thresholdsCreated manually per signal

The add-on gets you metrics and logs in one command. The remaining three each require one extra step.

Fastest install path: CloudWatch Observability EKS add-on#

The Amazon CloudWatch Observability EKS add-on is the current recommended way to install Container Insights on EKS. It replaces the older manual DaemonSet manifest path and handles upgrades automatically through the EKS add-on lifecycle.

Step 1: Set up IAM permissions with EKS Pod Identity#

The add-on’s service account needs permission to publish metrics and logs to CloudWatch. EKS Pod Identity is the current AWS-recommended approach. IAM Roles for Service Accounts (IRSA) also works and is widely used on existing clusters:

# Create the IAM role
aws iam create-role \
  --role-name EKSCloudWatchObservabilityRole \
  --assume-role-policy-document file://eks-pod-identity-trust-policy.json

# Attach the managed policy
aws iam attach-role-policy \
  --role-name EKSCloudWatchObservabilityRole \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

# Associate the role with the add-on service account via Pod Identity
aws eks create-pod-identity-association \
  --cluster-name my-cluster \
  --namespace amazon-cloudwatch \
  --service-account cloudwatch-agent \
  --role-arn arn:aws:iam::123456789012:role/EKSCloudWatchObservabilityRole

Step 2: Install the add-on#

aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name amazon-cloudwatch-observability \
  --region us-east-1

That single command deploys the CloudWatch agent DaemonSet and Fluent Bit DaemonSet in the amazon-cloudwatch namespace. Metrics start appearing in Container Insights within a few minutes.

What about the old manual DaemonSet path?

If you cannot use the managed add-on, for example on a self-managed node group or a non-standard setup, AWS provides raw manifests in the amazon-cloudwatch-container-insights GitHub repository. For standard EKS clusters, the add-on is significantly easier to maintain and is the recommended path.

Step 3: Enable EKS control plane logs#

Control plane logs are separate from Container Insights and must be enabled per cluster. Enable all five types unless you have a specific reason not to:

aws eks update-cluster-config \
  --name my-cluster \
  --region us-east-1 \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
Do this before the logs arrive, not after

Audit logs on a busy cluster can generate several gigabytes per day. CloudWatch Logs groups never expire by default. Set a retention policy on the log groups before enabling control plane logging. Teams that skip this step often discover the oversight when their AWS bill arrives.

kube-state-metrics adds Kubernetes state signals that the CloudWatch agent alone does not collect. Install it via Helm (see the Helm Package Manager guide if you are new to Helm):

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install kube-state-metrics prometheus-community/kube-state-metrics \
  --namespace kube-system

What each component collects#

CloudWatch agent: Container Insights metrics#

Metrics land in the ContainerInsights CloudWatch namespace with dimensions for cluster, node, namespace, pod, and container:

You can view these in the CloudWatch console under Insights > Container Insights, or query them via the AWS CLI and CloudWatch Dashboards.

Fluent Bit: container log forwarding#

Fluent Bit reads /var/log/containers/ on each node and routes logs to three CloudWatch Logs groups:

For searching and querying these log groups, see CloudWatch Logs. For more on how Kubernetes log forwarding works, see Logging in Kubernetes.

kube-state-metrics: Kubernetes state signals#

Why this is different from the CloudWatch agent

The CloudWatch agent measures how hard your nodes are working, like a heart rate monitor. kube-state-metrics reads the Kubernetes API and reports what the cluster thinks is true: whether pods are Running or Stuck, whether your deployment has the right number of replicas, whether any jobs have failed. A node can have perfectly normal CPU and memory while a deployment quietly has zero healthy pods. You need both views.

State signals that the CloudWatch agent does not see directly:

These metrics are in Prometheus format. They pair well with the CloudWatch agent for alerting on Kubernetes state and become the foundation if you later add Prometheus or AMP.

EKS control plane logs#

Logs from the components that AWS manages for you:

These land in CloudWatch Logs and are queryable with CloudWatch Logs Insights. Audit logs are especially useful for security investigations. See Securing EKS Clusters for the full security picture.

How to verify it is working#

After installing the add-on, work through this checklist before moving on.

1. Check the add-on pods are running:

kubectl get pods -n amazon-cloudwatch
# You should see cloudwatch-agent-* and fluent-bit-* pods, one per node

2. Check the CloudWatch agent logs for errors:

kubectl logs -n amazon-cloudwatch -l name=cloudwatch-agent --tail=20
# Look for: "Starting input plugins" with no ERROR lines

3. Check Fluent Bit logs for errors:

kubectl logs -n amazon-cloudwatch -l k8s-app=fluent-bit --tail=20
# Look for successful flush output lines with no ERROR lines

4. Verify metrics appear in Container Insights:

Open the AWS Console, navigate to CloudWatch, then Insights, then Container Insights. Select your cluster. If metrics are present, the agent is working. Allow 2 to 5 minutes after installation.

5. Verify log groups exist in CloudWatch Logs:

aws logs describe-log-groups \
  --log-group-name-prefix "/aws/containerinsights/my-cluster" \
  --region us-east-1

You should see the /application, /host, and /dataplane log groups.

6. Quick metric check via AWS CLI:

aws cloudwatch list-metrics \
  --namespace ContainerInsights \
  --region us-east-1 \
  --query "Metrics[?Dimensions[?Name=='ClusterName' && Value=='my-cluster']] | [0:5]"
If metrics are missing

The most common cause is missing IAM permissions. The agent pods start without error but silently fail to publish metrics if the service account role is not set up correctly. Check kubectl logs on a cloudwatch-agent pod and look for permission-related errors before checking anything else.

What to alert on first#

Start with five high-signal alerts. Get these working well before adding more. Alerts you trust are more useful than twenty alerts that engineers have learned to dismiss.

SignalStarter thresholdWhy it matters
Pod restart countMore than 3 restarts in 10 minutesCatches crash loops from application errors or resource exhaustion
Pending podsAny pod pending more than 5 minutesScheduling failure: not enough capacity or a node selector mismatch
Node memory utilizationAbove 85% for 5 minutesSustained memory pressure leads to OOMKill events without warning
Node CPU utilizationAbove 85% for 5 minutesCPU throttling affects all pods on a node, not just the busiest one
Node not readyAny node in NotReady state for 2 minutesNode has lost contact with the control plane or has a critical problem

For step-by-step instructions on creating these in CloudWatch, see Creating Alerts in CloudWatch.

If your pods have started crash-looping and you are not sure why, see EKS CrashLoopBackOff Explained for a diagnostic flow.

Cost and retention basics#

This catches teams off guard

Container Insights is not free, and CloudWatch Logs groups never expire by default. Teams that enable full control plane logging without setting retention policies regularly find unexpected costs on their AWS bill. The fix takes two minutes. Do it on day one.

The main cost drivers are:

Set retention on all Container Insights log groups on day one:

# Application logs: 30 days is typical
aws logs put-retention-policy \
  --log-group-name "/aws/containerinsights/my-cluster/application" \
  --retention-in-days 30 \
  --region us-east-1

# Audit logs: 90 days is a common compliance baseline
aws logs put-retention-policy \
  --log-group-name "/aws/eks/my-cluster/cluster" \
  --retention-in-days 90 \
  --region us-east-1

Enable control plane log types selectively. Audit logs are the most valuable for security but also the most expensive on a busy cluster. Enable only what you have a plan for.

CloudWatch vs Prometheus vs AMP#

SituationRecommendation
New to EKS, AWS-first team, 1 to 15 nodesCloudWatch Observability add-on is enough
Need app-level metrics from your own servicesAdd Prometheus via kube-prometheus-stack
Multi-cluster or long-term metric retentionAmazon Managed Service for Prometheus (AMP)
Compliance or security-sensitive environmentCloudWatch for audit logs plus Prometheus or AMP for metrics
Minimal operational overhead is the priorityCloudWatch only

This page covers the CloudWatch path in depth. For a full comparison of all three options, including setup examples for Prometheus and AMP, see the EKS Monitoring Guide: CloudWatch, Prometheus and Grafana.

Common beginner mistakes

  1. Using the old manual DaemonSet path instead of the add-on. The raw manifest approach from older AWS docs still works but requires you to manage upgrades manually. The CloudWatch Observability add-on handles upgrades through the EKS add-on lifecycle and is the current recommended path.

  2. Forgetting IAM permissions for the CloudWatch agent. The agent pods will start without error but fail silently if the service account does not have the right permissions. Always check kubectl logs on a cloudwatch-agent pod if metrics are not appearing after installation.

  3. Not setting a log retention policy. CloudWatch Logs groups never expire by default. Set retention on all Container Insights log groups before the first logs arrive, not once you notice the bill.

  4. Monitoring only at the cluster level. Cluster-level averages can hide hot spots. A cluster averaging 50% CPU can have one node at 95% and another at 5%. Monitor at the node and pod level too.

  5. Treating pod restarts as noise. Repeated container restarts are a serious warning sign. Set an alarm on restart counts early. Crash loops that are ignored tend to escalate. See EKS CrashLoopBackOff Explained for how to diagnose them.

  6. Running all workloads in the default namespace. Container Insights breaks down metrics by namespace. If all your applications live in default, you lose team-level and application-level visibility. Use dedicated namespaces.

Frequently asked questions

Do I need Prometheus if I already use CloudWatch Container Insights?

Not necessarily. CloudWatch Container Insights covers infrastructure metrics, Kubernetes state metrics, and log forwarding with minimal setup. Prometheus becomes worthwhile when you need application-level metrics exposed by your own services (request rate, error rate, latency percentiles), PromQL-based querying, or community dashboards. Many teams start with CloudWatch and add Prometheus or AMP later once they know what they actually need to measure.

What does CloudWatch Container Insights collect?

Container Insights collects metrics at five levels: cluster (total CPU and memory across all nodes), node (per-EC2-instance utilization), namespace (resource use broken down by Kubernetes namespace), pod (CPU, memory, network, and disk per pod), and container (utilization inside each container). All metrics land in the ContainerInsights CloudWatch namespace and are visible in the pre-built Container Insights dashboards in the CloudWatch console.

How do I monitor EKS logs?

Container logs (stdout and stderr from your pods) are forwarded to CloudWatch Logs by Fluent Bit, which the CloudWatch Observability EKS add-on installs automatically as a DaemonSet on each node. Logs land in /aws/containerinsights/CLUSTER_NAME/application. EKS control plane logs (API server, audit, scheduler) are a separate category and must be enabled per cluster using the aws eks update-cluster-config command.

What should I alert on first in EKS?

Start with five high-signal alerts: pod restart count (crash loops), pending pods (scheduling failures), node memory utilization above 85%, node CPU utilization above 85%, and node not ready. These catch the most common early problems without generating noise. Tune the thresholds once you have a few days of baseline data from your actual cluster.

When should I move beyond CloudWatch-only monitoring?

CloudWatch is a good fit for beginners, AWS-first teams, and small to medium clusters. Consider adding Prometheus or Amazon Managed Service for Prometheus (AMP) when you need application-level metrics from your own services, PromQL for complex queries, multi-cluster metric aggregation, or a community dashboard ecosystem. CloudWatch and Prometheus are not mutually exclusive. Hybrid setups that use CloudWatch for audit logs and Prometheus for app metrics are common in production.

Last verified: 3 May 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.