Skip to main content

Calico Cloud for Kubernetes demo

This guide is a variation of the simple policy demo intended to introduce the extra features of Calico Cloud to people already familiar with Project Calico for Kubernetes.

It requires a Kubernetes cluster configured with Calico networking and Calico Cloud, and expects that you have kubectl configured to interact with the cluster.

This guide assumes that you have installed all the Calico Cloud components from the guides above and that your cluster consists of the following nodes:

  • k8s-node1
  • k8s-node2
  • k8s-master

Where you see references to these in the text below, substitute for your actual node names. You can find what nodes are on your cluster with kubectl get nodes

Configure Namespaces​

This guide will deploy pods in a Kubernetes namespace. Let's create the Namespace object for this guide.

kubectl create ns policy-demo

Create demo pods​

We'll use Kubernetes Deployment objects to easily create pods in the namespace.

  1. Create some nginx pods in the policy-demo namespace.

    kubectl create deployment --namespace=policy-demo nginx --image=nginx
  2. Expose them through a service.

    kubectl expose --namespace=policy-demo deployment nginx --port=80
  3. Ensure the nginx service is accessible.

    kubectl run --namespace=policy-demo access --rm -ti --image busybox /bin/sh

    This should open up a shell session inside the access pod, as shown below.

    Waiting for pod 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.

    / #
  4. From inside the access pod, attempt to reach the nginx service.

    wget -q nginx -O -

    You should see a response from nginx. Great! Our service is accessible. You can exit the pod now.

  5. Inspect the network policies using calicoq. The host command displays information about the policies for endpoints on a given host.

    note

    calicoq complements calicoctl by inspecting the dynamic aspects of Calico Cloud Policy: in particular displaying the endpoints actually affected by policies, and the policies that actually apply to endpoints.

    DATASTORE_TYPE=kubernetes calicoq host k8s-node1

    You should see the following output.

    Policies and profiles for each endpoint on host "k8s-node1":

    Workload endpoint k8s/tigera-prometheus.alertmanager-calico-node-alertmanager-0/eth0
    Policies:
    Policy "tigera-prometheus/knp.default.calico-node-alertmanager" (order 1000; selector "(projectcalico.org/orchestrator == 'k8s' && alertmanager == 'calico-node-alertmanager' && app == 'alertmanager') && projectcalico.org/namespace == 'tigera-prometheus'")
    Policy "tigera-prometheus/knp.default.calico-node-alertmanager-mesh" (order 1000; selector "(projectcalico.org/orchestrator == 'k8s' && alertmanager == 'calico-node-alertmanager' && app == 'alertmanager') && projectcalico.org/namespace == 'tigera-prometheus'")
    Policy "tigera-prometheus/knp.default.default-deny" (order 1000; selector "(projectcalico.org/orchestrator == 'k8s') && projectcalico.org/namespace == 'tigera-prometheus'")
    Profiles:
    Profile "kns.tigera-prometheus"
    Rule matches:
    Policy "tigera-prometheus/knp.default.calico-node-alertmanager-mesh" inbound rule 1 source match; selector "(projectcalico.org/namespace == 'tigera-prometheus') && (projectcalico.org/orchestrator == 'k8s' && app in { 'alertmanager' } && alertmanager in { 'calico-node-alertmanager' })"

    ...

    Workload endpoint k8s/policy-demo.nginx-8586cf59-5bxvh/eth0
    Policies:
    Profiles:
    Profile "kns.policy-demo"

    For each workload endpoint, the Policies: section lists the policies that apply to that endpoint, in the order they apply. calicoq displays both Calico Cloud Policies and Kubernetes NetworkPolicies, although this example focuses on the latter. The Rule matches: section lists the policies that match that endpoint in their rules, in other words that have rules that deny or allow that endpoint as a packet source or destination.

    Focusing on the k8s/tigera-prometheus.alertmanager-calico-node-alertmanager-0/eth0 endpoint:

    • The first two policies are defined in the monitor-calico.yaml manifest. The selectors here have been translated from the original NetworkPolicies to the Calico Cloud format (note the addition of the namespace test).

    • The third policy and the following profile are created automatically by the policy controller.

  6. Use kubectl to see the detail of any particular policy or profile. For example, for the kns.policy-demo profile, which defines default behavior for pods in the policy-demo namespace:

    kubectl get profile kns.policy-demo -o yaml

    You should see the following output.

    apiVersion: projectcalico.org/v3
    kind: Profile
    metadata:
    creationTimestamp: '2022-01-06T21:32:05Z'
    name: kns.policy-demo
    resourceVersion: 435026/
    uid: 75dd2ed4-d3a6-41ca-a106-db073bfa946a
    spec:
    egress:
    - action: Allow
    destination: {}
    source: {}
    ingress:
    - action: Allow
    destination: {}
    source: {}
    labelsToApply:
    pcns.projectcalico.org/name: policy-demo

    Alternatively, you may also use Calico Cloud Manager to inspect and view information and metrics associated with policies, endpoints, and nodes.

Enable isolation​

Let's turn on isolation in our policy-demo namespace. Calico Cloud will then prevent connections to pods in this namespace.

Running the following command creates a NetworkPolicy which implements a default deny behavior for all pods in the policy-demo namespace.

kubectl create -f - <<EOF
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny
namespace: policy-demo
spec:
podSelector:
matchLabels: {}
EOF

Test Isolation​

This will prevent all access to the nginx service. We can see the effect by trying to access the service again.

  1. Start another pod within the policy-demo namespace.

    kubectl run --namespace=policy-demo access --rm -ti --image busybox /bin/sh

    This should open up a shell session inside the access pod, as shown below.

    If you don't see a command prompt, try pressing enter.

    / #
  2. From inside the access pod, attempt to connect to the nginx service.

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

    You should see the following output.

    wget: download timed out

    The request should time out after 5 seconds. By enabling isolation on the namespace, we've prevented access to the service.

Calico Cloud Metrics​

Now would be a great time to take a look at the metrics.

In Calico Cloud Manager, head to the dashboard view. You will see graphs associated with allowed packets/bytes and denied packets/bytes. The graphs represent the rates at which packets/bytes are being allowed or denied and are time windowed.

Now if we wanted to dig in further and find out what's causing the packets to be denied, we could take a look at the Packets by Policy bar graph. Each individual bar represents a policy that has either denied or allowed a packet. Also, the policies shown by the graph, just like the rest of the dashboard graphs, are time-windowed i.e. they will reflect only the ones that were recently exercised.

note

The NetworkPolicy spec for default-deny does not come configured with any rules. This policy results in a 'default deny' because of how it is evaluated. A packet will be dropped if the policies (like default-deny in this case) affecting the endpoint takes no action. You can review the metrics associated with such behavior in the Implicit Drops block. To view it, go to the policy page and enable Implicit Drops from the Eye (next to Add New Tier button) dropdown.

Allow Access using a NetworkPolicy​

Now, let's enable access to the nginx service using a NetworkPolicy. This will allow incoming connections from our access pod, but not from anywhere else.

  1. Create a network policy access-nginx with the following contents:

    kubectl create -f - <<EOF
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
    name: access-nginx
    namespace: policy-demo
    spec:
    podSelector:
    matchLabels:
    app: nginx
    ingress:
    - from:
    - podSelector:
    matchLabels:
    run: access
    EOF
    note

    The NetworkPolicy allows traffic from pods with the label run: access to pods with the label app: nginx. These are the labels automatically added to pods started via kubectl run based on the name of the Deployment.

  2. We should now be able to access the service from the access pod.

    kubectl run --namespace=policy-demo access --rm -ti --image busybox /bin/sh

    This should open up a shell session inside the access pod, as shown below.

    If you don't see a command prompt, try pressing enter.

    / #
  3. From inside the busybox pod, attempt to access the service again.

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

    You should see an HTTP response.

  4. Return to the Dashboard page and review the Packets by Policy bar graph to confirm that access-nginx causes the packets to be accepted. Other inspection workflows/options include: filtering through the information presented in policies, endpoints and nodes pages.

  5. To set a stream of allowed packets run the following command.

    for i in `seq 1 10000`; do (wget -q --timeout=1 nginx -O - & sleep 0.01); done
  6. Coming back, however, we still cannot access the service from a pod without the label run: access:

    kubectl run --namespace=policy-demo cant-access --rm -ti --image busybox /bin/sh

    This should open up a shell session inside the cant-access pod, as shown below.

    If you don't see a command prompt, try pressing enter.

    / #
  7. From inside the cant-access pod, attempt to access the service again.

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

    After 5 seconds, you should see the following output.

    wget: download timed out
  8. You can clean up the demo by deleting the demo namespace.

    kubectl delete ns policy-demo

    This was just a simple example of the Kubernetes NetworkPolicy API and how Calico Cloud can secure your Kubernetes cluster. For more information on network policy in Kubernetes, see the Kubernetes user guide.