Kubernetes NetworkPolicy: Preventing Cross-Tier Traffic with DNS Access
This tutorial demonstrates how to use Kubernetes NetworkPolicy to restrict traffic between application tiers while ensuring that services within each tier can still resolve DNS names. This is a critical component of a secure and well-structured Kubernetes deployment.
Understanding the Problem
In a multi-tier application, you often want to isolate tiers (e.g., web servers from backend services) for security and control. Traditionally, this has been achieved with firewalls. Kubernetes NetworkPolicy provides a declarative way to achieve similar results, enforcing network traffic rules at the pod level. Crucially, we need to ensure that services within each tier can continue to resolve DNS names, which is fundamental for accessing external services and internal components.
Example 1: Initial Setup – Basic NetworkPolicy
Let’s start with a simple NetworkPolicy that prevents all traffic between two pods: `web-tier` and `backend-tier`. We’ll also ensure DNS access is allowed.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tier-isolation-basic
namespace: default
spec:
podSelector:
matchLabels:
tier: backend-tier
policyTypes:
- Ingress
ingress:
- ports:
- protocol: UDP
port: 53
egress:
- to:
- podSelector:
matchLabels:
tier: web-tier
policyTypes:
- Egress
termination:
{}
Explanation:
- `apiVersion`, `kind`, `metadata`: Standard Kubernetes object definitions.
- `podSelector`: This specifies the pods to which this NetworkPolicy applies – in this case, pods labeled `tier: backend-tier`.
- `policyTypes`: This defines the types of traffic the policy governs – `Ingress` (incoming traffic) and `Egress` (outgoing traffic).
- `ingress`: This defines the incoming traffic rules. Here, we allow UDP traffic on port 53 (DNS) to pods labeled `tier: backend-tier`.
- `egress`: This defines the outgoing traffic rules. Here, we allow traffic from `backend-tier` pods to pods labeled `tier: web-tier`.
- `termination`: Ensures correct termination of the policy.
Verification:
kubectl apply -f tier-isolation-basic.yaml
kubectl get networkpolicy tier-isolation-basic -n default
kubectl describe networkpolicy tier-isolation-basic -n default
Check the output to ensure the NetworkPolicy is created and that the pod selectors are correct.
Example 2: Incorrect NetworkPolicy – Blocking DNS
Let’s deliberately introduce an error to demonstrate how NetworkPolicy affects DNS access. This time, we’ll block all outbound traffic from the `backend-tier` pods.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tier-isolation-blocked
namespace: default
spec:
podSelector:
matchLabels:
tier: backend-tier
policyTypes:
- Ingress
ingress:
- ports:
- protocol: UDP
port: 53
egress:
- to:
- '' # Block all egress traffic
termination:
{}
Explanation:
- The key difference is the `egress` section, which now has `to: ”`, effectively blocking all outbound traffic.
Verification:
kubectl apply -f tier-isolation-blocked.yaml
kubectl get pods -n default -l tier=backend-tier
kubectl describe pod -n default
kubectl get events -n default --field-selector involvedObject.kind=Pod,involvedObject.name=,namespace=default
Observe the following:
- The `kubectl get pods` command will likely show the `backend-tier` pods in a `Pending` or `Failed` state, indicating DNS resolution failure.
- `kubectl describe pod` will show error messages related to DNS resolution or network connectivity.
- `kubectl get events` will likely show events related to the pod failing to resolve DNS names.
Example 3: Corrected NetworkPolicy – Preserving DNS
Now, let’s fix the previous NetworkPolicy to correctly allow DNS traffic while still enforcing tier isolation.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tier-isolation-correct
namespace: default
spec:
podSelector:
matchLabels:
tier: backend-tier
policyTypes:
- Ingress
ingress:
- ports:
- protocol: UDP
port: 53
egress:
- to:
- podSelector:
matchLabels:
tier: web-tier
termination:
{}
Explanation:
- This NetworkPolicy is identical to the first example, which correctly allows DNS traffic to the `backend-tier` pods.
Verification:
kubectl apply -f tier-isolation-correct.yaml
kubectl get pods -n default -l tier=backend-tier
kubectl describe pod -n default
kubectl get events -n default --field-selector involvedObject.kind=Pod,involvedObject.name=,namespace=default
Verify that the `backend-tier` pods are now running successfully and can resolve DNS names. The events should show no DNS-related errors.



Leave a Reply