Define and enforce Network Policies
Network policies control traffic flow at Layer 3 (IP) or Layer 4 (Port) levels. We can define accepted and blocked communication between Pods inside a cluster as well as to the outside world.
We configure these using the NetworkPolicy API object
Tip
The CNI must explicitly support NetworkPolicies. Not all do!
Let's take the following example:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
- from:
- namespaceSelector:
matchLabels:
team: core
- from:
- ipBlock:
cidr: 172.16.0.0/24
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector:
matchLabels:
env: staging
- to:
- ipBlock:
cidr: 8.8.8.8/32
ports:
- protocol: UDP
port: 53
flowchart LR
%% Styling classes
classDef denyNode fill:#1E2D3D,stroke:#F44336,stroke-width:2px,color:#fff;
%% Target Node
subgraph Policy [NetworkPolicy Applied - Default Deny]
Target("`TARGET PODS
(Isolated)
Selected via:
podSelector
(e.g., app: backend)`")
end
%% Ingress Rules
subgraph Ingress [INGRESS RULES - Incoming Traffic]
IngPod("`Pod Selector
app: frontend`")
IngNS("`Namespace Selector
team: core`")
IngIP("`IP Block Selector
172.16.0.0/24`")
IngExt("`External / Other Pods`")
end
%% Egress Rules
subgraph Egress [EGRESS RULES - Outgoing Traffic]
EgPod("`Pod Selector
app: database`")
EgNS("`Namespace Selector
env: staging`")
EgIP("`IP Block Selector
8.8.8.8/32 DNS`")
EgExt("`Untrusted External IP
e.g., 198.51.100.0/24`")
end
%% Connections
IngPod -->|ALLOW TCP 8080| Target
IngNS -->|ALLOW| Target
IngIP -->|ALLOW| Target
IngExt -->|BLOCKED Default Deny| Target
Target -->|ALLOW TCP 5432| EgPod
Target -->|ALLOW| EgNS
Target -->|ALLOW UDP 53| EgIP
Target -->|BLOCKED| EgExt
%% Apply Classes
class Target targetNode;
class IngPod,IngNS,IngIP,EgPod,EgNS,EgIP allowNode;
class IngExt,EgExt denyNode;
Tip
In Kubernetes, applying a NetworkPolicy to a pod automatically isolates it (enabling a "Default Deny"). Any traffic not explicitly listed in the ingress or egress rules will be blocked, which is how the "External / Other Pods" and "Untrusted External IP" connections are denied.
Let's break this down:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: backend
podSelector defines which Pods we want to target for this Network Policy. In this case, it's Pods with the label app:backend in the default namespace
Next we have policy types. We can specify ingress, egress or both:
policyTypes:
- Ingress
- Egress
Ingress rules permit what can talk to these Pods:
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
- from:
- namespaceSelector:
matchLabels:
team: core
- from:
- ipBlock:
cidr: 172.16.0.0/24
Egress rules permit what these Pods can talk to:
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector:
matchLabels:
env: staging
- to:
- ipBlock:
cidr: 8.8.8.8/32
ports:
- protocol: UDP
port: 53
Exam Tip
Network policies are applied to workloads using label selectors
Exam Tip
Once a network policy is applied, only traffic explicitly defined is permitted, synonymous to a "deny-all" approach