Kubernetes profiling
Install the Last9 eBPF profiler Helm chart and explore continuous profiles from Kubernetes workloads
Last9 continuous profiling shows where CPU time is spent in workloads running on Linux Kubernetes nodes. The customer-installable Helm chart runs the upstream OpenTelemetry eBPF profiler as a DaemonSet and sends selected profiles to Last9 over OTLP/HTTP.
Prerequisites
- Kubernetes 1.27 or later with Linux worker nodes.
- Helm 3 and cluster-admin access to install the DaemonSet and its read-only workload-discovery permissions.
- Supported eBPF/BTF kernel features,
/proc,/sys, and writable bpffs on the worker nodes. - The profile ingestion endpoint and authorization value provided by Last9.
The profiler uses host PID visibility and explicit eBPF-related capabilities. Review those permissions with your Kubernetes administrator before installing.
Install the chart
Add the public chart repository and pin the supported chart version:
helm repo add last9 https://last9.github.io/helm-chartshelm repo updatemkdir -p chartshelm pull last9/last9-profiler --version 0.1.1 --destination ./chartsGet the Last9 endpoint and credentials
Open Integrations → OpenTelemetry
in Last9 and copy the server OTLP endpoint and Basic authorization value shown
for your organization. Use the profiles endpoint supplied for this chart; it
must end in /v1/profiles. If the credentials are not visible, ask an
organization admin or your Last9 contact for server ingestion credentials. Do
not use a query token or paste a credential into a tracked values file.
Create a Secret in the release namespace. The authorization value is passed
to the Last9 OTLP endpoint as the HTTP Authorization header; keep it in your
secret manager or a protected file.
kubectl create namespace last9-profilerkubectl create secret generic last9-profiler-credentials \ --namespace last9-profiler \ --from-file=authorization=/secure/path/profiling-authorizationCreate a values file and replace the endpoint with the customer-specific HTTPS profiles endpoint:
last9: ingestEndpoint: "https://REPLACE_WITH_LAST9_HOSTNAME/v1/profiles" authorization: existingSecret: last9-profiler-credentials existingSecretKey: authorizationdeploymentEnvironment: "production"clusterName: "REPLACE_WITH_CLUSTER_NAME"security: acceptHostAccess: truedeploymentEnvironment and clusterName are attached to every profile as
resource attributes. Set them explicitly so the Profiles UI can filter data by
environment and cluster.
Install the pinned archive:
helm install last9-profiler ./charts/last9-profiler-0.1.1.tgz \ --namespace last9-profiler \ --values ./last9-profiler-values.yamlkubectl rollout status daemonset/last9-profiler \ --namespace last9-profiler --timeout=180sThe chart requires an HTTPS DNS endpoint ending in /v1/profiles. It does not
create an inbound Service or persist profile payloads on the node.
Select workloads
Add the opt-in label to the pod template of each workload to profile:
metadata: labels: last9.profiling/enabled: "true"For a Deployment, the label belongs under spec.template.metadata.labels.
Roll out the workload after adding the label, then wait for samples to arrive.
View profiles
Open Profiles and filter by cluster, namespace, service, environment, and profile type. Select a profile to inspect the flamegraph and call-stack details.
Flamegraph names
The chart transports profile data; it does not add executable symbols. Readable
function names depend on the profiled runtime and symbols available to the
upstream eBPF profiler. Stripped or minimal images, including shell-only
BusyBox workloads, can show [unknown] frames even when collection and
ingestion are healthy.
To validate readable flamegraphs, use a symbolizable Go, Java, or similar application rather than a shell CPU-burn fixture. Unknown historical frames are not re-symbolized after ingestion.
The OpenTelemetry Demo includes workloads built with different runtimes and
image layouts. Some processes may therefore appear as [unknown] even when
the profiler is collecting and profiles are arriving. Confirm ingestion with
a known symbolizable workload before treating unknown names as an installation
failure.
Upgrade and uninstall
Keep the chart version pinned and upgrade only to a newer supported release:
helm upgrade last9-profiler ./charts/last9-profiler-0.1.1.tgz \ --namespace last9-profiler \ --values ./last9-profiler-values.yamlTo remove the profiler, uninstall the release. The customer-owned credentials Secret is not chart-managed and should be deleted separately if no longer needed:
helm uninstall last9-profiler --namespace last9-profilerkubectl delete secret last9-profiler-credentials --namespace last9-profiler