Kubernetes Network Policy

If we think of a classic three tier application deployed on the cloud, each tier of the application has controlled access to the other tiers. For example a front-end web application wouldn’t be able to communicate directly with a database. This isolation is achieved via firewalls, in AWS think Network ACL’s, Network Security Groups in Azure and so on.

With this in mind, how do we obtain a similar level of isolation within Kubernetes, when each of the tiers would reside within the same cluster?

Well, we could deploy an individual Kubernetes cluster per logical tier, but then we lose service density benefits, increase our costs, have more clusters to maintain and so on. So how else do we tackle this in Kubernetes? The answer comes in the form of NetworkPolicy.

NetworkPolicy is a Kubernetes feature, which allows intra Pod isolation. If a Pod has a network policy applied to it, any connections which do not match the policy will be rejected.

So let’s take a simple example to show how to use NetworkPolicy. In this example we have an NGINX deployment running a single Pod, with the deployment fronted by a Kubernetes Service. Calling the NGINX endpoint is a BusyBox client, which attempts to connect to the default NGINX endpoint to return it’s Index.html page.

Client calling NGINX service
NGINX deployment file

This setup works as expected, and the Index.html page is returned to the client. Now let’s apply the following NetworkPolicy.

NGINX NetworkPolicy

What this particular NetworkPolicy says is apply the policy to all Pods which have a label matching ngix-app. In our case this will be the NGINX deployment defined earlier. The policy itself then states to only allow inbound traffic from Pods which have a label of role:apiclient.

With the policy applied, when we run wget from the BusyBox container we get the following:

You can see that the wget experiences a timeout due to the policy being in place.

So essentially the relationship between Pods and NetworkPolicy at this time is as follows:

Client denied access to the service as the calling Pod’s label don’t match the Network Policy

Now we’ll run the BusyBox container again, but this time adding the role:apiclient label to the BusyBox deployment.

You can see that the client was successfully able to download the Index.html file, as the BusyBox Pod now matches the NetworkPolicy that is associated to the NGINX deployment.

Client allowed access to the service, as the calling client’s label matches that of the Network Policy

This has been a brief overview of Kubernetes NetworkPolicy, but hopefully some of you will find this of use.

Please note that NetworkPolicy might not be enabled on your Kubernetes cluster. In my case I ran this against a cluster deployed on Google Kubernetes Engine (which is awesome), and I had to enable this feature on the cluster.