APM Agent Setup with Kubernetes :: Kloudfuse Docs

APM Agent Setup with Kubernetes

Visual Guide

Prerequisites

Supported Environments

kf-agent runs on any conformant Kubernetes distribution:

Platform Notes
Amazon EKS Supported; enable AWS resource detection with resourceDetection.aws.enabled=true
Google GKE Supported; enable GCP resource detection with resourceDetection.gcp.enabled=true
Azure AKS Supported; enable Azure resource detection with resourceDetection.azure.enabled=true
OpenShift Supported; set securityContext.runAsNonRoot=true and configure an appropriate SCC
Self-managed (kubeadm, k3s, RKE) Supported without additional configuration

Step 1: Install kf-agent

Add the Helm Repository

helm repo add kloudfuse https://helm.kloudfuse.com
helm repo update

Deploy the Agent

Install kf-agent into a dedicated namespace. Replace <your-kloudfuse-api-key> with your API key and <my-cluster> with a name that identifies this cluster in the Kloudfuse UI:

helm install kf-agent kloudfuse/kf-agent \
  --namespace kloudfuse \
  --create-namespace \
  --set clusterName=my-cluster \
  --set apiKey=<your-kloudfuse-api-key>

To avoid embedding the API key in shell history or CI logs, pass it from a Kubernetes Secret:

kubectl create secret generic kloudfuse-api-key \
  --namespace kloudfuse \
  --from-literal=value=<your-kloudfuse-api-key>

helm install kf-agent kloudfuse/kf-agent \
  --namespace kloudfuse \
  --create-namespace \
  --set clusterName=my-cluster \
  --set apiKeySecretName=kloudfuse-api-key

Verify the Agent is Running

kubectl get pods -n kloudfuse -l app=kf-agent
kubectl logs -n kloudfuse -l app=kf-agent --tail=50

The agent is ready when the pod is in Running state and logs show Listening on :4317 (gRPC) and Listening on :4318 (HTTP).

Key Helm Values

Value Description Default
clusterName Cluster identifier shown in Kloudfuse UI service maps and resource attributes. ""
apiKey Kloudfuse API key for trace ingestion. Use apiKeySecretName instead in production. ""
apiKeySecretName Name of a Kubernetes Secret containing the API key under the value key. ""
replicaCount Number of agent replicas. Increase for high-throughput clusters. 1
resources.requests.memory Minimum memory for the agent pod. 256Mi
resources.limits.memory Maximum memory for the agent pod. 512Mi
service.grpcPort Port for OTLP/gRPC receiver. 4317
service.httpPort Port for OTLP/HTTP receiver. 4318
resourceDetection.aws.enabled Auto-detect EC2, ECS, EKS resource attributes. false
resourceDetection.gcp.enabled Auto-detect GCE, GKE, Cloud Run resource attributes. false
resourceDetection.azure.enabled Auto-detect Azure VM and AKS resource attributes. false

Network Requirements

Application pods must be able to reach kf-agent on two ports:

Port Protocol Used by
4317 OTLP/gRPC Java agent, Go otlptracegrpc, Python gRPC exporter (default)
4318 OTLP/HTTP (protobuf or JSON) Any SDK configured with OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

If your cluster enforces NetworkPolicy, add an egress rule allowing application pods to reach kf-agent on both ports:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-kf-agent-egress
  namespace: <app-namespace>
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kloudfuse
      ports:
        - port: 4317
          protocol: TCP
        - port: 4318
          protocol: TCP

Step 2: Instrument Your Applications

Set these two environment variables on every application pod to point it at kf-agent:

OTEL_SERVICE_NAME=my-service
OTEL_EXPORTER_OTLP_ENDPOINT=http://kf-agent:4317

Java

Use JAVA_TOOL_OPTIONS to attach the OpenTelemetry Java agent without modifying the container entrypoint:

env:
  - name: JAVA_TOOL_OPTIONS
    value: "-javaagent:/agent/opentelemetry-javaagent.jar"
  - name: OTEL_SERVICE_NAME
    value: my-java-service
  - name: OTEL_EXPORTER_OTLP_ENDPOINT
    value: http://kf-agent:4317
  - name: OTEL_RESOURCE_ATTRIBUTES
    value: service.namespace=payments,deployment.environment.name=production

Python

Run your application through the opentelemetry-instrument wrapper and set the endpoint via environment variable:

opentelemetry-instrument \
  --traces_exporter otlp \
  --exporter_otlp_endpoint http://kf-agent:4317 \
  --service_name my-python-service \
  python app.py

Or configure entirely via environment variables in the pod spec:

env:
  - name: OTEL_SERVICE_NAME
    value: my-python-service
  - name: OTEL_EXPORTER_OTLP_ENDPOINT
    value: http://kf-agent:4317
  - name: OTEL_TRACES_EXPORTER
    value: otlp

Go

Configure the otlptracegrpc exporter to point at kf-agent on port 4317:

import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"

exporter, err := otlptracegrpc.New(ctx,
    otlptracegrpc.WithEndpoint("kf-agent:4317"),
    otlptracegrpc.WithInsecure(),
)

Or read the endpoint from an environment variable so it can be set in the pod spec without changing code:

# Pod spec env
OTEL_SERVICE_NAME=my-go-service
OTEL_EXPORTER_OTLP_ENDPOINT=http://kf-agent:4317
// Use otlptracegrpc.WithEndpointURL to read OTEL_EXPORTER_OTLP_ENDPOINT automatically
exporter, err := otlptracegrpc.New(ctx)

Step 3: Verify Trace Collection

  1. Open Kloudfuse UI → APM → Trace Explorer
  2. In the search bar, filter by service.name = <your-service-name>
  3. Send a test request to your application — a trace should appear within a few seconds
  4. Click the trace to verify span names, attributes, and parent-child relationships
  5. Open APM → Service Map to confirm inter-service dependencies are visible

If traces do not appear, see Common Setup Issues for diagnostic steps.