ποΈ Kubernetes NetworkPolicy: Full Guide¶
π What is NetworkPolicy?¶
NetworkPolicy is a Kubernetes object that controls network traffic between pods, and between pods and other network endpoints. It acts like a firewall for pod-to-pod communication.
π§ Think of it as security guards controlling who can enter or leave a building (pod). Without it, anyone can come and go freely.
β Default Behavior¶
By default, if no NetworkPolicy is defined: - All pods can talk to all other pods. - Any external IP can reach any pod.
But once a NetworkPolicy is applied to a pod: - The pod becomes isolated. - Only allowed traffic defined by the policy is permitted.
π NetworkPolicy Structure¶
Hereβs a full example with all major fields and detailed comments.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-access
namespace: bankapp # πΉ The namespace where this policy is applied
spec:
podSelector:
matchLabels:
role: db # π Target only pods with label 'role=db'
policyTypes:
- Ingress # β¬
οΈ Controls incoming traffic to the selected pods
- Egress # β‘οΈ Controls outgoing traffic from the selected pods
ingress:
- from:
- podSelector:
matchLabels:
role: api # β
Only allow pods with label 'role=api' to access
- namespaceSelector:
matchLabels:
team: frontend # β
Allow any pod from namespace with label team=frontend
ports:
- protocol: TCP
port: 5432 # β
Allow access only on PostgreSQL port (5432)
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24 # β
Allow outgoing traffic to internal network
except:
- 10.0.0.5/32 # β Block this specific IP
ports:
- protocol: TCP
port: 53 # β
Allow DNS resolution (TCP DNS)
π Field-by-Field Breakdown¶
| Field | Description |
|---|---|
podSelector | Defines which pods this policy applies to. |
policyTypes | Can be Ingress, Egress, or both. |
ingress | Controls which sources can send traffic to the selected pods. |
egress | Controls which destinations selected pods can send traffic to. |
namespaceSelector | Controls access based on namespace labels. |
ipBlock | Allows you to whitelist or blacklist IP ranges. |
ports | Limits communication to specific ports and protocols. |
π― Real World Case Study¶
Use Case: BankApp Security
Your banking backend (role=db) should: - Only be accessible by role=api pods. - Not communicate to any IP outside your internal network except DNS.
You apply this policy: - API pods can talk to DB pods. - DB pods can only go out to 10.0.0.0/24, but not 10.0.0.5. - No one else can talk to DB pods.
π Additional Examples¶
Example 1: Allow traffic only from same namespace¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
spec:
podSelector: {}
ingress:
- from:
- podSelector: {}
Example 2: Deny all ingress traffic (isolate pod)¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
ingress: [] # Deny all incoming
Example 3: Allow egress only to specific DNS IP¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-dns
spec:
podSelector:
matchLabels:
app: webapp
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 8.8.8.8/32 # Google DNS
ports:
- protocol: UDP
port: 53
π Create YAML Imperatively?¶
No built-in kubectl create networkpolicy command. You must:
kubectl create -f network-policy.yaml
π Related Resources¶
Create a network policy to allow traffic from the Internal application only to the payroll-service and db-service.
Use the spec given below. You might want to enable ingress traffic to the pod to test your rules in the UI.
Also, ensure that you allow egress traffic to DNS ports TCP and UDP (port 53) to enable DNS resolution from the internal pod.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: internal-policy
namespace: default
spec:
podSelector:
matchLabels:
name: internal
policyTypes:
- Egress
- Ingress
ingress:
- {}
egress:
- to:
- podSelector:
matchLabels:
name: mysql
ports:
- protocol: TCP
port: 3306
- to:
- podSelector:
matchLabels:
name: payroll
ports:
- protocol: TCP
port: 8080
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
controlplane ~ β kubectl describe netpol internal-policy
Name: internal-policy
Namespace: default
Created on: 2025-05-29 12:09:20 +0000 UTC
Labels: <none>
Annotations: <none>
Spec:
PodSelector: name=internal
Allowing ingress traffic:
To Port: <any> (traffic allowed to all ports)
From: <any> (traffic not restricted by source)
Allowing egress traffic:
To Port: 8080/TCP
To:
PodSelector: name=payroll
----------
To Port: 3306/TCP
To:
PodSelector: name=mysql
Policy Types: Egress, Ingress
controlplane ~ β kubectl describe netpol payroll-policy
Name: payroll-policy
Namespace: default
Created on: 2025-05-29 11:19:08 +0000 UTC
Labels: <none>
Annotations: <none>
Spec:
PodSelector: name=payroll
Allowing ingress traffic:
To Port: 8080/TCP
From:
PodSelector: name=internal
Not affecting egress traffic
Policy Types: Ingress
The curl command times out following the installation of the Calico CNI, which supports Network Policies. As a result, the deny-backend policy began to take effect after the deployed applications were restarted.
kubectl exec -it frontend -- curl -m 5 172.17.49.71