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.
</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
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
After we have a external ip allocated, lets test it 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
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;
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
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