Kubesonde is a tool that probes and visualizes the actual network connectivity of applications running in a Kubernetes cluster, so you can compare it against the network policies you meant to enforce. It works by instrumenting live pods at runtime and reporting every connection attempt observed, rather than relying only on what NetworkPolicy manifests declare.
Kubesonde is not a network policy engine, admission controller, or firewall: it does not block or modify traffic, and it does not replace tools like Cilium, Calico, or Kubernetes NetworkPolicies. It is a diagnostic and auditing tool for finding gaps between the connectivity you think you have and the connectivity you actually have.
Kubernetes network security is declarative: you write NetworkPolicies and trust that the cluster enforces them. In practice, the gap between intended and actual connectivity is where misconfigurations hide:
- NetworkPolicies are hard to get right. A missing selector, an overly broad
podSelector, or a forgotten default-deny policy can silently leave pods reachable when they should be isolated. Reading the manifests does not tell you what traffic is really allowed. - The enforced state can differ from the declared state. CNI plugins, admission controllers, and overlapping policies interact in non-obvious ways. The only way to know what a pod can actually reach is to try.
- Auditing connectivity by hand does not scale. In a namespace with dozens of microservices, manually reasoning about which pod can talk to which — and on which ports — is error-prone and quickly becomes impossible.
Kubesonde answers a concrete question that manifests alone cannot: from this pod, what can I actually reach right now? It probes live pods, records every connection attempt and its outcome, and lets you visualize the resulting connectivity graph. This makes it useful for verifying that isolation policies work as intended, for finding unexpected reachability before an attacker does, and for understanding the real communication footprint of an application.
Grab the latest kubesonde.yaml installer manifest from the releases page and apply it to your cluster:
kubectl apply -f kubesonde.yamlThis creates the kubesonde-system namespace, the Kubesonde CRDs, and the controller that runs the probes.
Once the controller is running, create a Kubesonde resource that describes what you want to probe. The following example targets every pod in the default namespace:
apiVersion: security.kubesonde.io/v1
kind: Kubesonde
metadata:
name: kubesonde-sample
spec:
namespace: default
probe: allSave it as probe.yaml and apply it:
kubectl apply -f probe.yamlThe controller starts probing the target namespace. You can watch progress — including whether probing has quiesced — with:
kubectl get kubesondesNAME NAMESPACE PROBES COMPLETE AGE
kubesonde-sample default 228 true 5m
Port-forward the controller and download the recorded probes:
kubectl --namespace kubesonde-system port-forward deployment.apps/kubesonde-controller-manager 2709 &
curl localhost:2709/probes > probes.jsonTo avoid guessing how long probing takes, wait for the Complete condition before fetching:
kubectl wait --for=condition=Complete kubesonde/kubesonde-sample --timeout=300s
⚠️ Fetching results immediately after applying the resource may return empty or incomplete data. Wait for theCompletecondition (or a few minutes, depending on the number of pods).
The installer deploys the Kubesonde frontend alongside the controller, so you can explore results without leaving your cluster. Port-forward the frontend service (and the controller, which the UI reads from at localhost:2709), then open the UI in your browser:
kubectl --namespace kubesonde-system port-forward service/kubesonde-frontend 8088:8088 &
kubectl --namespace kubesonde-system port-forward deployment.apps/kubesonde-controller-manager 2709:2709 &Then browse to http://localhost:8088.
Alternatively, if you exported a probes.json file, you can upload it to the hosted Kubesonde website to explore the connectivity graph.
kubectl delete -f probe.yaml # remove the scanner
kubectl delete -f kubesonde.yaml # remove the controller and CRDsKubesonde is driven by a single custom resource, Kubesonde (API group security.kubesonde.io/v1). Its spec supports the following fields:
| Field | Description |
|---|---|
namespace |
Target namespace whose pods will be probed. |
probe |
Default probing behavior: all probes every pod-to-pod pair, none probes nothing unless explicitly included. |
debuggerImage |
(optional) Override the image used for the debugger container. |
monitorImage |
(optional) Override the image used for the monitor container. |
exclude |
(optional) List of connections to skip during probing. |
include |
(optional) List of connections to explicitly probe, optionally with an expected outcome. |
Each include / exclude entry accepts fromPodSelector, toPodSelector, port (default 80) and protocol (default TCP). An include entry may also set expected (Allow or Deny) to assert the expected outcome of that probe.
The resource also exposes status information: probeCount, a complete flag, and a Complete condition (so you can use kubectl wait --for=condition=Complete). Completeness is based on quiescence: probing is considered complete when the recorded probe count has been stable for a fixed window (30 seconds by default). This is a hint that it is a good time to fetch results — the controller keeps probing continuously.
You can also query completeness directly from the controller:
curl localhost:2709/probes/status{
"complete": true,
"count": 228,
"window": 30000000000,
"secondsSinceLastChange": 42.5
}Kubesonde dispatches probes through a bounded worker pool that runs 10 probes in parallel by default. Override it with the KUBESONDE_PROBE_WORKERS environment variable on the controller (any positive integer; invalid or unset values fall back to 10):
env:
- name: KUBESONDE_PROBE_WORKERS
value: "20"Clone the repository — it contains the controller, the CRDs and the frontend:
git clone https://github.com/kubesonde/kubesonde.git
cd kubesondeThe project is organized as follows:
crd: backend controller and the Kubesonde CRDfrontend: the UI for analyzing probe outputsexamples: sample output from Kubesondedocs: documentation and design notes
The controller lives in crd/ and is built with a standard Kubebuilder-style Makefile:
cd crd
make build # build the manager binary
make test # run the tests
make run # run the controller against your current kubecontextExport the worker override when running locally if you want to tune concurrency:
KUBESONDE_PROBE_WORKERS=20 make runTo regenerate the consolidated installer manifest (the kubesonde.yaml shipped in releases):
make build-installerThe UI lives in frontend/ and uses Vite:
cd frontend
nvm use # switch to the Node version pinned in .nvmrc
npm install
npm start # start the dev server
npm run build
npm testContributions to the project are welcome. Create a PR and let's discuss the changes.
Logo from Elisabetta Russo info@stelladigitale.it
Kubesonde has been described and used in the following peer-reviewed papers:
- Jacopo Bufalino, Mario Di Francesco, Tuomas Aura. "Analyzing Microservice Connectivity with Kubesonde". ESEC/FSE 2023.
- Jacopo Bufalino, Jose Luis Martin-Navarro, Mario Di Francesco, Tuomas Aura. "Inside Job: Defending Kubernetes Clusters Against Network Misconfigurations". Proceedings of the ACM on Networking, 2025.
Kubesonde is licensed under the Apache License, Version 2.0.