At last: Network Policies in AKS with kube-router

For ages I’ve been waiting for a way to enforce netwok policies on AKS, so last weekend while I was googling around, I found this hidden gem posted by Marcus Robinson : Enforcing Network Policies using kube-router on AKS and had to test the proposed solution.


1. Create a service exposed throuh your AKS DNS Zone

Let’s start by deploying the following service to your Kubernetes cluster, by saving the following content to a file named dni-function.yaml and replacing [YOUR_DNS__ZONE_NAME] with the corresponding value of your service:

 1apiVersion: apps/v1beta1
 2kind: Deployment
 4  name: dni-function
 6  replicas: 1
 7  template:
 8    metadata:
 9      labels:
10        app: dni-function
11    spec:
12      containers:
13      - name: dni-function
14        image: cmendibl3/dni:1.0.0
15        ports:
16        - containerPort: 80
18apiVersion: v1
19kind: Service
21  name: dni-function
23  type: ClusterIP
24  ports:
25  - name:
26    port: 80
27  selector:
28    app: dni-function
30apiVersion: extensions/v1beta1
31kind: Ingress
33  name: dni-function
34  annotations:
35 addon-http-application-routing
37  rules:
38  - host: dni-function.[YOUR_DNS__ZONE_NAME]
39    http:
40      paths:
41      - backend:
42          serviceName: dni-function
43          servicePort: 80
44        path: /

Now deploy it to Kubernetes:

1kubectl apply -f ./dni-function.yaml

In a few seconds you’ll have a working Web API (Validates Spanish National Identification Numbers).

Now test the service with the following command:

1curl -k http://dni-function.[YOUR_DNS__ZONE_NAME]/api/validate?dni=88410248L

which should return true.

2. Deploy kube-router

Thanks to Marcus Robinson we can deploy kube-router to AKS:

1kubectl apply -f

3. Deny all traffic to the service

Now let’s try to deny all the traffic to the service, creating a dni-function-deny-all.yaml file with the following contents:

1kind: NetworkPolicy
4  name: dni-function-deny-all
6  podSelector:
7    matchLabels:
8      app: dni-function
9  ingress: []

Deploy the policy:

1kubectl apply -f ./dni-function-deny-all.yaml

Try calling the service again:

1curl -k http://dni-function.[YOUR_DNS__ZONE_NAME]/api/validate?dni=88410248L

This time you should get:

2<head><title>502 Bad Gateway</title></head>
3<body bgcolor="white">
4<center><h1>502 Bad Gateway</h1></center>

That’s it! Your service is no longer available!!!

4. Allow only traffic from a specific pod

Create a dni-function-allow-internal.yaml file with the following contents:

 1kind: NetworkPolicy
 4  name: dni-function-allow-internal
 6  podSelector:
 7    matchLabels:
 8      app: dni-function
 9  ingress:
10  - from:
11      - podSelector:
12          matchLabels:
13            app: internal

Deploy the policy, which restricts the traffic to pods with the label: app=internal, and check that you still can’t connect:

1kubectl apply -f ./dni-function-allow-internal.yaml
2curl -k http://dni-function.[YOUR_DNS__ZONE_NAME]/api/validate?dni=88410248L

Now let’s create a pod with the expected label and try calling the dni-function service from it:

1kubectl run internal-function-tester --rm -i -t --image=alpine --labels app=internal -- sh
2wget -qO- --timeout=2 http://dni-function/api/validate?dni=88410248L

This time you should get true as the result!!!

To learn more about Network Policies check the kubernetes-network-policy-recipes repo and feel free to download the code and files for this post here

Simple Machine Learning with .NET Core Sample
Installing Azure CLI and Ansible on Ubuntu
comments powered by Disqus