APM Agent Setup with Kubernetes

kf-agent is a Kubernetes-native collector that receives OpenTelemetry traces from your instrumented applications over OTLP and forwards them to the Kloudfuse platform. It is deployed as a Kubernetes Deployment with a ClusterIP Service in the kloudfuse namespace, making it reachable from pods in other namespaces at http://kf-agent.kloudfuse:4317 (gRPC) or http://kf-agent.kloudfuse:4318 (HTTP).

Visual Guide

APM Kubernetes Agent Architecture — app pods send OTLP traces to kf-agent which forwards to the Kloudfuse platform

Prerequisites

  • Kubernetes 1.18 or later

  • Helm 3.x installed and configured against your cluster

  • A Kloudfuse API key with trace ingestion scope (see Administration → API Keys)

  • Outbound HTTPS access from the cluster to the Kloudfuse platform

  • At least one application instrumented with an OpenTelemetry SDK (see Java, Python, or Go)

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
bash

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>
bash

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
bash

Verify the Agent is Running

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

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
yaml

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
bash

The examples below show the minimal changes needed per language. See the linked setup guides for full configuration options.

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
yaml

See Java Kubernetes Integration for the full init container pattern that copies the agent JAR without baking it into your image.

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
bash

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
yaml

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(),
)
go

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
bash
// Use otlptracegrpc.WithEndpointURL to read OTEL_EXPORTER_OTLP_ENDPOINT automatically
exporter, err := otlptracegrpc.New(ctx)
go

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.