Network Policies with Calico in AKS

Calico network plugin is finally supported within Azure Kubernetes Services (AKS).

There is a very good tutorial on the online documentation, so we won’t give a walkthrough here.

Instead we will highlight a couple of points about Network Policies in general and in AKS.

Online references

On top of the aforementioned AKS tutorial, we recommend reading Kubernetes online documentation to become more familiar with the concepts:

There is a good recipes repo authored by Ahmet Alp Balkan. Ahmet also reference a great Kubecon video he did. Unfortunately, most of his repo and that video are more than 12 months old which is an eternity in Kubernetes time. For instance, one of the limitations he mentions, i.e. we can’t discriminate traffic both coming from a namespace and a pod-selector aren’t true anymore. That is actually done in the AKS tutorial.

AKS enabling

At the time of this writing (mid February 2019), Calico is enabled at cluster creation time only.

It is important to specify a recent Kubernetes version (e.g. 1.12.*). By default, at the time of this writing, the Azure CLI defaults to 1.9.* which supported network policies, but more recent versions have support for more complex policies. For instance, the online AKS tutorial doesn’t work in 1.9.*.

Network Policies can be... hard to figure out

Some design characteristics make Network Policies a little hard to predict at time.

Let’s look at some of them.

Network Policies need a network plugin

We can deploy as many network policies at a cluster as we want, if there are no plugin enabled, they won’t have any effect.

That is a little confusing, but in line with Ingress / Ingress Controller behaviours.

Allow all / Deny all by default

Network Policies have some interesting defaults.

Until a pod is selected by a Network Policy, all traffic in / out is allowed.

When a pod is selected, then all traffic in is denied until explicitly allowed by a policy.

Then Network Policies are scoped by namespace, i.e. we apply policies one namespace at a time.

This flip of default behaviour often cause confusion when reading a collection of policies and trying to figure out what effect they could have.

Namespace label

If we want to discriminate on namespaces, e.g. pods in namespace A can’t talk to pods in namespace B, we need selectors on namespaces’ labels.

Namespaces, as any other Kubernetes resources, can have labels. Typically, namespaces aren’t labelled though.

Network Policies or authentication?

What is the control plane? The network or the identity?

The legacy enterprise model favours the network. The cloud typically favours identity but allows the network more and more.

Instead of seeing those two as opposing sides, we can see them as different layers of defense.

There are many cases where the network won’t be enough. For instance, if a pod is talking to an Azure SQL DB, we can’t simply use networking to protect DB access. Since Azure SQL us outside AKS Cluster, we can’t use Network Policies. We can use Service Endpoint with Azure SQL to only allow AKS to access the DB. This reduces the attack surface drastically. We can then use Pod Identity to then discriminate which pod can have access to the database.

But identity can complement (and often replace) network even within an AKS cluster. Identity can be a fail safe if a Network Policy wasn’t applied or if a flaw in the policy allowed traffic that shouldn’t be allowed.


We quickly look at Network Policies with Calico in AKS.

We suggest caution as Network Policies aren’t trivial to understand / predict.

They do offer a good access control layer.

We recommend supplementing that access control layer with an authentication / authorization layer leveraging Pod Identity.

Leave a comment