This blog will go in to the “software defined networking” of “Configure networking components” objective of the EX280 exam from RedHat. In this post we will:
- Traffic to pods
- The types of Network Policy’s we can create
- Create a Network Policy based on a application label
This post focuses on Ingress (incoming traffic). You can also create Egress policy’s to manage outgoing traffic
As always. We will be doing all the examples in a CRC (Code Ready Containers) environment.
Traffic to pods
As explained in my post about Services and Routes pods are accessed in the cluster by using services. We can filter traffic to these services using Network Policy’s. These can allow traffic based on different ‘keys’ called identifiers. By default no traffic is blocked to a service and you can not block traffic from a pod to itself. When you add a Network Policy all traffic is blocked by default. Also, good to keep in mind is that Network Policy’s are cumulative. Meaning they won’t cancel each other out.
Types of Network Policy Identifiers
You can use three (3) ways to block or allow traffic to your Service, you can filter:
- Pods: by using a label (podSelector). You can allow traffic from certain pods in your cluster.
- Namespace: by using the label (namespaceSelector) you can allow access from a given namespace in the cluster
- IP Blocks: by using the IP (ipBlock) you can block or allow IPv4 addresses to access a service
Example of a Network Policy
A {networkPolicy}
can look like this:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-from-label
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
access-to-service: "true"
In this example:
- We create a network policy called
allow-from-label
- It will work on the pods that are labeled as
app: nginx
- It will allow access to our service if the pod that access our service has a label
access-to-service
which is set totrue
To create a IPBlock type Network Policy we would use:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
....
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
To create a namespace type Network Policy we would use:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
....
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
Creating a policy
To test if we can block traffic to a pod using a Network Policy we will spin up two (2) apps called server
and client
in our namespace called restricted-network
. We will secure access to our server
service by creating a Network Policy called access-policy
:
Creating the project and apps:
$ oc new-project restricted-network
$ oc new-app --name client --image bitnami/nginx
$ oc new-app --name server --image bitnami/nginx
Now that we have created the server app we can run a curl
command using oc exec
with our client pod and check if we can connect to it. But first we have to expose
the server:
$ oc expose service/server
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
server server-restricted-network.apps-crc.testing server 8080 None
Check, our target will be the service: server
. Lets curl
it:
$ oc exec -it client-76ccdb697d-n2xqp -- curl -v server:8080 | grep HTTP
> GET / HTTP/1.1
< HTTP/1.1 200 OK
Great! We can set up a connection. Now lets see what happens when we create the following network policy:
# allow-from-label.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-from-label
spec:
podSelector:
matchLabels:
policy: "true"
ingress:
- from:
- podSelector:
matchLabels:
access-to-service: "true"
And let’s apply it:
$ oc apply -f allow-from-label.yaml
networkpolicy.networking.k8s.io/allow-from-label configured
$ oc get networkpolicies.networking.k8s.io
NAME POD-SELECTOR AGE
allow-from-label deployment=server 5s
Now we only need to add a label to our server to link this Network Policy. We will apply the label: policy: "true"
:
$ oc label pod server-68ff6d4bfd-prd4w policy=true
pod/server-68ff6d4bfd-prd4w labeled
Let’s test our access again with the -m
flag (--max-time
), otherwise we will be waiting a long time:
$ oc exec -it client-76ccdb697d-n2xqp -- curl -v -m 3 server:8080 | grep HTTP
command terminated with exit code 28
No we will add the label access-to-service: "true"
to our pod client and try again:
$ oc label pod client-76ccdb697d-n2xqp access-to-service=true
pod/client-76ccdb697d-n2xqp labeled
$ oc exec -it client-76ccdb697d-n2xqp -- curl -v server:8080 | grep HTTP
> GET / HTTP/1.1
< HTTP/1.1 200 OK
And thats a simple demo of adding a Network Policy, applying it to a pod and granting access to it by adding a label to a pod.
Wrapping up
Controlling ingress traffic to services and pods gives you (and your developers) a great way to increase security in the cluster. By segmenting access based on labels or namespaces you can easily isolate important services from the rest of the cluster.
I hope this post has helped you. Check out my other EX280 related content on my EX280 page