Skip to content
Network Flow Discovery

Network Flow Discovery

Network Flow Discovery automatically builds a graph of service-to-service, service-to-database, and service-to-external flows by reading Kubernetes NetworkPolicies and GKE FQDNNetworkPolicies.

How it works

  1. A NetworkFlowDiscovery Custom Resource is created, linked to a Portal via spec.portalRef (auto-created at startup for the main portal)
  2. The controller periodically reconciles (every 60s) and:
    • Lists all NetworkPolicy resources (ingress rules → service-to-service flows)
    • Lists all FQDNNetworkPolicy resources (egress rules → service-to-database/external flows)
    • Builds a graph of nodes and edges
    • Stores nodes in a FlowNodeSet CR and edges in a FlowEdgeSet CR (both owned by the parent)
  3. The web UI and MCP server read from FlowNodeSet/FlowEdgeSet — no cluster queries at request time

CRDs

NetworkFlowDiscovery

The parent resource that drives reconciliation.

apiVersion: sreportal.io/v1alpha1
kind: NetworkFlowDiscovery
metadata:
  name: netflow-main
  namespace: sreportal-system
spec:
  portalRef: main
  # Optional: restrict to specific namespaces (default: all)
  namespaces: []

Status fields:

FieldDescription
status.nodeCountNumber of discovered nodes
status.edgeCountNumber of discovered edges
status.lastReconcileTimeWhen the graph was last rebuilt
status.conditionsReady condition indicating reconciliation success

FlowNodeSet

Stores all discovered nodes. Auto-created and owned by the parent NetworkFlowDiscovery.

  • Named <parent>-nodes (e.g. netflow-main-nodes)
  • spec.discoveryRef references the parent
  • status.nodes[] contains the discovered nodes

Each node has the following fields:

FieldDescriptionExample
idUnique identifierservice:namespace-a:service-1
labelHuman-readable nameservice-1
namespaceKubernetes namespacenamespace-a
nodeTypeClassification (see below)service
groupLogical group (namespace)namespace-a

FlowEdgeSet

Stores all discovered edges. Auto-created and owned by the parent NetworkFlowDiscovery.

  • Named <parent>-edges (e.g. netflow-main-edges)
  • spec.discoveryRef references the parent
  • status.edges[] contains the discovered edges

Each edge has the following fields:

FieldDescriptionExample
fromSource node idservice:namespace-a:service-1
toTarget node idservice:namespace-b:service-2
edgeTypeFlow type (see below)cross-ns

Deleting the parent NetworkFlowDiscovery automatically garbage-collects both children.

Node types

Nodes are classified by port:

TypeRule
servicePods referenced in NetworkPolicy ingress rules (app.kubernetes.io/name label)
cronCronJobs referenced in NetworkPolicy ingress rules (basename label)
databaseFQDNs on ports 5432, 1433, 3306
messagingFQDNs on ports 5672, 5671
externalAll other FQDNs in egress rules

Edge types

TypeMeaning
internalFlow between services in the same namespace
cross-nsFlow between services in different namespaces
cronFlow from a cron job to a service
databaseFlow from a service to a database
messagingFlow from a service to a messaging broker
externalFlow from a service to an external endpoint

Web UI

The Network Policies page (/:portalName/netpol) is organized into three tabs:

Flow Matrix

Lists every service with its outgoing and incoming flows. Features:

  • Collapsible namespace and service sections
  • Search filter and namespace dropdown
  • Copy as Markdown for documentation/audit export

Flow Matrix tab

Cross-Namespace

Aggregated matrix showing flow counts between namespaces. Useful for understanding inter-team dependencies.

Cross-Namespace tab

Flow Explorer

Select any resource (database, service, external endpoint) to see its direct incoming and outgoing flows in a butterfly layout:

  • Left column: services that call the selected resource (incoming), grouped by namespace in collapsible sections
  • Center: the selected resource with incoming/outgoing counts
  • Right column: services/resources that the selected resource calls (outgoing), grouped by namespace in collapsible sections

Click on any connected service to navigate to it and explore its own flows — this allows depth-first exploration without needing a multi-level BFS view.

Flow Explorer tab

MCP Server

Available at /mcp/netpol with two tools:

ToolDescriptionParameters
list_network_flowsList all nodes and edges in the flow graphsearch
get_service_flowsGet incoming/outgoing flows for a specific serviceservice (required)

Kubernetes API calls

The controller makes exactly two LIST calls per reconciliation cycle (every 60s):

  1. GET /apis/networking.k8s.io/v1/networkpolicies
  2. GET /apis/networking.gke.io/v1alpha3/fqdnnetworkpolicies (silently skipped if CRD is absent)

The web UI and MCP server read only from FlowNodeSet/FlowEdgeSet CRDs — zero cluster queries at request time.