Network Policies in AKS
In order to have a better network segregation at the AKS cluster level, we can make use of native Kubernetes technology: Network Policies.
Network isolation can be created on both ingress and egress traffic and can filter traffic based on namespaces, pod selectors, ip addresses.
For testing purpose we can use the following Deployment manifest file. It will deploy the desired number of Replicas on the cluster level, will use nginx image as a base layer and will install some networking testing tools: netcat, tcptraceroute.
After deploying this resource, every running Pod will have a container that will listen to port 8888 (configurable value)
For our tests, we will deploy two namespaces, prod and dev.
# kubectl create namespace prod
# kubectl create namespace dev
For our example we will deploy a two replicas Deployment in both namespaces (prod and dev).
Namespace dev:
NAME READY STATUS RESTARTS AGE
dev netest-778c8b549c-gzbtz 1/1 Running 0 3m45s 10.224.0.114 aks-nodepool1–15674456-vmss000003 <none> <none>
dev netest-778c8b549c-kvwww 1/1 Running 0 3m45s 10.224.0.110 aks-nodepool1–15674456-vmss000003 <none> <none>
Namespace prod:
NAME READY STATUS RESTARTS AGE
prod netest-778c8b549c-4zxvq 1/1 Running 0 3m46s 10.224.0.125 aks-nodepool1–15674456-vmss000003 <none> <none>
prod netest-778c8b549c-qh795 1/1 Running 0 3m46s 10.224.0.119 aks-nodepool1–15674456-vmss000003 <none> <none>
We will connect on first Pod (netest-778c8b549c-gzbtz — 10.224.0.114) on dev namespace and will test network connectivity toward the first Pod in the prod namespace (netest-778c8b549c-4zxvq — 10.224.0.125)
root@netest-778c8b549c-gzbtz:/# nc -zv 10.224.0.125 8888
Connection to 10.224.0.125 8888 port [tcp/*] succeeded!
We can observe that the connection succeeded.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: netest
name: netest
spec:
replicas: 3
selector:
matchLabels:
app: netest
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: netest
spec:
containers:
— image: nginx
name: nginx
command: [“/bin/bash”]
args: [“-c”, “apt update && apt install netcat -y && apt install tcptraceroute -y && while true; do printf ‘HTTP/1.1 200 OK SALUT’ | nc -l 8888; done”]
resources: {}
status: {}
We will label the dev namespace with following value, same thing will do for prod namespace but with a different value.
k label namespace dev ns=dev
k label namespace prod ns=prod
we will deploy a different namespace called demo in order to execute networking tests for our network policies:
k create ns demo
kubectl apply -f netest.yaml -n demo
We will connect to first Pod in this new namespace and will try to test connectivity toward our Pods in dev namespace
ovidiu@cc-ad7bec5e-545f66c74f-mncvt:~/netpol$ k exec -it netest-778c8b549c-kk4zt -n demo — bash
root@netest-778c8b549c-kk4zt:/# nc 10.224.0.114 8888
Our connectivity from our demo namespace is failing because of applied policy
If we test from prod namespace, everything is working as expected:
ovidiu@cc-ad7bec5e-545f66c74f-mncvt:~/netpol$ k exec -it netest-778c8b549c-4zxvq -n prod — bash
root@netest-778c8b549c-4zxvq:/# nc 10.224.0.114 8888
HTTP/1.1 200 OK SALUT
We will test now the selection based on Pod selectors (labels)
Creating and installing the following Network Policy on the prod namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: prodtest
namespace: prod
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
egress:
- {}
Creating a nginx Pod in prod namespace for testing connectivity toward other resources.
kubectl run nginx — image=nginx
kubectl exec -it nginx — bash
Testing connectivity toward the firs Pod in prod namespace:
root@nginx:/# nc -zv 10.224.0.125 8888
nc: connect to 10.224.0.125 port 8888 (tcp) failed: Connection timed out
As our traffic is coming from a Pod without label app: frontend, it is denied. After we apply the correct label on our Pod, we test again connectivity inside the same namespace:
kubectl label pod nginx -n prod app=frontend
root@nginx:/# netcat -zv 10.224.0.125 8888
Connection to 10.224.0.125 8888 port [tcp/*] succeeded!
There are multiple policies that could be applied on a Kubernetes cluster.
Please find a complete documentation on the Kubernetes official documentation:
https://kubernetes.io/docs/concepts/services-networking/network-policies/