Kubernetes NetworkPolicy: Preventing Cross-Tier Traffic with DNS Access
This tutorial demonstrates how to use Kubernetes NetworkPolicies to restrict communication between different tiers of your application while ensuring that services within each tier can still resolve DNS names. We’ll cover common pitfalls and demonstrate corrective actions through practical examples.
Understanding the Problem
Without NetworkPolicies, all pods in a Kubernetes cluster can communicate with each other. This can create security risks, especially in multi-tier applications. We’ll focus on preventing traffic from the Web Tier (frontend) to the Backend Tier (API and Database) and ensuring that the API tier can still resolve DNS names for its services. DNS access is critical for the API tier to function correctly.
Example 1: Initial State – Open Communication
Initially, all tiers can communicate. This is a risky state. We’ll start with a simple setup and then introduce the issues.
apiVersion: v1
kind: Pod
metadata:
name: web-frontend
labels:
app: web-frontend
spec:
containers:
- name: frontend
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: api-backend
labels:
app: api-backend
spec:
containers:
- name: backend
image: busybox:latest
command: ["sleep", "3600"]
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Pod
metadata:
name: db-backend
labels:
app: db-backend
spec:
containers:
- name: db
image: busybox:latest
command: ["sleep", "3600"]
ports:
- containerPort: 5432
Verification:
- `kubectl get pods -l app=web-frontend`
- `kubectl get pods -l app=api-backend`
- `kubectl get pods -l app=db-backend`
You should see all three pods running. Currently, the web frontend can directly connect to the api backend on port 8080 and the db backend on port 5432. This is undesirable.
Example 2: Introducing NetworkPolicy – Restricting Web Tier Access
Now, let’s restrict the web frontend from connecting to the backend tiers. This is the core of the tutorial.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-web-tier
namespace: default
spec:
podSelector:
matchLabels:
app: api-backend
ingress:
- ports:
- port: 8080
protocol: TCP
namespaceSelector:
matchLabels:
app: web-frontend
policyTypes:
- Ingress
Explanation: This NetworkPolicy defines a rule to restrict incoming traffic to pods labeled `app: api-backend` on port 8080. The `namespaceSelector` ensures this applies only within the `default` namespace. Critically, the `policyTypes` are explicitly set to `Ingress`. Without this, the network policy may not function as expected. The `matchLabels` are set to the labels of the API Backend pods.
Verification:
- `kubectl get networkpolicies -l app=api-backend`
- `kubectl describe networkpolicy restrict-web-tier`
- Attempt to connect from the web frontend pod to the api backend pod on port 8080. This should fail.
Example 3: Correcting a DNS Access Issue – Incomplete Policy & Correction
We’ve now restricted traffic, but the API tier still needs to resolve DNS names. If our NetworkPolicy is too restrictive, this will break the API. The key is that NetworkPolicies by default allow egress traffic to the Kubernetes DNS service (10.96.0.10). However, we can explicitly allow DNS resolution.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-resolution
namespace: default
spec:
podSelector:
matchLabels:
app: api-backend
ingress:
- ports:
- port: 53
protocol: UDP
namespaceSelector:
matchLabels:
app: kube-dns
policyTypes:
- Ingress
Explanation: This NetworkPolicy allows UDP traffic to port 53 (DNS) from the API backend pods, specifically targeting the Kubernetes DNS service (10.96.0.10). The `policyTypes` are explicitly set to `Ingress`. We have defined `matchLabels` on the Kubernetes DNS service to target the specific DNS server we want to use.
Verification:
- `kubectl get networkpolicies -l app=api-backend`
- `kubectl describe networkpolicy allow-dns-resolution`
- Exec into the api-backend pod and run `nslookup google.com`. It should resolve successfully.
Common Mistake & Correction: If this NetworkPolicy still doesn’t work, ensure you’ve applied it after the API Backend pods are running. NetworkPolicies are applied to existing pods, not created new ones. Also, ensure the labels are correctly applied to the pods and the NetworkPolicy selectors match these labels.
This tutorial demonstrates a basic scenario of restricting cross-tier traffic with NetworkPolicies while maintaining DNS access. Remember to thoroughly test your NetworkPolicies and understand their impact on your application.



Leave a Reply