DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Optimizing Java Applications for Arm64 in the Cloud
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Java Backend Development in the Era of Kubernetes and Docker
  • The Invisible OOMKill: Why Your Java Pod Keeps Restarting in Kubernetes

Trending

  • A Scalable Framework for Enterprise Salesforce Optimization: Turning Outcomes Into an Operating System
  • MuleSoft MCP and A2A in Production: What 17 Recipes Reveal
  • AWS Managed Database Observability: Monitoring DynamoDB, ElastiCache, and Redshift Beyond CloudWatch
  • Real-Time AI Inference at Scale Using Cloud Run, GPUs, and Vertex AI
  1. DZone
  2. Coding
  3. Java
  4. Monitoring Java Microservices on EKS Using New Relic APM and Kubernetes Metrics

Monitoring Java Microservices on EKS Using New Relic APM and Kubernetes Metrics

Monitor Java microservices on Amazon EKS using New Relic APM. Set up JVM agents, tune GC settings, and track Kubernetes metrics with dashboards and alerts.

By 
Praveen Chaitanya Jakku user avatar
Praveen Chaitanya Jakku
·
Sep. 02, 25 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
3.4K Views

Join the DZone community and get the full member experience.

Join For Free

Amazon EKS makes running containerized applications easier, but it doesn’t give you automatic visibility into JVM internals like memory usage or garbage collection. For Java applications, observability requires two levels of integration:

  • Cluster-level monitoring for pods, nodes, and deployments
  • JVM-level APM instrumentation for heap, GC, threads, latency, etc.

New Relic provides both via Helm for infrastructure metrics, and a lightweight Java agent for full JVM observability.

In containerized environments like Kubernetes, surface-level metrics (CPU, memory) aren’t enough. For Java apps, especially those built on Spring Boot, the real performance story lies inside the JVM. Without insight into heap usage, GC behavior, and thread activity, you're flying blind.

New Relic bridges this gap by combining infrastructure-level monitoring (via Prometheus and kube-state-metrics) with application-level insights from the JVM agent. This dual visibility helps teams reduce mean time to resolution (MTTR), avoid OOMKilled crashes, and tune performance with confidence.

This tutorial covers:

  • Installing New Relic on EKS via Helm
  • Instrumenting your Java microservice with New Relic’s Java agent
  • JVM tuning for container environments
  • Monitoring GC activity and memory usage
  • Creating dashboards and alerts in New Relic
  • Optional values.yaml file, YAML bundle, and GitHub repo

Architecture of JVM monitoring on Amazon EKS using New Relic.

Figure 1: Architecture of JVM monitoring on Amazon EKS using New Relic.


The Java microservice runs inside an EKS pod with the New Relic JVM agent attached. It sends GC, heap, and thread telemetry to New Relic APM. At the same time, Prometheus collects Kubernetes-level metrics, which are forwarded to New Relic for unified observability.

Prerequisites

  • Amazon EKS cluster with kubectl and helm configured
  • A Java-based app (e.g., Spring Boot) deployed in EKS
  • New Relic account (free tier is enough)
  • Basic understanding of JVM flags and Kubernetes manifests

Install New Relic’s Kubernetes Integration (Helm)

This installs the infrastructure monitoring components for cluster, pod, and container-level metrics.

Step 1: Add the New Relic Helm repository

Shell
 
helm repo add newrelic https://helm-charts.newrelic.com
helm repo update


Step 2: Install the monitoring bundle

Shell
 
helm install newrelic-bundle newrelic/nri-bundle \
  --set global.licenseKey=<NEW_RELIC_LICENSE_KEY> \
  --set global.cluster=<EKS_CLUSTER_NAME> \
  --namespace newrelic --create-namespace \
  --set newrelic-infrastructure.enabled=true \
  --set kube-state-metrics.enabled=true \
  --set prometheus.enabled=true


Replace <NEW_RELIC_LICENSE_KEY> and <EKS_CLUSTER_NAME> with your actual values.

Instrument Your Java Microservice With the New Relic Agent

Installing the Helm chart sets up cluster-wide observability, but to monitor JVM internals like heap usage, thread activity, or GC pauses, you need to attach the New Relic Java agent.

This gives you:

  • JVM heap, GC, thread metrics
  • Response times, error rates, transaction traces
  • GC pauses and deadlocks

Dockerfile (add agent):

Dockerfile
 
ADD https://download.newrelic.com/newrelic/java-agent/newrelic-agent/current/newrelic-java.zip /opt/
RUN unzip /opt/newrelic-java.zip -d /opt/


JVM startup args:

Shell
 
-javaagent:/opt/newrelic/newrelic.jar


Required environment variables:

YAML
 
- name: NEW_RELIC_APP_NAME
  value: your-app-name
- name: NEW_RELIC_LICENSE_KEY
  valueFrom:
    secretKeyRef:
      name: newrelic-license
      key: license_key


Create the secret:

Shell
 
kubectl create secret generic newrelic-license \
   --from-literal=license_key=<YOUR_NEW_RELIC_LICENSE_KEY>


Capture Kubernetes Metrics

New Relic Helm install includes:

  • newrelic-infrastructure → Node, pod, container metrics
  • kube-state-metrics → Kubernetes objects
  • prometheus-agent → Custom metrics support

Verify locally:

Shell
 
kubectl top pods
kubectl top nodes


In New Relic UI, go to: Infrastructure → Kubernetes

JVM Tuning for GC and Containers

To avoid OOMKilled errors and track GC behavior, tune your JVM for Kubernetes:

Recommended JVM Flags:

Shell
 
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=75.0
-XshowSettings:vm
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/tmp/gc.log


Make sure /tmp is writable or mount it via emptyDir.

Pod resources:

YAML
 
resources:
  requests:
    memory: "512Mi"
    cpu: "250m"
  limits:
    memory: "1Gi"
    cpu: "500m"


Align MaxRAMPercentage with limits.memory.

Why JVM Monitoring Matters in Kubernetes

Kubernetes enforces resource limits on memory and CPU, but by default, the JVM doesn’t respect those boundaries. Without proper tuning, the JVM might allocate more memory than allowed, triggering OOMKilled errors.

Attaching the New Relic Java agent gives you visibility into GC pauses, heap usage trends, and thread health all of which are critical in autoscaling microservice environments. With these insights, you can fine-tune JVM flags like `MaxRAMPercentage`, detect memory leaks early, and make data-driven scaling decisions.

Dashboards and Alerts in New Relic

Create an alert for GC pause time:

  • Go to Alerts & AI → Create alert
  • Select metric: JVM > GC > Longest GC pause
  • Set threshold: e.g., pause > 1000 ms

Suggested Dashboards:

  • JVM heap usage
  • GC pause trends
  • Pod CPU and memory usage
  • Error rate and latency

Use New Relic’s dashboard builder or import JSON from your repo.

Forwarding GC Logs to Amazon S3

While New Relic APM provides GC summary metrics, storing full GC logs is helpful for deep memory analysis, tuning, or post-mortem debugging. Since container logs are ephemeral, the best practice is to forward these logs to durable storage like Amazon S3.

Why S3?

  • Persistent log storage beyond pod restarts
  • Useful for memory tuning, forensic reviews, or audits
  • Cost-effective compared to real-time log ingestion services

Option: Use Fluent Bit with S3 Output Plugin

1. Enable GC logging with: 

Shell
 
-Xloggc:/tmp/gc.log


2. Mount /tmp with emptyDir in your pod

3. Deploy Fluent Bit as a sidecar or DaemonSet

Make sure your pod or node has an IAM role with s3:PutObject permission to the target bucket. 

This setup ensures your GC logs are continuously shipped to S3 for safe, long-term retention even after the pod is restarted or deleted.

Troubleshooting Tips

Problem

Fix

APM data not showing

Verify license key, agent path, app traffic

JVM metrics missing

Check -javaagent setup and environment vars

GC logs not collected

Check -Xloggc path, permissions, volume mount

Kubernetes metrics missing

Ensure Prometheus is enabled in Helm values


Check logs with:

Shell
 
kubectl logs <pod-name> --container <container-name>


Conclusion

New Relic allows you to unify infrastructure and application observability in Kubernetes environments. With JVM insights, GC visibility, and proactive alerts, DevOps and SRE teams can detect and resolve performance issues faster.

After setting up JVM and Kubernetes monitoring, consider enabling distributed tracing to get visibility across service boundaries. You can also integrate New Relic alerts with Slack, PagerDuty, or Opsgenie to receive real-time incident notifications.

Finally, use custom dashboards to compare performance across dev, staging, and production environments, helping your team catch regressions early and optimize for reliability at scale.

Java virtual machine Kubernetes Java (programming language) Metric (unit)

Opinions expressed by DZone contributors are their own.

Related

  • Optimizing Java Applications for Arm64 in the Cloud
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Java Backend Development in the Era of Kubernetes and Docker
  • The Invisible OOMKill: Why Your Java Pod Keeps Restarting in Kubernetes

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook