Every pod needs an IP and to communicate with other pods. The CNI (Container Network Interface) delivers this. But there's a catch that trips up many people: not every CNI enforces NetworkPolicy.
I've seen a cluster with network policies created, reviewed, and "approved" — and no effect. Flannel was handling the networking; the policy was just a decorative object in etcd.
Course seal: tested on Kubernetes 1.35 and Ubuntu 24.04.
What the CNI does
- Assigns an IP to the pod.
- Configures routes between nodes.
- Handles forwarding between pods and Services (together with kube-proxy).
- In some implementations, enforces network policies.
Common models:
| Model | How it works | Examples |
|---|---|---|
| Overlay (VXLAN) | encapsulates packets between nodes | flannel, Canal |
| Routed | routes/BGP between nodes | Calico (BGP), Cilium (native routing) |
| eBPF | datapath in the kernel | Cilium |
flannel: simple and honest
Flannel is great for labs: easy to install, works, and requires little maintenance. It creates a VXLAN network and distributes a /24 per node.
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
kubectl -n kube-flannel get pods -o wide
Important limitation: flannel does not implement NetworkPolicy. The object is accepted by the API and stored, but there is no agent applying the rule. If you need segmentation, you need Cilium, Calico, or another policy engine.
Cilium and Calico: real policy
- Cilium uses eBPF, has flow observability (Hubble), L3/L4/L7 policies, and can replace kube-proxy.
- Calico is mature, based on iptables/eBPF, with policy and BGP.
In this course, we will not change the CNI right now — changing CNI on a live cluster requires a maintenance window. But we will understand enough to not fall for the flannel myth.
NetworkPolicy in 5 minutes
A policy selects pods by label and defines who can enter/exit.
Default-deny ingress in the namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: demo
spec:
podSelector: {}
policyTypes:
- Ingress
Allow only from pod client:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-client
namespace: demo
spec:
podSelector:
matchLabels:
app: server
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- protocol: TCP
port: 80
Allow from ingress-nginx:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
Allow kubelet probes (which come from the node IP):
ingress:
- from:
- ipBlock:
cidr: 192.168.56.0/24
Lab: prove (or not) the policy
Create the namespace and two pods:
kubectl create ns demo
kubectl -n demo run server --image=nginx:1.27 --port=80 --labels=app=server
kubectl -n demo run client --image=curlimages/curl:8.10.1 --labels=app=client --command -- sleep 3600
Test before the policy:
kubectl -n demo exec client -- curl -s -o /dev/null -w '%{http_code}\n' http://server
# 200
Apply default-deny and allow-client:
kubectl apply -f default-deny.yaml
kubectl apply -f allow-client.yaml
Test again:
kubectl -n demo exec client -- curl -s -o /dev/null -w '%{http_code}\n' http://server
- On Cilium/Calico: the authorized client still gets 200; a pod without the
clientlabel gets a timeout. - On flannel: probably still 200 for everyone — the policy is not enforced.
This test is the most important of the chapter. If it doesn't block, your segmentation is fiction.
Changing CNI without breaking everything
If you decided to migrate to Cilium:
- Plan a maintenance window.
- Make a backup (etcd/Velero).
- Install Cilium with
kubeProxyReplacement=false(keeps kube-proxy) and IPAM compatible withpodCIDR. - Validate
cilium statuson all nodes. - Remove flannel node by node, with drain/cordon, ensuring pods are healthy.
- Apply the NetworkPolicies and run the negative test.
- Have a rollback: reinstall flannel and restore the CNI config.
Don't do this in production without rehearsal. In the lab, break at will.
Common errors
| Symptom | Probable cause |
|---|---|
Pods Pending or NotReady |
CNI not installed or DaemonSet with error |
| Broken DNS | CoreDNS without network or policy blocking 53 |
| Policy "does nothing" | CNI without NetworkPolicy support |
| Probes failing after policy | kubelet blocked; allow the node IP |
| Traffic between namespaces blocked | missing explicit namespaceSelector |
| IP exhaustion | CIDR too small for the number of pods |
Checklist
- [ ] I know which CNI is in the cluster.
- [ ] I know if it enforces NetworkPolicy.
- [ ] I tested default-deny with an unauthorized pod.
- [ ] I allowed DNS and probes.
- [ ] I have a rollback plan if I change the CNI.
- [ ] I documented the policies in the repository.
Glossary
- CNI: interface that configures pod networking.
- overlay: encapsulated network over the physical network.
- NetworkPolicy: ingress/egress rule by selector.
- default-deny: denies everything not explicitly allowed.
- eBPF: execution of programs in the kernel, used by Cilium.
Next
Now that the network is under control, let's organize the cluster: namespaces, labels, quotas, PDBs, and what really protects a workload during maintenance.
Next: Kubernetes Course 07 — Namespaces, labels, quotas, and PDB
Keep reading
Read also

StorCLI - Complete Cheat Sheet
StorCLI is the official and modern tool for managing Broadcom/LSI RAID controllers. This guide covers essential commands, syntax and use cases.
12 min de leitura
TutoriaisBusiness Services in Nyverra Portal: Translating IT into Business
The business doesn't feel a server go down — it feels email stop. The Business Services (Service Mapping) module of Nyverra ITSM Portal connects services like Email, ERP or PACS to CMDB assets, revealing the real impact of each failure.
5 min de leitura
SegurançaRPO vs RTO: How to Define Before Buying Backup (and Why Most Companies Get It Wrong)
Most companies buy backup asking the wrong question: "how much does it cost?". The right question is: how much data can I lose (RPO) and how long can I be down (RTO). Discover how to define these numbers per system and avoid purchasing protection based on price, not on real need.
9 min de leitura
Comments
No comments yet
Be the first to share your thoughts on this article.

Leave a comment