kubectl-rustnet
July 6, 2026 ยท View on GitHub
A kubectl plugin that runs RustNet as an ephemeral debug pod on Kubernetes nodes for real-time network monitoring.

Features
- Deploys RustNet with the correct security context for packet capture and eBPF
- Interactive TUI with deep packet inspection for 15+ protocols
- Process-to-connection attribution via eBPF on the target node
- Pod and container attribution: connections are labeled with their pod, namespace, and container, and can be filtered with the
pod:,ns:, andcontainer:keywords (see the RustNet usage guide) - Automatic cleanup of debug pods on exit
- Node targeting via
--nodeflag
Installation
Via Krew
kubectl krew install rustnet
Manual
Download the binary from the releases page and place it in your $PATH.
Prerequisites
kubectlconfigured with cluster access- Cluster permissions to create pods with
hostNetwork,hostPID, and elevated capabilities - The
ghcr.io/domcyrus/rustnetimage accessible from the cluster
RBAC
A sample ClusterRole is provided in deploy/rbac.yaml. Apply it and bind to your user:
kubectl apply -f deploy/rbac.yaml
Usage
# Monitor any node (scheduler picks). RustNet captures from every interface
# by default (-i any), which includes the host-side veth peers used by
# pod-to-pod same-node communication.
kubectl rustnet
# Monitor a specific node
kubectl rustnet --node worker-3
# In a specific namespace with a timeout
kubectl rustnet -n monitoring --timeout 5m
# Pin the capture to a single interface (overrides the -i any default)
kubectl rustnet -- -i eth0 --no-dpi
# Use a specific image tag. Note: pod/container attribution needs a tag
# newer than v1.4.0 (or latest); older tags fall back to plain monitoring.
kubectl rustnet --image ghcr.io/domcyrus/rustnet:v1.1.0
# Legacy kernels (< 5.8) that don't support CAP_BPF
kubectl rustnet --legacy-kernel
# Privileged mode (when fine-grained caps aren't enough)
kubectl rustnet --privileged
Plugin Flags
| Flag | Default | Description |
|---|---|---|
--namespace, -n | default | Kubernetes namespace |
--node | (any) | Target a specific node |
--image | ghcr.io/domcyrus/rustnet:latest | Container image (has pod/container attribution enabled) |
--timeout | 0 (none) | Session timeout (e.g. 5m, 1h) |
--privileged | false | Run in privileged mode |
--legacy-kernel | false | Use SYS_ADMIN instead of BPF+PERFMON |
--kubeconfig | (default) | Path to kubeconfig file |
--context | (default) | Kubernetes context |
RustNet Flags (after --)
| Flag | Description |
|---|---|
-i, --interface | Network interface to monitor (defaults to any when not set, so inter-pod same-node traffic on host-side veths is captured) |
-f, --bpf-filter | BPF filter expression |
--no-dpi | Disable deep packet inspection |
--resolve-dns | Enable reverse DNS lookups |
--no-geoip | Disable GeoIP lookups |
--json-log FILE | Export connection events as JSON (includes pod/container attribution) |
--pcap-export FILE | Export packets to PCAP file with a JSONL sidecar |
--pcapng-export FILE | Export packets to an annotated PCAPNG with per-packet process comments |
--kubernetes MODE | Pod/container attribution: auto (default, on inside a pod), on, or off |
--refresh-interval MS | UI refresh interval (default: 1000) |
--no-color | Disable colors |
Export files are written inside the ephemeral pod, which is deleted on exit. Copy them out with kubectl cp before quitting RustNet.
How It Works
The plugin creates an ephemeral pod with:
hostNetwork: truefor node-level network visibilityhostPID: truefor process attribution via eBPFrunAsUser: 0to read host/procentries for process lookupNET_RAW+BPF+PERFMONcapabilities for packet capture and eBPF- Read-only
/var/logmount so RustNet can resolve pod and container names from the kubelet log directories (/var/log/containers,/var/log/pods)
On exit (or Ctrl+C), the pod is automatically deleted.
Development
# Build
go build -o kubectl-rustnet ./cmd/kubectl-rustnet
# Unit tests
go test ./internal/... -v
# E2E tests (requires kind and Docker)
./e2e/setup.sh create
KUBECTL_RUSTNET_BIN=./kubectl-rustnet go test ./e2e/ -v -timeout 300s
./e2e/setup.sh delete
License
Apache License 2.0. See LICENSE.