Implementing Micro-Segmentation in K8s using Cilium Network Policies

By default, flat networks in Kubernetes allow any pod to talk to any other pod. If a public-facing frontend gets compromised, an attacker can move laterally to reach your backend databases.
Standard iptables-based network policies struggle at scale because frequent pod creation and churn force constant kernel rule rewrites. Cilium avoids this by using eBPF (Extended Berkeley Packet Filter) to process network filtering directly in the Linux kernel with minimal overhead.
Zero-Trust Isolation for Workloads
A zero-trust model requires blocking all inter-pod traffic by default and explicitly permitting access only where required.
In the manifest below, a CiliumNetworkPolicy (CNP) isolates a PostgreSQL database so it only accepts TCP connections on port 5432 from pods labeled app: backend-api.
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "db-micro-segmentation"
namespace: "production"
spec:
endpointSelector:
matchLabels:
app: postgres-db
tier: storage
ingress:
- fromEndpoints:
- matchLabels:
app: backend-api
tier: application
toPorts:
- ports:
- port: "5432"
protocol: TCP
How Cilium Enforces Policy with eBPF
Instead of filtering by dynamic IP addresses or managing iptables chains, Cilium attaches eBPF programs to the virtual ethernet (veth) interfaces of target pods:
kind: CiliumNetworkPolicy: Standard KubernetesNetworkPolicyresources offer basic L3/L4 rules.CiliumNetworkPolicyextends this with features like DNS-based rules and L7 protocol filtering (HTTP, gRPC, Kafka), though this configuration focuses on L4 port restriction.endpointSelector: Node-level Cilium agents assign numeric security identities to pods matchingapp: postgres-dbandtier: storage. The policy rules map directly to the eBPF bytecode attached to those pods' network interfaces.ingress.fromEndpoints: Specifies allowed source workloads by label (app: backend-api,tier: application). Because Cilium evaluates traffic using numeric security IDs rather than IP addresses, pod restarts and IP reassignments don't trigger constant network rule updates.toPorts: Restricts incoming connections strictly to TCP port 5432. If a backend API container is breached, the attacker cannot probe administrative ports (such as SSH on port 22) or unexposed services on the database pod.
Adopting a default-deny posture with explicit CNP rules keeps network boundaries tight and limits lateral movement across your cluster.