Network Policy with Examples
Contents
Network Policy Configuration⌗
If a Network Policy object is defined in a namespace, it acts as an explicit allow list and all other traffic is denied. If there is no Network Policy object, all traffic is allowed in to that namespaces.
In order to control traffic flows in between namespaces and pods, selectors inside the Network Policy objects are used to explicitly allow traffic.
Multiple networkpolicy objects can be created in the same namespace to make it clear which rules are allowing traffic through.
Allow Pod to Pod - Same Namespace⌗
To simply allow traffic between pods in the same namespace, this would be the yaml to apply:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-same-namespace
spec:
ingress:
- from:
- podSelector: {}
podSelector: {}
policyTypes:
- Ingress
The key part of this is spec.ingress[0].from[0].podSelector: {}
which allows traffic between all the pods matched in that namespaces.
This configuration will disable traffic from the openshift Ingress pods.
Allow Openshift Ingress⌗
An example to allow Openshift Ingress routes to any pod in the namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-ingress
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: ingress
podSelector: {}
policyTypes:
- Ingress
This will not allow traffic between pods inside the namespace, but will allow Openshift routes to communicate with their backing pod inside the namespace.
Allow Pod-Pod and Openshift Ingress⌗
The spec.ingress.from
is an array of allowed rules to be applied in the network policy, so can be chained together. For example, this will allow both the Openshift Ingress routes and pod - pod traffic, but will not allow other namespaces access into these pods.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-and-namespace
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: ingress
- podSelector: {}
podSelector: {}
policyTypes:
- Ingress
Advanced Examples⌗
For these to work, either the pod or the namespaces or both require labels.
To label a namespace:
# oc label namespace <namespace> name=<namespace>
namespace/project1 labeled
To label a pod: (Note: this will only persist for the lifetime of the pod. It will need to be defined to persist)
# oc label pod pod2-1-ksmjx name=pod2
pod/pod2-1-ksmjx labeled
All pods in project A to a specific service/pod to project B⌗
In this example, we want all pods in project1
to be able to access pod2
in project2
In this example:
project2
has an existing network policy that only allows traffic between pods in that namespace (see Allow Pod to Pod).project1
has the labelingressname=project1
pod2
inproject2
has the labelname=pod2
- Namespace label
# oc get namespaces -l name=project1 NAME STATUS AGE project1 Active 140m
- Pod label
# oc -n project2 get pods -l ingressname=pod2 NAME READY STATUS RESTARTS AGE pod2-4-6msv5 1/1 Running 0 15m
This will allow traffic in from namespace project1
to just pod2
:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-namespace-to-pod
spec:
podSelector:
matchLabels:
ingressname: pod2
ingress:
- from:
- namespaceSelector:
matchLabels:
name: project1
Once this is created
# oc -n project2 create -f allow-namespace-to-pod.yaml
networkpolicy.networking.k8s.io/allow-namespace-to-pod created
Traffic is now able to reach pod2 from pods inside project1.
Specific pod in project A to a specific service/pod to project B⌗
Similarly to allowing all traffic in from a namespace label, here we can allow traffic in from a pod label that exists in the cluster.
In this example:
project2
has an existing network policy that only allows traffic between pods in that namespace (see Allow Pod to Pod).pod3
inproject2
has the label:ingressname=pod3
project1
has the labelname=project1
pod2
inproject1
has the label:name=project1-pod2
Pod label
# oc -n project2 get pods -l ingressname=pod3 NAME READY STATUS RESTARTS AGE pod3-1-jxpd8 1/1 Running 0 14m
Namespace label
# oc get pods --all-namespaces -l name=project1-pod2 NAMESPACE NAME READY STATUS RESTARTS AGE project1 pod2-1-ksmjx 1/1 Running 0 126m
This will now allow access from pod2
in project1
to pod3
in project2
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-pod-to-pod-x-namespace
spec:
podSelector:
matchLabels:
ingressname: pod3
ingress:
- from:
- namespaceSelector:
matchLabels:
name: project1
podSelector:
matchLabels:
name: project1-pod2
Update existing Projects⌗
In order to update existing projects, all that is required is to add a NetworkPolicy object to the namespace. Should this interfere with the operation of the pods in that namespace, removing the object will restore the previous allow all state.
# oc -n <target namespace> create -f <network-policy.yaml file>
networkpolicy.networking.k8s.io/allow-from-openshift-ingress created
And to remove the network policy in case of issues;
# oc -n <target namespace> delete networkpolicy <policy name>
networkpolicy.networking.k8s.io "allow-from-openshift-ingress" deleted
Update Default Project Template⌗
To add a default Network Policy to every new project that is created, a new default project template will need to be defined.
First, generate a project template yaml:
# oc adm create-bootstrap-project-template -o yaml > template.yaml
Then add the desired default NetworkPolicy to the template. In this example it will allow all pods in the same namespace to communicate and any routes access to the pods.
# This section is added to objects
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-policy
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: ingress
- podSelector: {}
podSelector: {}
policyTypes:
- Ingress
Then create this template in the openshift-config namespace
# oc create -f template.yaml -n openshift-config
template.template.openshift.io/project-request created
Once the template is created, the project resource will need to be updated to use the new template.
First edit the project.config.openshift.io/cluster
resource
# oc edit project.config.openshift.io/cluster
Then add the project template to spec
spec:
projectRequestTemplate:
name: project-request
Now new projects will be created with a default NetworkPolicy
# oc new-project project4
# oc -n project4 get networkpolicy
NAME POD-SELECTOR AGE
default-policy <none> 14s