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