Kubernetes Infrastructure
Deploy Maple's Kubernetes infrastructure collector with Helm to stream host, kubelet, and cluster metrics — and wire the service map's Infrastructure tab to your workloads.
Maple ships a small Helm chart — maple-k8s-infra — that collects host, kubelet, and cluster metrics from your Kubernetes cluster over OpenTelemetry and streams them to Maple. Once it’s running, the Infrastructure section lights up with your pods, nodes, and workloads, and the service map gains a pod-count badge plus an Infrastructure tab on each service.
The chart uses a split-collector architecture:
- a DaemonSet for node-local OTLP, host metrics, kubelet/pod metrics, and optional pod logs
- a single-replica Deployment for cluster-wide metrics and optional Kubernetes events
All signals are exported over OTLP HTTP to Maple’s ingest gateway. The collector never writes to the warehouse directly — the gateway handles ingest-key auth and org enrichment.
Prerequisites
kubectlandhelm(v3.8+, for OCI registry support) pointed at the target cluster- Cluster-admin (the chart installs RBAC and, by default, the OpenTelemetry Operator)
- A private ingest key — copy it from Settings → Ingestion in the Maple UI
Install
The fastest path is the install script, which creates the namespace + ingest-key Secret and runs Helm for you. It prints your active kubectl context and asks for confirmation first (set MAPLE_INSTALL_YES=1 to skip):
curl -fsSL https://raw.githubusercontent.com/Makisuo/maple/main/deploy/k8s-infra/install.sh | \
MAPLE_INGEST_KEY=YOUR_MAPLE_INGEST_KEY \
MAPLE_CLUSTER_NAME=production \
bash
Prefer Helm directly? Install the published OCI chart:
helm upgrade --install maple-k8s-infra \
oci://ghcr.io/makisuo/charts/maple-k8s-infra \
--namespace maple --create-namespace \
--set-string maple.ingestKey.value=YOUR_MAPLE_INGEST_KEY \
--set-string global.clusterName=production
For production, keep the key out of your Helm values and reference an existing Secret instead:
kubectl create namespace maple
kubectl -n maple create secret generic maple-ingest-key \
--from-literal=ingest-key=YOUR_MAPLE_INGEST_KEY
helm upgrade --install maple-k8s-infra \
oci://ghcr.io/makisuo/charts/maple-k8s-infra \
--namespace maple \
--set maple.ingestKey.existingSecret.name=maple-ingest-key \
--set maple.ingestKey.existingSecret.key=ingest-key \
--set-string global.clusterName=production
Confirm the rollout:
kubectl -n maple rollout status daemonset/maple-k8s-infra-agent
kubectl -n maple rollout status deployment/maple-k8s-infra-cluster
Self-hosted Maple
The chart defaults to the hosted gateway (https://ingest.maple.dev). If you run Maple yourself, point the collector at your own ingest endpoint by adding:
--set-string maple.ingest.endpoint=https://your-ingest.example.com
What gets collected
Enabled by default:
- Host metrics — CPU, memory, disk, network, and load per node (powers the Infrastructure → Hosts views)
- Kubelet/pod metrics — per-pod CPU usage, CPU/memory limit and request utilization
- Cluster metrics — node conditions, pod phases, deployment availability, namespace phases
- OTLP receivers — gRPC
:4317and HTTP:4318on every node, so in-cluster apps can send traces, logs, and metrics to the local agent
Off by default (enable per your ingestion budget):
presets:
podLogs:
enabled: true
k8sEvents:
enabled: true
fargateMetrics: # EKS Fargate per-pod CPU/memory
enabled: true
In-cluster apps can export to the agent’s Service:
OTLP gRPC: maple-k8s-infra-agent.maple.svc:4317
OTLP HTTP: http://maple-k8s-infra-agent.maple.svc:4318
Verify data is arriving
Within about a minute of a healthy rollout:
- Open Infrastructure in Maple — your nodes should appear with live CPU/memory/disk, and the Kubernetes → Pods / Nodes / Workloads views should populate.
- If a view stays empty, check the agent logs:
kubectl -n maple logs -l app.kubernetes.io/component=agent --tail=200.
Hosted Maple: the Infrastructure feature is gated per organization during rollout. If you don’t see it, ask your Maple contact to enable
infra_monitoringfor your org. Self-hosted and local installs have it on by default.
Wire the service map’s Infrastructure tab
To get a pod-count badge and an Infrastructure tab on each service node (correlating your app traces to the workload running them), opt a namespace into env-var injection:
kubectl annotate namespace shop \
instrumentation.opentelemetry.io/inject-sdk=maple/maple-default
kubectl rollout restart deployment -n shop
The chart bundles the OpenTelemetry Operator and an Instrumentation/maple-default resource that injects downward-API env vars (OTEL_EXPORTER_OTLP_ENDPOINT + pod IP/UID/name/namespace/node into OTEL_RESOURCE_ATTRIBUTES). Your app’s existing OpenTelemetry SDK reads those on startup; the agent’s k8sattributes processor then enriches each span with k8s.deployment.name / k8s.statefulset.name / k8s.daemonset.name, closing the service.name → workload join.
This injects env vars only — it does not add an SDK to your app. Your service must already emit OTLP spans, and its SDK must read the standard OTEL_* env vars (most auto-instrumentation agents and Maple’s own SDK do). To opt many namespaces in at install time, list them under autoInstrumentation.instrumentation.autoInstrumentNamespaces instead of annotating each one.
Per-cloud notes
| Distribution | Notes |
|---|---|
| EKS standard, GKE Standard, AKS | Works out of the box. |
| EKS Fargate | The DaemonSet can’t run on Fargate nodes. Keep one EC2 node for the agent, and set presets.fargateMetrics.enabled=true so per-pod CPU/memory is scraped via the API-server proxy. |
| GKE Autopilot | Only annotate your own namespaces — mutating webhooks are rejected on Google-managed namespaces. |
| k3s / kind / k0s | Works with auto-generated webhook certs (no cert-manager needed). |
| Service mesh (Linkerd, Istio) | Sidecars rewrite source IPs, but the k8s.pod.uid / (name, namespace) association keys ride inside the OTLP payload and rescue the workload join. No mesh-side config needed. |
Troubleshooting
- No hosts/pods after a few minutes — confirm both workloads are
Readyand look fork8sattributesor exporter errors inkubectl -n maple logs -l app.kubernetes.io/component=agent. - Empty Infrastructure tab on a service — the namespace annotation wasn’t applied or the pods weren’t restarted, or your SDK ignores
OTEL_*env vars. Verify withkubectl exec -n <ns> <pod> -- env | grep OTEL. - Operator webhook crash-looping — usually a cert issue. Switch to cert-manager with
opentelemetryOperator.admissionWebhooks.certManager.enabled=trueif your cluster requires it.
Already running the OpenTelemetry Operator yourself? Set autoInstrumentation.operator.enabled=false — the Instrumentation resource still renders so you can apply it into your own setup.
Uninstall
helm uninstall maple-k8s-infra --namespace maple
To stop env-var injection for a namespace without uninstalling, remove the annotation and restart:
kubectl annotate namespace shop instrumentation.opentelemetry.io/inject-sdk-
kubectl rollout restart deployment -n shop