Agent on Kubernetes
The agent ships as a Helm chart published as an OCI artifact. It deploys the collector plus all three co-located local stores — VictoriaMetrics (metrics), Loki (logs), and Tempo (traces) — each as its own workload, all enabled by default in central mode.
Install
Section titled “Install”You need your tenant name and an agent key from the LeanSignal app (Agents → Add Agent).
helm upgrade --install leansignal-agent \ oci://ghcr.io/leansignal/charts/leansignal-agent \ --namespace leansignal --create-namespace \ --set leansignal.tenant="YOUR_TENANT" \ --set leansignal.agentKey.value="YOUR_KEY"To keep the key out of your values, reference an existing Secret:
leansignal: tenant: YOUR_TENANT agentKey: existingSecret: my-agent-secret existingSecretKey: agent-keyleansignal.agentName sets the leansignal_agent_name label; leave it unset and
it defaults to the Kubernetes node name.
On Kubernetes the agent collects cluster and node metrics (the k8s_cluster and
kubeletstats receivers) and accepts OTLP from your workloads.
What gets created
Section titled “What gets created”Resource names come from the chart’s fullname helper, which always prefixes the
release name. Installing with the release name leansignal-agent therefore
produces the doubled leansignal-agent-leansignal-agent:
| Workload | Name (release leansignal-agent) |
|---|---|
| Deployment + ConfigMap + Service (collector) | leansignal-agent-leansignal-agent |
| Deployment + ConfigMap + Service (local Loki) | leansignal-agent-leansignal-agent-loki |
| Deployment + ConfigMap + Service (local Tempo) | leansignal-agent-leansignal-agent-tempo |
| StatefulSet + Service (local VictoriaMetrics) | leansignal-agent-victoria-metrics-single-server |
Plus a ServiceAccount, a ClusterRole/Binding for the cluster and kubelet receivers, and a Secret unless you supply one.
Configure
Section titled “Configure”Configuration is Helm values, not files edited in place. The collector config
is a rendered ConfigMap, so hand-editing it in the cluster is undone by the next
helm upgrade — unless you own it out-of-band with config.existingConfigMap.
# see the rendered collector configkubectl -n leansignal get cm leansignal-agent-leansignal-agent -o jsonpath='{.data.config\.yaml}'
# change a value and roll it outhelm upgrade leansignal-agent oci://ghcr.io/leansignal/charts/leansignal-agent \ --namespace leansignal --reuse-values \ --set leansignal.tenant=NEW_TENANT \ --set leansignal.agentKey.value=NEW_KEYA helm upgrade that changes the ConfigMap restarts the pod automatically. If
you rotate an external Secret instead, restart it yourself with rollout restart.
Bring your own local stores
Section titled “Bring your own local stores”Point the agent at a store you already run — setting a writeEndpoint disables
the bundled one:
localLoki: writeEndpoint: http://loki.monitoring.svc:3100/otlp/v1/logslocalTempo: writeEndpoint: http://tempo.monitoring.svc:4318/v1/traces # queryEndpoint has no derivation (the query API is a different port), so set it: queryEndpoint: http://tempo.monitoring.svc:3200
victoria-metrics-single: enabled: falselocalVM: writeEndpoint: http://my-vm.monitoring.svc:8428/api/v1/writeLeanSignal reads these stores over the gRPC tunnel via their queryEndpoint, so
they never need to be exposed.
To store nothing locally, set localLoki.deploy=false /
localTempo.deploy=false without a writeEndpoint — telemetry still reaches
LeanSignal, but there is no local buffer to explore before demanding.
Storage
Section titled “Storage”The bundled Loki and Tempo use an emptyDir by default, so a pod restart drops
the local window. That is acceptable for a roughly one-hour buffer and never
affects what LeanSignal already holds. Give either one a PVC to survive
restarts:
localLoki: persistence: { enabled: true, size: 5Gi, storageClassName: "" }localTempo: persistence: { enabled: true, size: 5Gi, storageClassName: "" }Manage the workloads
Section titled “Manage the workloads”# statuskubectl -n leansignal get pods,deploy,sts,svc,cm
# restart (rolling; PVCs and store data are retained)kubectl -n leansignal rollout restart deploy/leansignal-agent-leansignal-agentkubectl -n leansignal rollout status deploy/leansignal-agent-leansignal-agentkubectl -n leansignal rollout restart deploy/leansignal-agent-leansignal-agent-lokikubectl -n leansignal rollout restart deploy/leansignal-agent-leansignal-agent-tempokubectl -n leansignal rollout restart sts/leansignal-agent-victoria-metrics-single-serverInvestigate logs
Section titled “Investigate logs”kubectl -n leansignal logs deploy/leansignal-agent-leansignal-agent -f # collectorkubectl -n leansignal logs deploy/leansignal-agent-leansignal-agent-loki -f # local log storekubectl -n leansignal logs deploy/leansignal-agent-leansignal-agent-tempo -f # local trace storekubectl -n leansignal logs sts/leansignal-agent-victoria-metrics-single-server -f
# after a crashkubectl -n leansignal logs deploy/leansignal-agent-leansignal-agent -f --previousWhat is actually being forwarded? Each demand filter logs its verdict per batch:
kubectl -n leansignal logs deploy/leansignal-agent-leansignal-agent | grep 'demand filter' | tail -20allowed=0 on a fresh agent is normal and correct — nothing is forwarded
until a dashboard or alert demands it. The local stores keep receiving
everything either way.
Query the local stores
Section titled “Query the local stores”Port-forward, then use the same queries as any other platform:
kubectl -n leansignal port-forward svc/leansignal-agent-victoria-metrics-single-server 8428:8428kubectl -n leansignal port-forward svc/leansignal-agent-leansignal-agent-loki 3100:3100kubectl -n leansignal port-forward svc/leansignal-agent-leansignal-agent-tempo 3200:3200kubectl -n leansignal port-forward deploy/leansignal-agent-leansignal-agent 13133:13133 # healthExtend the agent
Section titled “Extend the agent”Add receivers through Helm values so they survive upgrades, then let the chart roll the pod. The agent bundles the full OpenTelemetry Collector Contrib set, and the integration pages give you a ready-made receiver block plus a demand you can import in one step.
For configuration you want to own entirely, point the chart at a ConfigMap you manage:
config: existingConfigMap: my-agent-config # must contain a config.yaml keyThe chart then renders no ConfigMap and mounts yours instead — and you trigger the rollout yourself when it changes.
Edge mode
Section titled “Edge mode”An edge agent forwards OTLP to a central agent instead of running the full pipeline — no local stores, no demand filtering, no control stream, so no tenant is needed:
helm upgrade --install leansignal-agent-edge \ oci://ghcr.io/leansignal/charts/leansignal-agent \ -n leansignal --create-namespace \ --set leansignal.agentKey.value="YOUR_KEY" \ --set leansignal.agentName="edge-cluster-1" \ --set leansignal.centralAgentGrpcUrl="central-agent.central-ns.svc:4317"The central agent’s OTLP Service must be reachable and is unauthenticated by design — keep it in-cluster or on a trusted network.
Upgrade and uninstall
Section titled “Upgrade and uninstall”helm upgrade leansignal-agent oci://ghcr.io/leansignal/charts/leansignal-agent \ --namespace leansignal --reuse-values --version <chart-version>
helm uninstall leansignal-agent --namespace leansignalUpgrading bumps the collector image; the local stores’ PVCs are retained.
Full detail lives in the Kubernetes install guide in the agent repository.
Thanks for your feedback!
Report sent — thank you!