Profile your Kubernetes applications with zero overhead and zero modifications π
kubectl-prof is a powerful kubectl plugin that enables low-overhead profiling of applications running in Kubernetes environments. Generate FlameGraphs, JFR files, thread dumps, heap dumps, and many other diagnostic outputs without modifying your pods.
β¨ Key Features:
- π― Zero modification - Profile running pods without any changes to your deployment
- π Multi-language support - Java, Go, Python, Ruby, Node.js, Rust, Clang/Clang++
- π Multiple output formats - FlameGraphs, JFR, SpeedScope, thread dumps, heap dumps, and more
- β‘ Low overhead - Minimal impact on running applications
- π Continuous profiling - Support for both discrete and continuous profiling modes
This is an open source fork of kubectl-flame with enhanced features and bug fixes.
| Language | Status | Tools Available |
|---|---|---|
| β Java (JVM) | β Fully Supported | async-profiler, jcmd |
| πΉ Go | β Fully Supported | eBPF profiling |
| π Python | β Fully Supported | py-spy |
| π Ruby | β Fully Supported | rbspy |
| π Node.js | β Fully Supported | eBPF profiling, perf |
| π¦ Rust | β Fully Supported | eBPF profiling |
| βοΈ Clang/Clang++ | β Fully Supported | eBPF profiling, perf |
- Containerd -
--runtime=containerd(default) - CRI-O -
--runtime=crio
Profile a Java application for 1 minute and save the FlameGraph:
kubectl prof my-pod -t 1m -l javaProfile a Python application and save to a specific location:
kubectl prof my-pod -t 1m -l python --local-path=/tmpProfile multiple pods using a label selector:
kubectl prof --selector app=myapp -t 5m -l java -o jfrProfile a Java application for 5 minutes and generate a FlameGraph:
kubectl prof my-pod -t 5m -l java -o flamegraph --local-path=/tmpπ‘ Tip: If
--local-pathis omitted, the FlameGraph will be saved to the current directory.
For Java applications running in Alpine-based containers, use the --alpine flag:
kubectl prof mypod -t 1m -l java -o flamegraph --alpine
β οΈ Note: The--alpineflag is only required for Java applications.
Using jcmd (default for JFR):
kubectl prof mypod -t 5m -l java -o jfrUsing async-profiler:
kubectl prof mypod -t 5m -l java -o jfr --tool async-profilerGenerate a thread dump using jcmd:
kubectl prof mypod -l java -o threaddumpGenerate a heap dump in hprof format:
kubectl prof mypod -l java -o heapdump --tool jcmdGenerate a heap histogram:
kubectl prof mypod -l java -o heaphistogram --tool jcmdWhen using async-profiler, you can specify different event types:
# CPU profiling (default: ctimer)
kubectl prof mypod -t 5m -l java -e cpu
# Memory allocation profiling
kubectl prof mypod -t 5m -l java -e alloc
# Lock contention profiling
kubectl prof mypod -t 5m -l java -e lockSupported events: cpu, alloc, lock, cache-misses, wall, itimer, ctimer
kubectl prof mypod -t 1m -l python -o flamegraph --local-path=/tmpkubectl prof mypod -l python -o threaddump --local-path=/tmpGenerate a SpeedScope compatible file:
kubectl prof mypod -t 1m -l python -o speedscope --local-path=/tmpProfile a Go application for 1 minute:
kubectl prof mypod -t 1m -l go -o flamegraphkubectl prof mypod -t 1m -l node -o flamegraphπ‘ Tip: For JavaScript symbols to be resolved, run your Node.js process with the
--perf-basic-profflag.
Generate a heap snapshot:
kubectl prof mypod -l node -o heapsnapshot
β οΈ Requirements: Your Node.js app must be run with--heapsnapshot-signal=SIGUSR2(default) or--heapsnapshot-signal=SIGUSR1.
If using SIGUSR1:
kubectl prof mypod -l node -o heapsnapshot --node-heap-snapshot-signal=10π Learn more: Node.js Heap Snapshots
Profile a Ruby application:
kubectl prof mypod -t 1m -l ruby -o flamegraphAvailable output formats:
flamegraph- FlameGraph visualizationspeedscope- SpeedScope formatcallgrind- Callgrind format
Clang:
kubectl prof mypod -t 1m -l clang -o flamegraphClang++:
kubectl prof mypod -t 1m -l clang++ -o flamegraphkubectl prof mypod -t 1m -l java --runtime crioSupported runtimes: containerd (default), crio
Profile continuously at 60-second intervals for 5 minutes:
kubectl prof mypod -l java -t 5m --interval 60sπ Note: In continuous mode, a new result is produced every interval. Only the last result is available by default.
Set CPU and memory limits for the profiling agent pod:
kubectl prof mypod -l java -t 5m \
--cpu-limits=1 \
--cpu-requests=100m \
--mem-limits=200Mi \
--mem-requests=100MiProfile a pod in a different namespace:
kubectl prof mypod -n profiling \
--service-account=profiler \
--target-namespace=my-apps \
-l goUse a custom profiling agent image:
kubectl prof mypod -l java -t 5m \
--image=localhost/my-agent-image-jvm:latest \
--image-pull-policy=IfNotPresent \
--runtime containerdProfile all pods matching a label selector:
kubectl prof --selector app=myapp -t 5m -l java -o jfr
β οΈ ATTENTION: Use this option with caution as it will profile ALL pods matching the selector.
Control concurrent profiling jobs:
kubectl prof --selector app=myapp -t 5m -l java -o jfr --pool-size-profiling-jobs 5By default, kubectl-prof attempts to profile all processes in the container. To target a specific process:
Using PID:
kubectl prof mypod -l java --pid 1234Using process name:
kubectl prof mypod -l java --pgrep java-app-processFor Java profiling, kubectl-prof uses PERFMON and SYSLOG capabilities by default. To use SYS_ADMIN:
kubectl prof my-pod -t 5m -l java --capabilities=SYS_ADMINAdd multiple capabilities:
kubectl prof my-pod -t 5m -l java \
--capabilities=SYS_ADMIN \
--capabilities=PERFMONProfile pods on nodes with taints by specifying tolerations:
Tolerate specific taint:
kubectl prof my-pod -t 5m -l java \
--tolerations=node.kubernetes.io/disk-pressure=true:NoScheduleMultiple tolerations:
kubectl prof my-pod -t 5m -l java \
--tolerations=node.kubernetes.io/disk-pressure=true:NoSchedule \
--tolerations=node.kubernetes.io/memory-pressure:NoExecute \
--tolerations=dedicated=profiling:PreferNoScheduleToleration formats:
key=value:effect- Full specificationkey:effect- Any valuekey- Defaults to NoSchedule
For a complete list of options:
kubectl prof --helpKrew is the plugin manager for kubectl.
-
Install Krew (if not already installed)
-
Add kubectl-prof repository and install:
kubectl krew index add kubectl-prof https://github.com/josepdcs/kubectl-prof
kubectl krew search kubectl-prof
kubectl krew install kubectl-prof/prof
kubectl prof --helpDownload pre-built binaries from the releases page.
wget https://github.com/josepdcs/kubectl-prof/releases/download/1.8.1/kubectl-prof_1.8.1_linux_amd64.tar.gz
tar xvfz kubectl-prof_1.8.1_linux_amd64.tar.gz
sudo install kubectl-prof /usr/local/bin/wget https://github.com/josepdcs/kubectl-prof/releases/download/1.8.1/kubectl-prof_1.8.1_darwin_amd64.tar.gz
tar xvfz kubectl-prof_1.8.1_darwin_amd64.tar.gz
sudo install kubectl-prof /usr/local/bin/Download the Windows binary from the releases page and add it to your PATH.
- Go 1.21 or higher
- Make
- Docker (for building agent containers)
- Clone and install dependencies:
go get -d github.com/josepdcs/kubectl-prof
cd $GOPATH/src/github.com/josepdcs/kubectl-prof
make install-deps- Build the binary:
make buildThe binary will be available in ./bin/kubectl-prof
- Build agent containers (optional):
Modify the DOCKER_BASE_IMAGE property in Makefile, then run:
make build-docker-agentskubectl-prof launches a Kubernetes Job on the same node as the target pod. The profiling is performed using specialized tools based on the programming language:
async-profiler - For FlameGraphs and JFR files
- FlameGraphs:
--tool async-profiler -o flamegraph(default) - JFR files:
--tool async-profiler -o jfr - Collapsed/Raw:
--tool async-profiler -o collapsedor-o raw - Event types:
cpu,alloc,lock,cache-misses,wall,itimer,ctimer(default)
jcmd - For JFR, thread dumps, heap dumps
- JFR files:
--tool jcmd -o jfr(default for jcmd) - Thread dumps:
--tool jcmd -o threaddump - Heap dumps:
--tool jcmd -o heapdump - Heap histogram:
--tool jcmd -o heaphistogram
py-spy - Low-overhead Python profiler
- FlameGraphs:
-o flamegraph(default) - Thread dumps:
-o threaddump - SpeedScope:
-o speedscope - Raw output:
-o raw
eBPF profiling - Kernel-level profiling
- FlameGraphs:
-o flamegraph(default) - Raw output:
-o raw
rbspy - Ruby sampling profiler
- FlameGraphs:
-o flamegraph(default) - SpeedScope:
-o speedscope - Callgrind:
-o callgrind
eBPF profiling (recommended) and perf
- FlameGraphs:
-o flamegraph(default) - Raw output:
-o raw - Heap snapshot:
-o heapsnapshot
π‘ Tip: For JavaScript symbol resolution, run Node.js with
--perf-basic-profflag
π‘ Tip: For heap snapshots, run Node.js with--heapsnapshot-signalflag
perf (default) and eBPF profiling
- FlameGraphs:
-o flamegraph - Raw output:
-o raw
The raw output is a text file containing profiling data that can be:
- Used to generate FlameGraphs manually
- Visualized at speedscope.app
Discrete Mode (default)
- Single profiling session
- Result available when profiling completes
- Usage:
-t 5m
Continuous Mode
- Multiple results at regular intervals
- Only the last result is available by default
- Client responsible for storing all results
- Usage:
-t 5m --interval 60s
By default, kubectl-prof profiles all processes in the target container matching the specified language.
Warning example:
β Detected more than one PID to profile: [2508 2509].
It will attempt to profile all of them.
Use the --pid flag to profile a specific PID.
Target a specific process:
- By PID:
--pid 1234 - By name:
--pgrep process-name
For Java profiling, kubectl-prof uses PERFMON and SYSLOG capabilities by default.
According to the Kernel documentation, these capabilities should be sufficient for collecting performance samples.
To use SYS_ADMIN instead:
kubectl prof my-pod -t 5m -l java --capabilities=SYS_ADMINAdd multiple capabilities:
kubectl prof my-pod -t 5m -l java \
--capabilities=SYS_ADMIN \
--capabilities=PERFMONBy default, the profiling agent pod is scheduled only on nodes without taints. For nodes with taints, specify tolerations:
Toleration formats:
key=value:effect- Full specificationkey:effect- Any valuekey- Defaults to NoSchedule
Examples:
# Single toleration
kubectl prof my-pod -t 5m -l java \
--tolerations=node.kubernetes.io/disk-pressure=true:NoSchedule
# Multiple tolerations
kubectl prof my-pod -t 5m -l java \
--tolerations=node.kubernetes.io/disk-pressure=true:NoSchedule \
--tolerations=node.kubernetes.io/memory-pressure:NoExecute \
--tolerations=dedicated=profiling:PreferNoScheduleWe welcome contributions! Please refer to Contributing.md for information about how to get involved.
We welcome:
- π Bug reports
- π‘ Feature requests
- π Documentation improvements
- π§ Pull requests
- Josep DamiΓ Carbonell SeguΓ - [email protected]
Original author of kubectl-flame:
- Eden Federman - [email protected]
- Verizon Media Code
This project is licensed under the terms of the Apache 2.0 open source license. Please refer to LICENSE for the full terms.