Azure Kubernetes and Calico network policies

2019, Feb 26    

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.
</p>

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.</del>

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 <a title="https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Azure-Vote-Labelled.yml" href="https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Azure-Vote-Labelled.yml">https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Azure-Vote-Labelled.yml</a><br /> 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 <a href="https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Deny-All.yml">https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/Deny-All.yml</a><br /> 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 <a href="https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-1-FrontEnd.yml">https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-1-FrontEnd.yml</a><br /> 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 <a href="https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-2-BackEnd.yml">https://raw.githubusercontent.com/Gordonby/Snippets/master/AKS/NetworkPolicy-2-BackEnd.yml</a><br /> kubectl apply -f NetworkPolicy-2-BackEnd.yml

BackEndPolicy