Kubernetes and Cloud Native Security Associate (KCSA)
Kubernetes Security Fundamentals
Network Policies
In this guide, you’ll learn how to secure communication between pods using Kubernetes NetworkPolicies. We’ll start with a permissive default, then restrict access to a database (DB) pod so that only an API pod can connect on port 3306. Finally, you’ll see how to scope access by namespace, IP range, and even add egress rules.
1. Default “Allow-All” Behavior
By default, Kubernetes does not restrict pod-to-pod traffic. Any pod in the cluster can communicate with any other pod on any port. To secure your DB pod:
- Deny all incoming traffic.
- Explicitly allow only the API pod to connect on port 3306.
2. Deny All Ingress to the DB Pod
First, create a policy that selects pods with label role=db and blocks all ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
Note
This policy ensures no traffic can reach the DB pod until you add explicit ingress rules.
3. Allow Ingress from the API Pod on Port 3306
Next, extend db-policy to permit traffic from the API pod:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
ports:
- protocol: TCP
port: 3306
Note
Responses from the DB pod back to the API pod are automatically allowed—no egress rule is required for reply traffic.
4. Restrict API Access by Namespace
If you have multiple namespaces (dev, test, prod), the preceding policy allows API pods from all namespaces. To limit to the prod namespace, add a namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: prod
ports:
- protocol: TCP
port: 3306
Warning
The target namespace must have the label name=prod before this selector will match.
5. Allow Traffic from an External IP Range
To permit a backup server (e.g., 192.168.5.10/32) outside your cluster to read from the DB, use an ipBlock:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: prod
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 3306
Here, matching either condition (API pod in prod OR external IP) grants access.
Selector Logic
| Combination | Semantics |
|---|---|
podSelector + namespaceSelector (same) | AND (both must match) |
Multiple entries under from or to | OR (any one entry may match) |
6. Adding Egress Rules
If your DB pod must initiate outbound connections (e.g., pushing backups), include Egress in policyTypes and define an egress rule:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
ports:
- protocol: TCP
port: 3306
egress:
- to:
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 80
This allows the DB pod to send TCP traffic on port 80 to the backup server at 192.168.5.10.
Summary of Policy Types
| Policy Type | Controls |
|---|---|
| Ingress | Incoming traffic to selected pods |
| Egress | Outgoing traffic from selected pods |
References
Watch Video
Watch video content
Practice Lab
Practice lab