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:
- Azure Kubernetes Service (AKS) deployed with HTTP application routing enabled.
- kubectl installed
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.
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
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!!!
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
Comments