---
title: "Calico Cloud for Kubernetes demo"
description: "Tour of the additional features Calico Cloud adds to Kubernetes policy that make it suitable for production environments."
product: "Calico Cloud"
version: "v20.4.0"
section: "Network policy"
canonical_url: "https://docs.tigera.io/calico-cloud/next/network-policy/beginners/simple-policy-cnx"
---

# Calico Cloud for Kubernetes demo

This guide is a variation of the [simple policy demo](https://docs.tigera.io/calico-cloud/next/tutorials/kubernetes-tutorials/kubernetes-policy-basic.md) 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.

```text
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.

   ```shell
   kubectl create deployment --namespace=policy-demo nginx --image=nginx
   ```

2. Expose them through a service.

   ```shell
   kubectl expose --namespace=policy-demo deployment nginx --port=80
   ```

3. Ensure the nginx service is accessible.

   ```shell
   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.

   ```text
   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.

   ```shell
   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.

   > **SECONDARY:** 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.

   ```text
   DATASTORE_TYPE=kubernetes calicoq host k8s-node1
   ```

   You should see the following output.

   ```text
   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:

   ```shell
   kubectl get profile kns.policy-demo -o yaml
   ```

   You should see the following output.

   ```yaml
   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 the Calico Cloud web console 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.

```shell
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.

   ```shell
   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.

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

   / #
   ```

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

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

   You should see the following output.

   ```text
   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 the Calico Cloud web console, 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.

> **SECONDARY:** The `NetworkPolicy` spec for [`default-deny`](#enable-isolation) does not come configured with any rules. This policy results in a 'default deny' because of how it is [evaluated](https://docs.tigera.io/calico-cloud/next/reference/resources/tier.md#how-policy-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:

   ```shell
   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
   ```

   > **SECONDARY:** 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.

   ```shell
   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.

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

   / #
   ```

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

   ```text
   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.

   ```shell
   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`:

   ```shell
   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.

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

   / #
   ```

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

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

   After 5 seconds, you should see the following output.

   ```text
   wget: download timed out
   ```

8. You can clean up the demo by deleting the demo namespace.

   ```shell
   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](https://kubernetes.io/docs/concepts/services-networking/network-policies/).
