Calico policy tutorial
- A working Kubernetes cluster and access to it using kubectl and calicoctl
- Your Kubernetes nodes have connectivity to the public internet
- You are familiar with Calico NetworkPolicy
Tutorial flow
- Create the namespace and NGINX service
- Configure default deny
- Allow egress traffic from busybox
- Allow ingress traffic to NGINX
- Clean up
We’ll use a new namespace for this guide. Run the following commands to create the namespace and a plain NGINX service listening on port 80.
Open up a second shell session which has connectivity to the Kubernetes cluster and create a busybox pod to test policy access. This pod will be used throughout this tutorial to test policy access.
kubectl run --namespace=advanced-policy-demo access --rm -ti --image busybox /bin/sh
This will open up a shell session inside the busybox
pod, as shown below.
Waiting for pod advanced-policy-demo/access-472357175-y0m47 to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
/ #
Now from within the busybox “access” pod execute the following command to test access to the nginx service.
It returns the HTML of the nginx welcome page.
Still within the busybox “access” pod, issue the following command to test access to google.com.
wget -q --timeout=5 google.com -O -
It returns the HTML of the google.com home page.
2. Lock down all traffic
We will begin by using a default deny (which you can only do using Calico) that will help us adopt best practices in using a zero trust network model to secure our workloads. Note that Global Calico Network Policies are not namespaced and effect all pods that match the policy selector. In contrast, Kubernetes Network Policies are namespaced, so you would need to create a default deny policy per namespace to achieve the same effect. Note that to simplify this tutorial we exclude pods in the kube-system
,calico-system
and calico-apiserver
namespace, so we don’t have to consider the policies required to keep Kubernetes itself running smoothly when we apply our default deny.
calicoctl create -f - <<EOF
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: projectcalico.org/namespace not in {'kube-system', 'calico-system', 'calico-apiserver'}
types:
- Egress
EOF
We can see that this is the case by switching over to our “access” pod and attempting to access the nginx service.
It will return:
wget: bad address 'nginx'
Next, try to access google.com.
wget -q --timeout=5 google.com -O -
It will return:
wget: bad address 'google.com'
Let’s create a Calico Network Policy which allows egress traffic from the busybox “access” pod. For a production workload you would typically want to make this egress rule more restrictive, to only allow egress to the specific services you want the workload to talk to. But as this is just our dummy access pod we will allow all egress traffic from it so we can probe to see what traffic is allowed in this case.
calicoctl create -f - <<EOF
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-busybox-egress
namespace: advanced-policy-demo
spec:
selector: run == 'access'
types:
egress:
- action: Allow
EOF
As we’ve allowed all egress traffic, we should now be able to access google.
Try to retrieve the home page of google.com.
wget -q --timeout=5 google.com -O -
It will return the HTML of the google home page.
Run the command to verify that we cannot access the nginx service.
It will return:
Access to google is allowed because we have allowed all egress traffic from the busybox access pod, however we still cannot access the nginx service because we have not allowed ingress traffic into that service. Let’s do that now.
4. Allow ingress traffic to nginx
Let’s create a Calico Network Policy that allows ingress traffic into the nginx service from the busybox access pod.
calicoctl create -f - <<EOF
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-nginx-ingress
namespace: advanced-policy-demo
spec:
selector: app == 'nginx'
types:
- Ingress
ingress:
- action: Allow
source:
selector: run == 'access'
EOF
Now run the command to verify that we can access the nginx service.
wget -q --timeout=5 nginx -O -
It will return the HTML of the nginx welcome page.
<!DOCTYPE html>
<html>
<head>
Next, try to retrieve the home page of google.com.
wget -q --timeout=5 google.com -O -
It will return the HTML of the google home page.
5. Clean up
To clean up this tutorial session run the following commands to clean up the network policies and remove the demo namespace.