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.

Prerequisites:

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
 3metadata:
 4  name: dni-function
 5spec:
 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
17---
18apiVersion: v1
19kind: Service
20metadata:
21  name: dni-function
22spec:
23  type: ClusterIP
24  ports:
25  - name:
26    port: 80
27  selector:
28    app: dni-function
29---
30apiVersion: extensions/v1beta1
31kind: Ingress
32metadata:
33  name: dni-function
34  annotations:
35    kubernetes.io/ingress.class: addon-http-application-routing
36spec:
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 https://raw.githubusercontent.com/marrobi/kube-router/marrobi/aks-yaml/daemonset/kube-router-firewall-daemonset-aks.yaml

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
2apiVersion: networking.k8s.io/v1
3metadata:
4  name: dni-function-deny-all
5spec:
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:

1<html>
2<head><title>502 Bad Gateway</title></head>
3<body bgcolor="white">
4<center><h1>502 Bad Gateway</h1></center>
5<hr><center>nginx/1.13.12</center>
6</body>
7</html>

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
 2apiVersion: networking.k8s.io/v1
 3metadata:
 4  name: dni-function-allow-internal
 5spec:
 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