We are moving toward a multi-tenant setup and I am worried about the default "allow-all" traffic behavior in Kubernetes. I want to isolate namespaces so that teams cannot access each other's pods. What is the standard approach for a "Default Deny" policy without breaking internal DNS resolution or essential health checks like liveness and readiness probes?
3 answers
The gold standard is to start with a 'default-deny-all' policy in every namespace. This forces you to be intentional about every connection. To avoid breaking things, you must explicitly allow egress to the 'kube-dns' service in the 'kube-system' namespace, usually on port 53. For health checks, remember that if they are coming from the Kubelet (which is on the host), they are usually exempt from network policies, but this depends on your CNI provider like Calico or Cilium. We spent weeks refining our YAMLs to ensure that only the front-end can talk to the back-end via specific labels and selectors.
Are you using a CNI that actually supports NetworkPolicy? I’ve seen many folks try to apply these on clusters running Flannel, which silently ignores them.
Use labels religiously. Network policies rely on 'podSelector' and 'namespaceSelector', so if your labeling strategy is messy, your security will be full of holes.
Exactly, Laura. A strict labeling convention is the foundation of any Zero Trust architecture in Kubernetes. Without it, you cannot scale your security policies.
Christopher, you hit the nail on the head. We actually made that mistake early on. We were applying policies and wondering why traffic was still flowing. Switching to Calico allowed us to actually enforce those rules. It is vital to check the 'Provider' documentation before spending hours writing complex egress rules that the underlying network layer isn't even capable of processing.