By default, pods accept traffic from any source. A network policy helps to specify how a group of pods can communicate with each other and other network endpoints. NetworkPolicy uses labels to select pods and define rules to specify what traffic is allowed to the selected pods Once there is a NetworkPolicy applied on a particular pod, that pod will reject connections that are not allowed the NetworkPolicy. The pods that are not selected by any NetworkPolicy will continue to accept all traffic.

To know more about NetworkPolicy in detail, visit the official page of Kubernetes here.

In this article, we will see the usage of Ingress and Egress NetworkPolicy where ingress is incoming traffic to the pod, and egress is outgoing traffic from the pod.

Pre-requisites

  1. Kubernetes Cluster with at least 1 worker node.

    If you want to learn to create a Kubernetes Cluster, click here. This guide will help you create a Kubernetes cluster with 1 Master and 2 Nodes on AWS Ubuntu 18.04 EC2 Instances. 

What will we do?

  1. Create Network Policies

Create Network Policies

Ingress Network Policy

Create a hello-web pod with a label “app-destination-pod” and service on which we will allow incoming traffic on port 8080.

kubectl run hello-web --labels app=destination-pod --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --
kubectl get pod | grep hello-web


kubectl get service | grep hello-web

Network Policy in Kubernetes linux

Create an ingress definition file using the following content which allows traffic on the “hello-web” pod with label “app=destination-pod” on port 8080 from the pod matching the label “app=source-pod”.

vim ingress.yml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: destination-pod-allow-from-source-pod
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: destination-pod
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: source-pod

Network Policy in Kubernetes linux

Before we create an ingress policy create a pod with label “app=unknown” not matching the rule of the policy.

kubectl run -l app=unknown --image=alpine --restart=Never --rm -i -t test-1

Now when we try to access our “hello-web” pod on port 8080 from this pod, the pod will be accessible.

wget -qO- --timeout=2 http://hello-web:8080

Network Policy in Kubernetes linux

Now create a policy that allows connection on the pod with label “app=destination-pod” from the pod with label “app=source-pod” and get details of it.

kubectl apply -f ingress.yml
kubectl get networkpolicy destination-pod-allow-from-source-pod

Network Policy in Kubernetes linux

Now, again create a pod with a label not matching the rule defined in the policy.

kubectl run -l app=unknown --image=alpine --restart=Never --rm -i -t test-1

If we again try to access the “hello-web” pod from this pod, the “hello-web” pod will not be reachable.

wget -qO- --timeout=2 http://hello-web:8080

Network Policy in Kubernetes linux

This time, let’s create a pod matching the network policy rule i.e. pod with label “app=source-app” 

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-1

Now, if we try to access the “hello-web” pod  from the pod with label “app=source-pod”, the “hello-web” can be accessed.

wget -qO- --timeout=2 http://hello-web:8080

Network Policy in Kubernetes linux

In the above screenshot, you can see that the “hello-web” pod was accessible from the pod with label “app=source-pod”. This means that we restricted connections on our “hello-web” and only pods with label “app=source-pod”  can connect to it.

Egress Network Policy

Create a new file for Egress Network Policy with the following content.

vim egress.yml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: source-pod-allow-to-destination-pod
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: source-pod
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: destination-pod
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP

Network Policy in Kubernetes linux

The above policy will allow outgoing connections from the pod with label “app=source-pod” to the pod with label “app=destination-pod” and also on port 53 for DNS resolution.

Before we apply Egress Policy in the cluster, create a pod “hello-web-2” and service which does not match our policy.

kubectl run hello-web-2 --labels app=hello-2 --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose
kubectl get pod | grep hello-web-2
kubectl get service | grep hello-web-2

Network Policy in Kubernetes linux

Now create a pod with label “app=source-pod”.Advertisement

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-2

Before we apply the Egress policy, both the apps “hello-web” and “hello-web-2” can be accessed from the pod with label “app=source-pod”

wget -qO- --timeout=2 http://hello-web:8080
wget -qO- --timeout=2 http://hello-web-2:8080

Network Policy in Kubernetes linux

Now, create a Network policy with egress rule.

kubectl create -f egress.yml
kubectl get networkpolicy | grep source-pod-allow-to-destination-pod

Network Policy in Kubernetes linux

Let’s create a pod with label “app=source-pod” and try to access both the pod “app=source-pod”

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-3

wget -qO- –timeout=2 http://hello-web:8080

wget -qO- --timeout=2 http://hello-web-2:8080

Network Policy in Kubernetes linux

In the above screenshot, you can observe that this time the pod “hello-web-2” was not reachable as it does not match the egress policy which allows connection from a pod with label “app=source-pod” to the pod with label “app=destination-pod”.

Conclusion

In this article, we saw the steps to create an ingress and egress network policy. We also saw how the incoming and outgoing connection can be restricted using ingress and egress respectively and to understand this better we saw its implementation using a simple web-app.