Kubernetes Series: Control Pods Traffic with Network Policies
Explaining k8s NetworkPolicies resources, Pod isolation based on network traffic types, a NetworkPolicy manifest and NetworkPolicy fields with some practical examples
Introduction
This article covers the k8s Network Policies. Section 1 explains k8s NetworkPolicies resources, Section 2 goes through Pod isolation based on network traffic types. Section 3 illustrates a NetworkPolicy manifest and finally Section 4 details NetworkPolicy fields with some practical examples.
1. Network Policies
NetworkPolicies provide the ability to control Pods network traffic at the IP address or port level (OSI layer 3 or 4) through specifying how a Pod is allowed (or not) to communicate with other network entities. [1]
It is worth noting that NetworkPolicies only apply to Pods and are not relevant to other k8s resources.[1] They only restrict Pod-to-Pod communication when necessary.
Entities that a Pod can communicate with are identified through a combination of the following 3 identifiers: [1]
- Other Pods that are allowed (exception: a Pod cannot block access to itself)
- Namespaces that are allowed
- IP blocks (exception: traffic to and from the node where a Pod is running is always allowed, regardless of the IP address of the Pod or the node)
Prerequisites
NetworkPolicies are implemented by the k8s network plugins such as Calico. To use NetworkPolicies, you must be using a networking solution which supports NetworkPolicy. Creating a NetworkPolicy resource without a controller that implements it will have no effect.[1]
2. Pods Isolation
There are two sorts of isolation for a pod:
Isolation for ingress: ingress refers to inbound traffic received by the Pod.
Isolation for Egress: egress refers to outbound traffic sent by the Pod.
They are declared independently, and are both relevant for a communication from one Pod to another. [1]
2.1 Isolation for Ingress
By default, a Pod is non-isolated for ingress. All inbound connections to the Pod are allowed. [1]
A Pod is isolated for ingress if there is any NetworkPolicy that both selects the Pod and has ingress attribute in its policyTypes
(NetworkPolicy Fields are presented later on). [1]
When a Pod is isolated for ingress, the only allowed connections into the pod are those from the Pod's node and those allowed by the ingress
list of some NetworkPolicy that applies to the Pod for ingress. [1]
For a connection from a source Pod to a destination Pod to be allowed, both the egress policy on the source Pod and the ingress policy on the destination Pod need to allow the connection. If either side does not allow the connection, it will not happen
Important
NetworkPolicies do not conflict.They are additive. If any policy or policies apply to a given pod for a given direction, the connections allowed in that direction from that pod is the union of what the applicable policies allow. Thus, order of evaluation does not affect the policy result. [1]
2.2 Isolation for egress
By default, a Pod is non-isolated for egress. All outbound connections are allowed. [1]
A Pod is isolated for egress if there is any NetworkPolicy that both selects the Pod and has egress attribute in its policyTypes
(NetworkPolicy Fields are presented later on)[1]
When a Pod is isolated for egress, the only allowed connections from the pod are those allowed by the egress
list of the NetworkPolicy that applies to the Pod for egress. [1]
3. The NetworkPolicy YAML Manifest
Here’s an example of a NetworkPolicy taken from Kubernetes Official Documentation [1]
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
The above NetworkPolicy performs the following:
- It isolates Pods with the
role=db
label in thedefault
namespace for both ingress and egress traffic. - It defines a set of ingress rules that allow connections to Pods with the
role=db
label in thedefault
namespace on TCP port 6379 only from:
- Any pod in the
default
namespace with the labelrole=frontend
- Any pod in a namespace with the label
project=myproject
- Entities with IP addresses in the CIDR
172.17.0.0/16
except172.17.1.0/24
- It defines a set of egress rules that allow connections from Pods with the
role=db
label in thedefault
to CIDR10.0.0.0/24
on TCP port 5978 .
4. The NetworkPolicy Fields
podSelector
: selects the grouping of Pods based on their Labels in the same namespace as the NetworkPolicy. An emptypodSelector
selects all pods in thenamespace
.[1]
# this pod selector selects all pods having the label role: db
# in the NetworkPolicy namespace
...
spec:
podSelector:
matchLabels:
role: db
...
Important
# this pod selector selects all pods in the NetworkPolicy namespace
podSelector: {}
policyTypes
: It may include eitherIngress
,Egress
, or both. it indicates whether or not the NetworkPolicy applies toIngress
traffic to selected pod,Egress
traffic from selected pods, or both.[1]
...
policyTypes:
- Ingress
- Egress
...
Important
If no
policyTypes
are specified on a NetworkPolicy then by defaultIngress
will always be set andEgress
will be set if the NetworkPolicy has anyEgress
rulesif a
policyTypes
is defined withIngress
orEgress
but noIngress
orEgress
fields are specified later then by defaultIngress
andEgress
traffic will be denied. Here’s an example:
# Deny all ingress traffic:
# ---------------------------
# This NetworkPolicy selects all pods in the NetworkPolicy namespace
# but does not allow any ingress traffic to those pods.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
# Deny all egress traffic:
# ---------------------------
# This NetworkPolicy selects all pods in the NetworkPolicy namespace
# but does not allow any egress traffic to those pods.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
# Deny all ingress and all egress traffic
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Ingress
: Includes a list of allowedingress
rules. Each rule allows traffic which matches both thefrom
andports
sections. The example policy contains a singleingress
rule, which matches traffic on a single port, from one of three sources:ipBlock
,namespaceSelector
andpodSelector
.[1]
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
Important
If no rule is specified within the
Ingress
as follows. Then, all ingress traffic will be allowed. Here’s an example that allows all incoming ingress traffic to all pods in the NetworkPolicy namespace.
# Allow all ingress traffic to all pods within the NetworkPolicy namespace
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- {}
ipBlock
This selects particular IP CIDR ranges to allow as ingress sources or egress destinations. These should be cluster-external IPs, since Pod IPs are ephemeral and unpredictable.[1]
...
...
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
namespaceSelector
This selects particular namespaces having specific labels for which all Pods should be allowed as ingress sources or egress destinations.[1]
# There's two ways of targeting labeled namespaces:
# OPTION 1: target the namespace labeled project:myproject
ingress:
- from:
...
- namespaceSelector:
matchLabels:
project: myproject
# OPTION 2: target namespaces having project:myproject1 and app:myproject2 labels
- namespaceSelector:
matchExpressions:
- key: project
operator: In
values: ["myproject1", "myproject2"]
Important
namespaceSelector
andpodSelector
: A singleto
/from
entry that specifies bothnamespaceSelector
andpodSelector
selects particular Pods within particular namespaces. Be careful to use correct YAML syntax. For example:[1]
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
This policy contains a single
from
element allowing connections from Pods with the labelrole=client
in namespaces with the labeluser=alice
. [1]But the following policy is different:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
It contains two elements in the
from
array, and allows connections from Pods in the same namespace as the NetworkPolicy having the labelrole=client
, or from any Pod in any namespace labeleduser=alice
.[1]
Port
this field allowsIgress
orEgress
traffic to a specific port or to a range of port. For exampe:
# allow ingress traffic on port 6370
...
ingress:
- from:
...
ports:
- protocol: TCP
port: 6379
# allow ingress traffic on port range 32000 - 32768
...
ingress:
- from:
...
ports:
- protocol: TCP
port: 32000
endPort: 32768
Egress
: Each NetworkPolicy may include a list of allowedegress
rules. Each rule allows traffic which matches both theto
andports
sections. The example policy contains a single rule, which matches traffic on a single port to any destination in10.0.0.0/24
.[1]
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Important
If no rule is specified within the
Egress
as follows. Then, all egress traffic will be allowed. Here’s an example that allows all incoming egress traffic to all pods in the NetworkPolicy namespace.
# Allow all egress traffic
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
Conclusion
The primary goal of this article was to give a deeper understanding of the Kubernetes NetworkPolicy resource through practical examples. This has been accomplished by giving a general overview of the k8s NetworkPolicies and then getting more practical through different examples.
References
[1] Network policies (2023) Kubernetes. Available at: https://kubernetes.io/docs/concepts/services-networking/network-policies/ (Accessed: 08 June 2023).