Calico Service Rules

Create the namespace and nginx service

We’ll use a new namespace for this lab.

Step1. Run the following commands to create the namespace and a plain NGINX service listening on port 80.

kubectl create ns advanced-policy-demo
kubectl create deployment --namespace=advanced-policy-demo backend --image=nginx
kubectl expose --namespace=advanced-policy-demo deployment backend --port=80

Step2. Verify access - allowed all ingress and egress

Open up a second shell session which has kubectl connectivity to the Kubernetes cluster and create a frontend pod to test policy access.

This pod will be used throughout this tutorial to test policy access.

kubectl run --rm -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11 frontend --namespace advanced-policy-demo

This will open up a shell session inside the froentend

Step3. Now from within the busybox “frontend” pod execute the following command to test access to the nginx service.

wget -q --timeout=5 -O - backend

It returns the HTML of the nginx welcome page.

Still within the busybox “frontend” 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.

Lock down all traffic

We will begin by using a default deny Global Calico Network Policy (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.

Step4. Note that to simplify this tutorial we exclude pods in the kube-system namespace, so we don’t have to consider the policies required to keep Kubernetes itself running smoothly when we apply our default deny.

https://raw.githubusercontent.com/nishanthkumarpathi/k8s-calico-istio-training/main/calico/ns-svc-rules/default-deny-global.yaml

calicoctl apply -f default-deny-global.yaml

Step5. Verify access - denied all ingress and egress

As our pods are not in the kube-system namespace, the policy we just created applies to them, and any traffic which is not explicitly allowed by a policy will be denied.

We can see that this is the case by switching over to our "frontend" pod and attempting to access the backend service.

wget -q --timeout=5 backend -O -

It will return, either a wget: bad address 'frontend' or error

Step6. Next, try to access google.com.

wget -q --timeout=5 google.com -O -

It will return, wget: bad address 'google.com' or stuck state

Allow egress traffic from frontend

Let’s create a Calico Network Policy which allows egress traffic from the busybox frontend 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.

Step7. 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.

https://raw.githubusercontent.com/nishanthkumarpathi/k8s-calico-istio-training/main/calico/ns-svc-rules/allow-egress-frontend.yaml

calicoctl apply -f allow-egress-frontend.yaml

Verify egress - traffic allowed from "frontend" pod to google but not backend

As we’ve allowed all egress traffic, we should now be able to access google.

Step8. 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.

If we try to access the backend pod, egress from the frontend pod will be allowed, but the connection will still be denied because our default deny policy is blocking ingress traffic to the backend pod.

Step9. Run the command to verify that we cannot access the nginx service.

wget -q --timeout=5 backend -O -

It will return, wget: download timed out

Access to google is allowed because we have allowed all egress traffic from the frontend pod,

However we still cannot access the nginx service because we have not allowed ingress traffic into that service.

Let’s do that now.

Allow ingress traffic to nginx

Step10. Let’s create a Calico Network Policy that allows ingress traffic into the nginx service from the busybox access pod.

https://raw.githubusercontent.com/nishanthkumarpathi/k8s-calico-istio-training/main/calico/ns-svc-rules/allow-ingress-backend.yaml

calicoctl apply -f allow-ingress-backend.yaml

Step11. Verify access - allowed ingress traffic to backend from "frontend" pod

Now run the command to verify that we can access the backend service.

wget -q --timeout=5 backend -O -

It will return the HTML of the nginx welcome page.

Step12. 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.

We have allowed our frontend pod access to the outside internet and the backend service using Calico Network Policies!

Clean up

To clean up this tutorial session run the following commands to clean up the network policies and remove the demo namespace.

calicoctl delete policy allow-frontend-egress -n advanced-policy-demo
calicoctl delete policy allow-backend-ingress -n advanced-policy-demo
calicoctl delete gnp default-deny
kubectl delete ns advanced-policy-demo

Last updated