Azure Kubernetes and Calico network policies

In this post i’m looking at the Network Policies in AKS which uses Calico to restrict pod network communication in a number of different ways.

Preview feature

The first point to make about Network Policies in AKS is that they’re currently in preview.  New features to AKS will always hit preview first, for a couple of months before going GA.  This is a model that most people familiar with Azure will be happy with.  The official documentation on Network Policies is here; https://docs.microsoft.com/en-us/azure/aks/use-network-policies – Where you can check the current status of the feature and read the Preview caveat in more detail.

Network Enforcement through labels

Labels on Pods drive the network policy enforcement.  Taking a simple 2 tier app, like the Azure Vote Sample app.  It has a front end pod which contains the HTML and JS, and the backend pod which serves as the Datastore.  The original yaml deployment file is here: https://raw.githubusercontent.com/Azure-Samples/azure-voting-app-redis/master/azure-vote-all-in-one-redis.yaml
I’ve added a couple of extra pod labels to this version of the deployment: https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Azure-Vote-Labelled.yml

PodLabels

Deploying the app

Lets start by deploying the app to our cluster and making sure it works.  I won’t go through cluster configuration and enablement of the Network Policies here as that’s already covered extensively in the official documentation: https://docs.microsoft.com/en-us/azure/aks/use-network-policies

curl -O https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Azure-Vote-Labelled.yml
kubectl create -f Azure-Vote-Labelled.yml

AKS-Vote-Labelled-Created

After we have a external ip allocated, lets test it works.

Azure-Vote-Works

Deny All

It’s important to first make sure we’re operating with least privilege, so lets start by denying all traffic in a network policy and then checking our app again to make sure that it’s broken.

curl -O https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Deny-All.yml
kubectl create –f Deny-All-yml

Aks-Calico-Deny-All

If you now navigate to the front-end, you’ll see that the app is now unreachable.  You can also take a look at the network policy definition with this kubectl command;

DenyAllPolicy

Allowing Front-End access

Our app has a couple of labels, and I want to specifically allow access to any pod that has the label; role: frontend
This is going to save me time for every subsequent web app I want to add.

curl -O https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-1-FrontEnd.yml
kubectl apply -f NetworkPolicy-1-FrontEnd.yml

web-allow-external

Allowing Back-End access

For this network policy, i’m going to limit it to just the specific Azure Frontend pod.

curl -O https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-2-BackEnd.yml
kubectl apply -f NetworkPolicy-2-BackEnd.yml

BackEndPolicy