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

    1. Create the namespace and NGINX service
    2. Configure default deny
    3. Allow egress traffic from busybox
    4. Allow ingress traffic to NGINX
    5. 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.

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

    1. Waiting for pod advanced-policy-demo/access-472357175-y0m47 to be running, status is Pending, pod ready: false
    2. If you don't see a command prompt, try pressing enter.
    3. / #

    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.

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

      1. calicoctl create -f - <<EOF
      2. apiVersion: projectcalico.org/v3
      3. kind: GlobalNetworkPolicy
      4. metadata:
      5. name: default-deny
      6. spec:
      7. selector: projectcalico.org/namespace not in {'kube-system', 'calico-system', 'calico-apiserver'}
      8. types:
      9. - Egress
      10. 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:

      1. wget: bad address 'nginx'

      Next, try to access google.com.

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

      It will return:

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

      1. calicoctl create -f - <<EOF
      2. apiVersion: projectcalico.org/v3
      3. kind: NetworkPolicy
      4. metadata:
      5. name: allow-busybox-egress
      6. namespace: advanced-policy-demo
      7. spec:
      8. selector: run == 'access'
      9. types:
      10. egress:
      11. - action: Allow
      12. 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.

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

      1. calicoctl create -f - <<EOF
      2. apiVersion: projectcalico.org/v3
      3. kind: NetworkPolicy
      4. metadata:
      5. name: allow-nginx-ingress
      6. namespace: advanced-policy-demo
      7. spec:
      8. selector: app == 'nginx'
      9. types:
      10. - Ingress
      11. ingress:
      12. - action: Allow
      13. source:
      14. selector: run == 'access'
      15. EOF

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

      1. wget -q --timeout=5 nginx -O -

      It will return the HTML of the nginx welcome page.

      1. <!DOCTYPE html>
      2. <html>
      3. <head>

      Next, try to retrieve the home page of google.com.

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