========================================
KUBERNETES NETWORKPOLICY — CKA REVISION
========================================
1. WHAT IS NETWORKPOLICY?
--------------------------
NetworkPolicy controls network traffic to/from Pods.
It is an ALLOW-LIST model:
- No explicit deny: field
- If no policy isolates a direction -> traffic is allowed by default
- Once a Pod is isolated for a direction -> only explicitly allowed traffic works
- NetworkPolicy is enforced by the CNI/networking plugin
- Our lab uses Calico
Important:
NetworkPolicy is namespace-scoped.
2. BASIC STRUCTURE
------------------
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-policy
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- ...
egress:
- ...
3. TOP-LEVEL podSelector
------------------------
spec:
podSelector:
matchLabels:
app: backend
Means:
"Which Pods does THIS policy protect?"
It selects Pods in the SAME namespace as the NetworkPolicy.
podSelector: {}
Means:
"ALL Pods in this namespace."
4. INGRESS vs EGRESS
--------------------
INGRESS:
Traffic coming INTO the selected/protected Pod.
Mental model:
INGRESS = FROM whom can traffic come INTO ME?
Example:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
Meaning:
Backend Pods allow incoming TCP/80 traffic FROM frontend Pods.
Diagram:
Frontend
|
| TCP 80
↓
Backend
EGRESS:
Traffic going OUT FROM the selected/protected Pod.
Mental model:
EGRESS = TO where can traffic go FROM ME?
Example:
podSelector:
matchLabels:
app: frontend
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 80
Meaning:
Frontend Pods can send TCP/80 traffic TO backend Pods.
Diagram:
Frontend
|
| TCP 80
↓
Backend
5. EASY MEMORY
--------------
INGRESS:
MY POD <- FROM <- SOURCE
EGRESS:
MY POD -> TO -> DESTINATION
For traffic:
A -> B : 80
Think:
A's Egress
+
B's Ingress
6. from
-------
Used under ingress.
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
Means:
"Allow traffic FROM frontend Pods."
The from selector identifies the SOURCE.
7. to
------
Used under egress.
egress:
- to:
- podSelector:
matchLabels:
app: backend
Means:
"Allow traffic TO backend Pods."
The to selector identifies the DESTINATION.
8. podSelector IN PEER
----------------------
Example:
egress:
- to:
- podSelector:
matchLabels:
app: backend
Means destination Pods have app=backend.
Important:
Top-level podSelector and peer podSelector have different purposes.
Top-level:
"Which Pods am I protecting?"
Peer podSelector:
"Which Pods can communicate with those protected Pods?"
9. namespaceSelector
--------------------
Selects namespaces using namespace labels.
Example:
namespaceSelector:
matchLabels:
team: app
Means:
Select namespaces having:
team=app
10. namespaceSelector + podSelector
-----------------------------------
When BOTH are in the SAME peer item:
- namespaceSelector:
matchLabels:
team: app
podSelector:
matchLabels:
app: backend
This means:
Namespace MUST match
AND
Pod MUST match
So:
namespace team=app
AND
pod app=backend
11. SEPARATE PEER ITEMS = OR
----------------------------
Example:
from:
- podSelector:
matchLabels:
app: frontend
- namespaceSelector:
matchLabels:
team: app
Means:
frontend Pod
OR
Pod from namespace team=app
MEMORY:
Same peer item = AND
Separate list items = OR
12. ipBlock
-----------
Used to select IP/CIDR ranges.
Example:
from:
- ipBlock:
cidr: 192.168.10.0/24
Means:
Allow traffic from that IP range.
except excludes a subrange:
ipBlock:
cidr: 10.10.0.0/16
except:
- 10.10.5.0/24
Important:
ipBlock is IP-based selection.
Do not think of it simply as "external traffic only".
Actual behavior can depend on networking implementation.
13. PORTS
---------
ports controls destination port/protocol.
Example:
ports:
- protocol: TCP
port: 80
Means:
Allow TCP traffic to destination port 80.
Common protocols:
TCP
UDP
SCTP
14. endPort
----------
Allows a port range.
Example:
ports:
- protocol: TCP
port: 8000
endPort: 8080
Means:
TCP ports 8000 through 8080.
15. DEFAULT DENY — INGRESS
--------------------------
podSelector: {}
policyTypes:
- Ingress
No ingress rules.
Meaning:
All Pods in this namespace become ingress-isolated
and no ingress traffic is allowed by this policy.
Mental model:
ALL Pods
↓
Ingress
↓
DENY unless another applicable policy allows it
16. DEFAULT DENY — EGRESS
-------------------------
podSelector: {}
policyTypes:
- Egress
No egress rules.
Meaning:
All Pods in this namespace become egress-isolated
and no egress traffic is allowed by this policy.
This also blocks DNS unless DNS egress is explicitly allowed.
17. DEFAULT DENY — BOTH
-----------------------
podSelector: {}
policyTypes:
- Ingress
- Egress
Meaning:
All Pods in namespace are isolated for both directions.
Ingress -> blocked unless allowed
Egress -> blocked unless allowed
18. DEFAULT DENY + ALLOW
------------------------
Common real-world/CKA pattern:
1. Apply default deny
2. Add specific allow policy
Example:
Default:
ALL traffic denied
Then:
frontend -> backend TCP 80 allowed
Result:
frontend -> backend :80 ALLOWED
frontend -> database :3306 BLOCKED
frontend -> other Pod BLOCKED
19. MULTIPLE NETWORKPOLICIES
----------------------------
NetworkPolicies are ADDITIVE.
They do NOT override each other.
Example:
Policy A:
allows frontend
Policy B:
allows monitoring
Result:
frontend OR monitoring can communicate.
Think:
Policy A allowed traffic
+
Policy B allowed traffic
=
UNION of allowed traffic
A later policy does NOT automatically override an earlier policy.
20. POLICY TYPES
----------------
policyTypes tells Kubernetes which directions the policy isolates.
Ingress:
Controls incoming traffic.
Egress:
Controls outgoing traffic.
Both:
Controls both directions.
21. IMPORTANT DIRECTION RULE
----------------------------
For:
Frontend -> Backend
Frontend:
Egress
Backend:
Ingress
If frontend is egress-isolated:
Frontend's Egress must allow it.
If backend is ingress-isolated:
Backend's Ingress must allow it.
If both are isolated:
BOTH sides need applicable allow rules.
22. DNS + EGRESS
----------------
DNS is also network traffic.
If a Pod is egress-isolated:
DNS will be blocked unless explicitly allowed.
Typical DNS:
UDP 53
TCP 53
Example:
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Meaning:
Frontend
|
| DNS UDP/TCP 53
↓
CoreDNS
23. DNS TROUBLESHOOTING
----------------------
Check DNS Service:
kubectl get svc -n kube-system
Check namespace labels:
kubectl get ns kube-system --show-labels
Check CoreDNS labels:
kubectl get pods -n kube-system --show-labels
Check Pod DNS configuration:
kubectl exec <pod> -- cat /etc/resolv.conf
Typical:
nameserver 10.96.0.10
Then test:
kubectl exec <pod> -- nslookup kubernetes.default
IMPORTANT:
Do not blindly assume namespace or CoreDNS labels.
Inspect the actual cluster labels.
24. NETWORKPOLICY + SERVICE
---------------------------
Service provides stable networking/routing to Pods.
Example:
frontend
|
↓
backend-service
|
↓
backend Pods
Service:
- provides stable name/IP
- selects backend Pods
- routes traffic to endpoints
NetworkPolicy:
- controls allowed Pod traffic
- does NOT have a "serviceName" selector
There is no:
serviceName: backend-service
inside NetworkPolicy peers.
Think:
Service:
"Where should traffic be routed?"
NetworkPolicy:
"Is this Pod traffic allowed?"
25. SERVICE SELECTOR + ENDPOINTS
-------------------------------
Example Service:
selector:
app: backend
It finds Pods with:
app=backend
Those Pods become Service endpoints.
Check:
kubectl get svc <service-name>
kubectl get endpoints <service-name>
kubectl get endpointslice
If Service has no endpoints:
NetworkPolicy can be correct,
but Service traffic still fails because there is
no backend Pod to receive it.
26. SERVICE PORT vs targetPort
------------------------------
Example:
ports:
- port: 80
targetPort: 8080
Client accesses:
Service :80
Service forwards to:
Pod :8080
Conceptually:
Client
|
| :80
↓
Service
|
| → :8080
↓
Pod
For NetworkPolicy troubleshooting,
remember that policy concerns actual Pod traffic,
and exact Service translation/enforcement details
can depend on the networking implementation.
Do not blindly memorize:
"NetworkPolicy always uses Service port"
or
"NetworkPolicy always uses targetPort."
27. NETWORKPOLICY + SERVICE IMPORTANT POINT
-------------------------------------------
NetworkPolicy does not select a Service by name.
It selects traffic using:
podSelector
namespaceSelector
ipBlock
and controls ports using:
ports
protocol
endPort
28. CNI
-------
Kubernetes defines the NetworkPolicy API.
The networking/CNI plugin actually enforces it.
Mental model:
NetworkPolicy
↓
CNI / networking plugin
↓
Actual network enforcement
Your cluster:
Calico
We identified:
calico-node
calico-kube-controllers
So Calico is responsible for enforcing
NetworkPolicy in your lab.
29. CNI LIMITATION
------------------
NetworkPolicy behavior depends on CNI/networking implementation.
Not every networking implementation supports
every advanced networking feature identically.
For CKA:
Understand the concept:
Kubernetes API defines NetworkPolicy,
CNI implements/enforces it.
30. NETWORKPOLICY TROUBLESHOOTING
---------------------------------
If traffic is failing, check in this order:
1. Does NetworkPolicy exist?
kubectl get networkpolicy -n <namespace>
2. Inspect it:
kubectl describe networkpolicy <name> -n <namespace>
3. Check Pod labels:
kubectl get pods --show-labels -n <namespace>
4. Check namespace labels:
kubectl get ns --show-labels
5. Verify podSelector matches the intended Pods.
6. Verify from/to selector.
7. Verify namespaceSelector.
8. Verify port/protocol.
9. If DNS fails, check DNS policy.
10. Check Service:
kubectl get svc
11. Check endpoints:
kubectl get endpoints
kubectl get endpointslice
12. Check whether application is listening
on the expected port.
13. Check CNI/networking plugin.
31. COMMON CKA COMMANDS
-----------------------
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <name> -n <namespace>
kubectl get pods --show-labels -n <namespace>
kubectl get ns --show-labels
kubectl get svc -n <namespace>
kubectl get endpoints -n <namespace>
kubectl get endpointslice -n <namespace>
kubectl exec <pod> -- nc -vz <IP> <port>
kubectl exec <pod> -- nslookup <service>
kubectl exec <pod> -- cat /etc/resolv.conf
32. MOST IMPORTANT CKA MENTAL MODEL
-----------------------------------
Top-level podSelector
↓
"WHO AM I PROTECTING?"
Ingress
↓
"WHO CAN COME TO ME?"
↓
from
Egress
↓
"WHERE CAN I GO?"
↓
to
33. FINAL MEMORY TRICK
----------------------
INGRESS:
MY POD
↑
FROM
↑
SOURCE
"Who can come INTO me?"
EGRESS:
MY POD
↓
TO
↓
DESTINATION
"Where can I send traffic?"
34. EXAMPLE — COMPLETE
----------------------
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
# Frontend → Backend
- to:
- namespaceSelector:
matchLabels:
team: app
podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 80
# Frontend → CoreDNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Interpretation:
Top podSelector:
frontend = protected/source Pod
First egress rule:
frontend → backend :80 = ALLOWED
Second egress rule:
frontend → CoreDNS :53 = ALLOWED
Anything else from frontend:
BLOCKED because frontend is egress-isolated.
========================================
NETWORKPOLICY — 10 SECOND REVISION
========================================
podSelector
= Which Pods am I protecting?
Ingress
= Who can come INTO me?
from
= SOURCE
Egress
= Where can I send traffic?
to
= DESTINATION
namespaceSelector
= Select namespaces by labels
podSelector
= Select Pods by labels
ipBlock
= Select IP/CIDR
ports
= Destination port/protocol
Same peer item:
namespaceSelector + podSelector = AND
Separate peer items = OR
podSelector: {}
= All Pods in that namespace
policyTypes:
Ingress = isolate incoming traffic
Egress = isolate outgoing traffic
No applicable isolation:
traffic normally allowed
Isolated direction:
only explicitly allowed traffic works
Multiple policies:
ADDITIVE / UNION
Egress isolation:
remember DNS!
Service:
routes/selects Pods
NetworkPolicy:
controls Pod traffic
CNI:
actually enforces NetworkPolicy
========================================