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.

kubectl-rustnet Demo

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:, and container: keywords (see the RustNet usage guide)
  • Automatic cleanup of debug pods on exit
  • Node targeting via --node flag

Installation

Via Krew

kubectl krew install rustnet

Manual

Download the binary from the releases page and place it in your $PATH.

Prerequisites

  • kubectl configured with cluster access
  • Cluster permissions to create pods with hostNetwork, hostPID, and elevated capabilities
  • The ghcr.io/domcyrus/rustnet image 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

FlagDefaultDescription
--namespace, -ndefaultKubernetes namespace
--node(any)Target a specific node
--imageghcr.io/domcyrus/rustnet:latestContainer image (has pod/container attribution enabled)
--timeout0 (none)Session timeout (e.g. 5m, 1h)
--privilegedfalseRun in privileged mode
--legacy-kernelfalseUse SYS_ADMIN instead of BPF+PERFMON
--kubeconfig(default)Path to kubeconfig file
--context(default)Kubernetes context

RustNet Flags (after --)

FlagDescription
-i, --interfaceNetwork interface to monitor (defaults to any when not set, so inter-pod same-node traffic on host-side veths is captured)
-f, --bpf-filterBPF filter expression
--no-dpiDisable deep packet inspection
--resolve-dnsEnable reverse DNS lookups
--no-geoipDisable GeoIP lookups
--json-log FILEExport connection events as JSON (includes pod/container attribution)
--pcap-export FILEExport packets to PCAP file with a JSONL sidecar
--pcapng-export FILEExport packets to an annotated PCAPNG with per-packet process comments
--kubernetes MODEPod/container attribution: auto (default, on inside a pod), on, or off
--refresh-interval MSUI refresh interval (default: 1000)
--no-colorDisable 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: true for node-level network visibility
  • hostPID: true for process attribution via eBPF
  • runAsUser: 0 to read host /proc entries for process lookup
  • NET_RAW + BPF + PERFMON capabilities for packet capture and eBPF
  • Read-only /var/log mount 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.