When using Kubernetes APM auto-attach, you may want to add Java extension modules to enhance monitoring capabilities for specific libraries or frameworks not covered by the default Java agent instrumentation.
This guide shows you how to create a custom Docker image with Java extensions and integrate it with Kubernetes APM auto-attach.
Before you begin
Before adding Java extensions, ensure you have:
- Kubernetes APM auto-attach installed and configured
- Docker installed for building custom images
- Access to a container registry (Docker Hub, ECR, GCR, etc.)
- Permission to push images to the registry
- Knowledge of which Java extension modules you need
Overview
The process involves three main steps:
- Create a custom Docker image based on
newrelic/newrelic-java-init:latestwith your desired extensions - Build and push the image to your container registry
- Update your Kubernetes instrumentation to use the new image
Create custom Docker image with extensions
Create a Dockerfile
Create a new Dockerfile that extends the original New Relic Java init image and adds your desired extensions. Here's an example using the Kotlin coroutines extension:
# Start from the original New Relic Java init imageFROM newrelic/newrelic-java-init:latest
# Create the extensions directory in the rootRUN mkdir -p /extensions
# Example: Add Kotlin coroutines instrumentation# Download the latest version and extract to extensions directoryRUN VERSION=$(wget -q -O - https://api.github.com/repos/newrelic/newrelic-java-kotlin-coroutines/releases/latest | \ awk '/tag_name/{gsub(/,|"/,"",$2);print$2}') && \ wget -qO /tmp/kotlin-coroutines-instrumentation.zip \ "https://github.com/newrelic/newrelic-java-kotlin-coroutines/releases/download/$VERSION/kotlin-coroutines-instrumentation-$VERSION.zip" && \ unzip -j /tmp/kotlin-coroutines-instrumentation.zip "*.jar" -d /extensions && \ rm /tmp/kotlin-coroutines-instrumentation.zipTip
Replace the Kotlin coroutines example with the specific extensions you need. You can find available extensions in the Java extension modules documentation.
Build the Docker image
Build your custom image locally:
$docker build -t your-registry/{Your-Image-Name}Replace your-registry/{Your-Image-Name} with your actual container registry path and image name, for example, mycompany/newrelic-java-init-custom.
Push to container registry
Push the image to your container registry:
$docker push your-registry/{Your-Image-Name}Update Kubernetes instrumentation
Modify the instrumentation resource
Update your existing instrumentation Custom Resource (CR) to use the new image. Here's an example instrumentation-java.yaml:
apiVersion: newrelic.com/v1beta2kind: Instrumentationmetadata: name: newrelic-instrumentation-java namespace: newrelicspec: agent: language: java image: your-registry/{Your-Image-Name}Apply the updated instrumentation
Apply the updated instrumentation to your cluster:
$kubectl apply -f instrumentation-java.yamlRestart affected workloads
Restart your Java applications to pick up the new init container with extensions:
To restart a specific deployment:
bash$# Restart a specific deployment$kubectl rollout restart deployment/my-java-deploymentTo restart all deployments in a namespace:
bash$# Or restart all deployments in a namespace$kubectl rollout restart deployments -n my-namespace
Troubleshooting
Extensions not loading
If extensions aren't loading:
Verify the extensions directory exists in your custom image:
bash$docker run --rm your-registry/{Your-Image-Name} ls -la /extensionsCheck file permissions ensure extension JAR files are readable.
Review init container logs for any error messages during agent initialization.