Kubernetes NetworkPolicy Explained: Ingress, Egress, Default Deny, Selectors, and IP-Based Rules

Devops | 3x AWS Certified | CKA
A practical guide to standard Kubernetes NetworkPolicy using only the Kubernetes NetworkPolicy API.
This article intentionally does not cover Cilium, Calico-specific policy features, or other extended policy engines. Those are separate topics.
Why NetworkPolicy feels confusing
NetworkPolicy looks straightforward:
kind: NetworkPolicy
spec:
podSelector:
policyTypes:
ingress:
egress:
But several concepts interact:
Is the Pod isolated for ingress?
Is it isolated for egress?
Does an empty rule mean allow everything or deny everything?
What happens when multiple policies select the same Pod?
Does
frommean the source or destination?Does
tomean the source or destination?Can I select a Pod?
Can I select a namespace?
Can I select an external IP?
What happens when I specify a port?
Can standard NetworkPolicy explicitly deny one IP/port?
What happens to return traffic?
The easiest way to understand all of this is to build the mental model first.
1. The two directions: Ingress and Egress
Think of every Pod as having two doors:
POD
┌──────────────┐
│ │
INGRESS ──>│ │<── EGRESS
│ │
└──────────────┘
Ingress
Ingress is traffic coming into the Pod.
frontend ───────────────> backend
INGRESS
From the backend's point of view, this is ingress traffic.
Egress
Egress is traffic leaving the Pod.
frontend ───────────────> backend
EGRESS
From the frontend's point of view, this is egress traffic.
The same connection can therefore be:
frontend backend
│ │
│ ─────── TCP connection ─────> │
│ │
EGRESS INGRESS
This distinction is fundamental.
2. The default behavior: everything is open
If there is no NetworkPolicy selecting a Pod, the Pod is non-isolated.
In the normal Kubernetes NetworkPolicy model:
Ingress = allowed
Egress = allowed
So without applicable policies:
Pod A ───────────────> Pod B ✓
Pod B ───────────────> Pod A ✓
Pod A ───────────────> Internet ✓
NetworkPolicy is not a firewall that automatically blocks traffic just because the API object exists somewhere in the cluster.
The important question is:
Does a NetworkPolicy select this Pod for this direction?
3. A NetworkPolicy has a target: podSelector
Every NetworkPolicy has a podSelector.
Example:
spec:
podSelector:
matchLabels:
app: backend
This means:
Apply this policy to Pods with the label
app=backendin the policy's namespace.
For example:
metadata:
labels:
app: backend
matches:
Pod A: app=backend ← selected
Pod B: app=frontend ← not selected
Pod C: app=database ← not selected
Empty podSelector
This:
podSelector: {}
means:
Select all Pods in the policy's namespace.
That is why default-deny policies commonly use:
podSelector: {}
4. policyTypes: which direction are we controlling?
policyTypes tells Kubernetes whether the policy applies to:
IngressEgressor both
Example:
policyTypes:
- Ingress
means:
This policy isolates the selected Pods for incoming traffic.
Example:
policyTypes:
- Egress
means:
This policy isolates the selected Pods for outgoing traffic.
Example:
policyTypes:
- Ingress
- Egress
means:
Isolate the selected Pods in both directions.
A useful mental model is:
policyTypes
│
├── Ingress → control incoming traffic
│
└── Egress → control outgoing traffic
For clarity, it is a good practice to explicitly specify policyTypes, especially for an egress-only policy.
5. Standard NetworkPolicy is an ALLOW-list
This is the single most important concept.
Standard Kubernetes NetworkPolicy does not provide an explicit deny: rule.
You cannot write:
egress:
- deny:
- ipBlock:
cidr: 192.168.121.17/32
There is no standard deny field in the Kubernetes NetworkPolicy API.
Instead, NetworkPolicy answers:
What traffic should be allowed?
Everything else is implicitly denied once the Pod is isolated for that direction.
Think:
No policy selecting Pod
↓
ALLOW ALL
Policy selects Pod for Egress
↓
ALLOW only
what matches rules
6. An Egress rule automatically creates egress isolation
This is a very common point of confusion.
Suppose there is no default-deny policy.
You create:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-database
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 192.168.121.17/32
ports:
- protocol: TCP
port: 9999
You do not need another empty egress policy first.
The selected Pods become egress-isolated.
The result is:
backend Pod
│
├──> 192.168.121.17:9999/TCP ✓ ALLOW
│
├──> 192.168.121.17:80 ✗ DENY
│
├──> 8.8.8.8:443 ✗ DENY
│
└──> another Pod ✗ DENY
Why?
Because the Pod is now egress-isolated and the policy only allows traffic matching its egress rule.
7. Compare that with having no Egress policy
Scenario A: no egress policy
Pod
│
├──> 192.168.121.17:9999 ✓
├──> 192.168.121.17:80 ✓
├──> 8.8.8.8:443 ✓
└──> anywhere else ✓
Egress is open.
Scenario B: an Egress policy allows one destination
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 192.168.121.17/32
ports:
- protocol: TCP
port: 9999
Now:
192.168.121.17:9999 ✓
Everything else ✗
This distinction is critical:
The existence of an applicable Egress policy changes the selected Pod from non-isolated to egress-isolated.
8. Default-deny Ingress
A classic default-deny ingress policy is:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
Notice there is no ingress: rule.
This means:
All Pods in namespace
│
↓
Ingress isolation enabled
│
↓
No ingress rules
│
↓
DENY ALL INGRESS
So:
frontend ───────X──────> backend
random ───────X──────> backend
external ───────X──────> backend
The empty rule set is not "allow everything."
It means:
The selected Pods are isolated, and this policy allows no ingress traffic.
9. Default-deny Egress
Same concept:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
Result:
All Pods
│
↓
Egress isolation
│
↓
No egress rules
│
↓
DENY ALL EGRESS
So:
Pod ─────X────> Internet
Pod ─────X────> database
Pod ─────X────> another Pod
All are blocked unless another applicable NetworkPolicy allows them.
Important: DNS
A default-deny egress policy also blocks DNS traffic unless DNS is explicitly allowed by another applicable policy.
That is a common reason applications suddenly stop resolving service names after egress lockdown.
10. Default-deny both directions
You can isolate both directions with one policy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
No ingress rules.
No egress rules.
Therefore:
POD
│
┌────────┴────────┐
│ │
INGRESS EGRESS
│ │
DENY DENY
This is the strongest baseline:
DEFAULT DENY
+
EXPLICIT ALLOW
11. ingress.from: Who can connect to me?
Suppose the backend has:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
Read this as:
Allow traffic from frontend Pods into backend Pods.
So:
frontend ─────────> backend
✓
but:
random-pod ───────> backend
✗
Remember:
INGRESS
│
└── from = SOURCE
12. egress.to: Where can I connect?
Now reverse the direction.
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: backend
Read this as:
Allow frontend Pods to connect to backend Pods.
So:
frontend ─────────> backend
✓
Remember:
EGRESS
│
└── to = DESTINATION
A simple memory trick:
Ingress → from = who is coming TO me?
Egress → to = where am I going?
13. What can from and to target?
Standard Kubernetes NetworkPolicy provides three main peer selector mechanisms:
podSelectornamespaceSelectoripBlock
These can be used under:
ingress:
- from:
and:
egress:
- to:
Let's look at each.
14. Target type #1: podSelector
Example:
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
This selects Pods with:
app=frontend
in the same namespace as the NetworkPolicy when podSelector is used by itself.
Example:
Namespace: default
frontend Pod
app=frontend
backend Pod
app=backend
Policy attached to backend:
frontend ─────────> backend
✓
A frontend Pod in another namespace is not selected by this standalone podSelector.
15. Target type #2: namespaceSelector
You can select namespaces by their labels.
Example:
ingress:
- from:
- namespaceSelector:
matchLabels:
team: platform
Read this as:
Allow traffic from Pods in namespaces labeled
team=platform.
This can allow Pods from multiple namespaces.
Think:
namespace-a team=platform
namespace-b team=platform
namespace-c team=payments
Then:
namespace-a Pods ──┐
├──> backend ✓
namespace-b Pods ──┘
namespace-c Pods ─────> backend ✗
16. Target type #3: ipBlock
ipBlock lets you select an IP range using CIDR.
Example:
egress:
- to:
- ipBlock:
cidr: 192.168.121.17/32
/32 represents exactly one IPv4 address:
192.168.121.17
You can also specify a range:
ipBlock:
cidr: 192.168.121.0/24
which represents the CIDR range.
You can exclude a smaller CIDR from the range:
ipBlock:
cidr: 192.168.121.0/24
except:
- 192.168.121.17/32
Conceptually:
192.168.121.0/24
│
├── most addresses ✓
│
└── .17 ✗ excluded
Important limitation
ipBlock.except excludes an IP/CIDR range. It is not a port-specific deny mechanism.
So it can express:
ALLOW 192.168.121.0/24
EXCEPT 192.168.121.17
but standard NetworkPolicy cannot express:
ALLOW 192.168.121.17:80
DENY 192.168.121.17:9999
ALLOW 192.168.121.17:443
using an explicit deny rule.
17. Can ipBlock target external IPs?
Yes. ipBlock is intended for IP/CIDR-based policy, including traffic between Pods and the outside world.
For example:
egress:
- to:
- ipBlock:
cidr: 8.8.8.8/32
can express an allow rule for traffic to that IP.
But there is an important Kubernetes caveat:
The exact source/destination IP seen by NetworkPolicy can depend on address rewriting performed by the network implementation, cloud provider, Services, and other networking components.
For example, traffic involving a Service or load balancer may undergo source/destination NAT, so the IP you expect may not be the IP the NetworkPolicy implementation evaluates.
This is one reason ipBlock behavior should be tested in the actual cluster/network implementation.
18. podSelector + namespaceSelector: the AND case
You can combine them in the same peer entry:
ingress:
- from:
- namespaceSelector:
matchLabels:
team: platform
podSelector:
matchLabels:
app: frontend
This means:
Allow Pods labeled
app=frontendAND located in namespaces labeledteam=platform.
Conceptually:
namespace must match
AND
Pod must match
Example:
namespace-a
team=platform
└── frontend
✓
namespace-b
team=payments
└── frontend
✗
namespace-c
team=platform
└── database
✗
19. A very common YAML mistake: AND vs OR
Compare these two.
Case A: same peer entry
from:
- namespaceSelector:
matchLabels:
team: platform
podSelector:
matchLabels:
app: frontend
This means:
namespace = platform
AND
pod = frontend
Case B: two peer entries
from:
- namespaceSelector:
matchLabels:
team: platform
- podSelector:
matchLabels:
app: frontend
This means:
namespace = platform
OR
Pod = frontend in the policy's namespace
The indentation changes the meaning.
This is a very important NetworkPolicy YAML detail.
20. Ports: another important concept
Suppose you have:
egress:
- to:
- ipBlock:
cidr: 192.168.121.17/32
ports:
- protocol: TCP
port: 9999
The destination and port both need to match.
Think:
destination MATCH
AND
port MATCH
↓
ALLOW
Therefore:
192.168.121.17:9999/TCP ✓
192.168.121.17:80/TCP ✗
8.8.8.8:9999/TCP ✗
The rule is not saying "allow the IP OR the port."
It is saying:
Allow traffic that matches the destination and the port.
21. Multiple ports in one rule are OR
Example:
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
means:
TCP/80 ✓
TCP/443 ✓
The ports inside that list are logically ORed.
22. Multiple destinations in one rule are OR
Example:
to:
- ipBlock:
cidr: 10.0.0.0/24
- ipBlock:
cidr: 192.168.1.0/24
means:
10.0.0.0/24 ✓
192.168.1.0/24 ✓
The destination peers are logically ORed.
23. Multiple rules are also additive
Suppose:
egress:
- to:
- podSelector:
matchLabels:
app: database
- to:
- podSelector:
matchLabels:
app: redis
Then:
backend ─────> database ✓
backend ─────> redis ✓
backend ─────> frontend ✗
Think:
Rule 1 OR Rule 2 OR Rule 3 ...
not:
Rule 1 AND Rule 2
24. Multiple NetworkPolicies are additive
This is one of the most important concepts.
Suppose Policy A allows:
frontend → backend:8080
and Policy B allows:
monitoring → backend:9090
If both policies select the same backend Pods:
frontend ───> backend:8080 ✓
monitoring ───> backend:9090 ✓
The policies do not override each other.
Their allowed traffic is combined.
Think:
Policy A
│
├── allow X
│
Policy B
│
├── allow Y
│
Policy C
│
├── allow Z
│
↓
X + Y + Z are allowed
This also means there is no standard policy ordering such as:
Policy 1
↓
Policy 2
↓
Policy 3
The policies are combined additively.
25. There is no "deny wins" in standard NetworkPolicy
Because standard NetworkPolicy does not have explicit deny rules, you cannot normally create:
Policy A:
ALLOW 10.0.0.0/24
Policy B:
DENY 10.0.0.5
and expect the second policy to override the first.
There is no standard deny rule.
Instead, the design is:
DEFAULT DENY
+
EXPLICIT ALLOW
This is why NetworkPolicy is best understood as an allow-list.
26. Pod-to-Pod traffic: both directions matter
Suppose:
frontend Pod ───────────────> backend Pod
There are potentially two policy checks:
frontend backend
│ │
│ EGRESS │ INGRESS
│ │
└──────── connection ─────────>│
For a Pod-to-Pod connection to work when both Pods are isolated:
SOURCE EGRESS = ALLOW
AND
DESTINATION INGRESS = ALLOW
↓
CONNECTION = ALLOW
If either side blocks it:
SOURCE EGRESS = DENY
OR
DESTINATION INGRESS = DENY
↓
CONNECTION = BLOCKED
27. Scenario: both sides are default-deny
Suppose we start with:
Frontend:
Egress = DENY ALL
Backend:
Ingress = DENY ALL
Then:
frontend ─────────X────────> backend
Blocked.
28. Scenario: only frontend Egress is allowed
Now we add:
Frontend:
Egress → ALLOW backend:8080
Backend:
Ingress → still DENY ALL
Result:
frontend ─────────X────────> backend
Still blocked.
Why?
Because:
Frontend Egress = ✓
Backend Ingress = ✗
Both sides are not allowed.
29. Scenario: only backend Ingress is allowed
Now instead:
Frontend:
Egress → still DENY ALL
Backend:
Ingress → ALLOW frontend:8080
Result:
frontend ─────────X────────> backend
Still blocked.
Why?
Frontend Egress = ✗
Backend Ingress = ✓
Again, both sides are not allowed.
30. Scenario: both sides are allowed
Now:
Frontend:
Egress → ALLOW backend:8080
Backend:
Ingress → ALLOW frontend:8080
Result:
frontend ──────────────────> backend
ALLOWED ✓
Now:
Frontend Egress = ✓
Backend Ingress = ✓
The connection works.
31. But do you always need both policies?
No.
This is an important nuance.
Suppose:
Frontend:
Egress = NOT isolated
Backend:
Ingress = ALLOW frontend:8080
Then the connection can work.
Why?
Because the frontend has no applicable Egress isolation, so its egress is allowed by default.
Likewise:
Frontend:
Egress = ALLOW backend:8080
Backend:
Ingress = NOT isolated
can also work.
The actual rule is:
If the source is egress-isolated, its egress must allow the connection.
If the destination is ingress-isolated, its ingress must allow the connection.
If neither side is isolated, traffic is allowed by default.
32. Return traffic
Suppose:
frontend ─────────> backend
request
is allowed.
The backend's response traffic for that connection is permitted as reply traffic.
You do not normally need to create a separate NetworkPolicy rule just to permit the response to an already allowed connection.
Think:
frontend backend
─────── request ────────>
<────── response ────────
ONE CONNECTION
NetworkPolicy is concerned with whether the connection is allowed; it is not normally necessary to model the return packet as an independent application connection.
33. A complete example
Suppose we have:
frontend Pod
app=frontend
backend Pod
app=backend
database Pod
app=database
We want:
frontend → backend:8080
backend → database:5432
and we want everything else denied.
A common design is:
Default deny
+
Allow frontend → backend
+
Allow backend → database
Default deny
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Allow frontend to backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Allow backend to database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-database
namespace: default
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
If backend egress is still denied by the default-deny policy, you would also need an egress allow for backend → database.
For example:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-egress-to-database
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
Now the flow is:
frontend
│
│ Egress must be allowed
↓
backend
│
│ Egress must be allowed
↓
database
And the database must allow the corresponding ingress.
34. A practical way to read any NetworkPolicy
Whenever you see a NetworkPolicy, read it in this order:
Step 1 — Who is selected?
Look at:
podSelector:
Ask:
Which Pods does this policy apply to?
Step 2 — Which direction?
Look at:
policyTypes:
Ask:
Is this controlling ingress, egress, or both?
Step 3 — Who/where is allowed?
For ingress:
from:
Ask:
Who can connect to these Pods?
For egress:
to:
Ask:
Where can these Pods connect?
Step 4 — Which ports?
Look at:
ports:
Ask:
Which protocol and destination port are allowed?
Step 5 — Remember the implicit deny
If the Pod is isolated for that direction:
matches a rule → ALLOW
doesn't match → DENY
35. Your original policy, translated
Your original policy was:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-metadata
namespace: default
spec:
podSelector:
matchLabels:
app: app
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 192.168.121.17/32
ports:
- protocol: TCP
port: 9999
Read it in plain English:
Select Pods with
app=app.
Then:
Isolate them for Egress.
Then:
Allow TCP traffic to
192.168.121.17on port9999.
Therefore:
app=app Pod
192.168.121.17:9999/TCP ✓ ALLOW
192.168.121.17:80 ✗ DENY
192.168.121.17:443 ✗ DENY
8.8.8.8:443 ✗ DENY
another Pod ✗ DENY
So despite its name:
name: deny-metadata
the policy is actually allowing the metadata destination.
The name does not change policy behavior.
36. If I want to block one specific IP/port, what should I remember?
Suppose your requirement is:
ALLOW everything
EXCEPT
192.168.121.17:9999
Standard Kubernetes NetworkPolicy does not provide an explicit deny rule for this.
You cannot simply write:
deny:
- ipBlock:
cidr: 192.168.121.17/32
ports:
- port: 9999
That field does not exist in the standard NetworkPolicy API.
Instead, standard NetworkPolicy works by defining the traffic that is allowed.
This is why a precise "deny one IP + port while allowing everything else" requirement can require careful allow-list design, or a policy engine with capabilities beyond the standard Kubernetes NetworkPolicy API.
We will cover those extended policy engines separately.
37. What NetworkPolicy can target
For standard Kubernetes NetworkPolicy, keep these three peer mechanisms in your mental model:
| Selector | What it targets | Typical use |
|---|---|---|
podSelector |
Pods | frontend → backend |
namespaceSelector |
Namespaces, and therefore Pods in them | allow traffic from another team/namespace |
ipBlock |
IP/CIDR ranges | external networks, specific IPs, CIDRs |
You can also combine namespaceSelector and podSelector in the same peer entry to select specific Pods in selected namespaces.
38. What about Services?
NetworkPolicy fundamentally operates at the network traffic level, not at the Kubernetes Service object level.
For example, an application may connect to:
my-backend.default.svc.cluster.local:8080
The traffic ultimately reaches a Pod endpoint.
How the Service IP, endpoint IP, NAT, routing, and NetworkPolicy implementation interact can depend on the cluster's networking implementation.
Therefore, don't assume that writing a policy around a Service's virtual IP is always equivalent to writing a policy around the actual Pod endpoints.
For exact behavior involving Services and IP rewriting, test with your actual network plugin.
39. NetworkPolicy requires enforcement support
Creating a NetworkPolicy object does not magically enforce traffic filtering.
Your cluster must use a network plugin that supports NetworkPolicy enforcement.
For example, the Kubernetes API can accept:
kubectl apply -f network-policy.yaml
but actual traffic enforcement depends on the networking implementation.
This is why NetworkPolicy behavior can sometimes differ between clusters.
40. The mental model to remember
If you remember only these rules, you can understand most standard NetworkPolicies.
Rule 1 — No applicable policy means open
No policy selecting Pod
↓
Ingress = allowed
Egress = allowed
Rule 2 — An applicable policy isolates that direction
Ingress policy selects Pod
↓
Ingress becomes allow-list
Egress policy selects Pod
↓
Egress becomes allow-list
Rule 3 — Empty rules mean deny everything for that isolated direction
Ingress isolation
+
no ingress rules
↓
DENY ALL INGRESS
Egress isolation
+
no egress rules
↓
DENY ALL EGRESS
Rule 4 — NetworkPolicy is allow-list based
MATCHES an allowed rule → ALLOW
DOES NOT MATCH → DENY
for an isolated direction.
Rule 5 — Multiple policies are additive
Policy A allows X
Policy B allows Y
Result:
X + Y are allowed
Rule 6 — Pod-to-Pod traffic can involve both sides
SOURCE EGRESS ✓
+
DESTINATION INGRESS ✓
=
CONNECTION ✓
when both directions are isolated.
41. The simplest possible picture
Keep this picture in your head:
Kubernetes Pod
│
┌─────────┴─────────┐
│ │
INGRESS EGRESS
│ │
"from" "to"
│ │
↓ ↓
Who can reach me? Where can I reach?
│ │
└─────────┬─────────┘
│
ALLOW-LIST
│
Everything else
is denied
when isolated
And for peer selection:
from / to
│
┌─────────┼─────────┐
│ │ │
↓ ↓ ↓
Pod Namespace IP/CIDR
selector selector ipBlock
That's the standard Kubernetes NetworkPolicy model.
42. Final cheat sheet
podSelector
↓
Which Pods does this policy apply to?
policyTypes
↓
Which direction becomes isolated?
Ingress
↓
Traffic coming INTO selected Pods
Egress
↓
Traffic going OUT OF selected Pods
from
↓
Ingress source
to
↓
Egress destination
podSelector
↓
Select Pods
namespaceSelector
↓
Select namespaces
ipBlock
↓
Select IP/CIDR ranges
ports
↓
Restrict protocol + destination port
No applicable policy
↓
Traffic allowed by default
Applicable policy + no matching rule
↓
Traffic denied for that isolated direction
Multiple policies
↓
Allowed traffic is combined additively
Explicit deny
↓
Not part of the standard Kubernetes NetworkPolicy API
Official Kubernetes sources
This article intentionally uses the standard Kubernetes NetworkPolicy model and official Kubernetes documentation as the source of truth.
Kubernetes Network Policies: https://kubernetes.io/docs/concepts/services-networking/network-policies/
Kubernetes NetworkPolicy API reference: https://kubernetes.io/docs/reference/kubernetes-api/networking/network-policy-v1/
The official API reference defines podSelector, policyTypes, ingress, egress, podSelector, namespaceSelector, ipBlock, ports, and the additive behavior of applicable policies.
Note: NetworkPolicy enforcement requires a network plugin that supports NetworkPolicy. Exact behavior around source/destination IP rewriting, Services, load balancers, and other networking features can depend on the cluster's networking implementation.



