Skip to content

Calico Operator Add-on

Project Calico is an open source networking and network security solution for containers, virtual machines, and native host-based workloads. To secure workloads in Kubernetes, Calico utilizes Network Policies. The Calico Operator add-on adds support for Calico to an EKS cluster by deploying Tigera Operator.

By default, the native VPC-CNI plugin for Kubernetes on EKS does not support Kubernetes Network Policies. Installing Calico (or alternate CNI provider) will enable customers to define and apply standard Kubernetes Network Policies to their EKS cluster.

Calico add-on supports standard helm configuration options.

Usage

import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';

const app = new cdk.App();

const addOn = new blueprints.addons.CalicoOperatorAddOn();

const blueprint = blueprints.EksBlueprint.builder()
  .version("auto")
  .addOns(addOn)
  .build(app, 'my-stack-name');

Upgrading from Calico Add-on

To upgrade from Calico add-on the following two step process has been validated to work:

  1. Remove CalicoAddOn from the blueprint and deploy (via cdk deploy or via pipeline support).
  2. Add CalicoOperatorAddOn to the blueprint and deploy again.

Applying Network Policies

In the Getting Started guide, we bootstrapped an EKS cluster with the workloads contained in the eks-blueprints-workloads repository. Below, we will demonstrate how we can apply network policies to govern traffic between the workloads once Calico is installed.

To start, we can verify that there are no network policies in place in your EKS cluster.

kubectl get networkpolicy -A

This means that all resources within the cluster should be able to make ingress and egress connections with other resources within and outside the cluster. You can verify, for example, that you are able to ping ateam-burnham pod from a team-riker pod. To do so, first retrieve the podIP from the team-burnham namespace.

BURNHAM_POD=$(kubectl get pod -n team-burnham -o jsonpath='{.items[0].metadata.name}') 
BURNHAM_POD_IP=$(kubectl get pod -n team-burnham $BURNHAM_POD -o jsonpath='{.status.podIP}')

Now you can start a shell from the pod in the team-riker namespace and ping the pod from team-burnham namespace:

RIKER_POD=$(kubectl -n team-riker get pod -o jsonpath='{.items[0].metadata.name}')
kubectl exec -ti -n team-riker $RIKER_POD -- sh

Note: since this opens a shell inside the pod, it will not have the environment variables saved above. You should retrieve the actual podIP from the environment variable BURNHAM_POD_IP.

With those actual values, curl the IP and port 80 of the pod from team-burnham:

# curl -s <Team Burnham Pod IP>:80>/dev/null && echo Success. || echo Fail. 

You should see Success.

Applying Kubernetes Network Policy to block traffic

Let's apply the following Network Policy:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny
spec:
  podSelector:
    matchLabels: {}

Save it as deny-all.yaml. Run the following commands to apply the policy to both team-riker and team-burnham namespaces:

kubectl -n team-riker apply -f deny-all.yaml 
kubectl -n team-burnham apply -f deny-all.yaml

This will prevent access to all resources within both namespaces. Try curl commands from above to verify that it fails.

Applying additional policy to re-open pod to pod communications

You can apply a new Kubernetes Network Policy on top of the previous to “poke holes” for egress and ingress needs.

For example, if you want to be able to curl from the team-riker pod to the team-burnham pod, the following Kubernetes NetworkPolicy should be applied.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  namespace: team-burnham
  name: allow-riker-to-burnham
spec:
  podSelector:
    matchLabels:
      app: guestbook-ui
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: guestbook-ui
          namespaceSelector:
            matchLabels:
              name: team-riker
      ports:
        - protocol: TCP
          port: 80
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: guestbook-ui
          namespaceSelector:
            matchLabels:
              name: team-riker
      ports:
        - protocol: TCP
          port: 80

Save as allow-burnham-riker.yaml and apply the new NetworkPolicy:

kubectl apply -f allow-burnham-riker.yaml     

Once the policy is applied, once again try the curl command from above. You should now see Success. once again.

Securing your environment with Kubernetes Network Policies

Calico also allows Custom Resource Definitions (CRD) which provides the ability to add features not in the standard Kubernetes Network Policies, such as:

  • Explicit Deny rules
  • Layer 7 rule support (i.e. Http Request types)
  • Endpoint support other than standard pods: OpenShift, VMs, interfaces, etc.

In order to use CRDs (in particular defined within the projectcalico.org/v3 Calico API), you must install the Calico CLI (calicoctl). You can find more information about Calico Network Policy and using calicoctl here.