Calico is an open-source CNI plugin that provides fine-grained network policy enforcement for Kubernetes clusters. It implements the full Kubernetes NetworkPolicy API and extends it with Calico-specific GlobalNetworkPolicy, supporting policy ordering, deny rules, and service-account-based selectors.
kubectl and calicoctl CLI tools# Install the Tigera operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
# Install Calico custom resources
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
# Verify installation
kubectl get pods -n calico-system
watch kubectl get pods -n calico-system
# Install calicoctl
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calicoctl.yaml
# Check Calico pods
kubectl get pods -n calico-system
# Check Calico node status
kubectl exec -n calico-system calicoctl -- calicoctl node status
# Check IP pools
kubectl exec -n calico-system calicoctl -- calicoctl get ippool -o wide
# deny-all-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
# deny-all-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
# allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
# allow-dns-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# allow-same-namespace.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
# global-deny-external.yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-external-ingress
spec:
order: 100
selector: "projectcalico.org/namespace != 'ingress-nginx'"
types:
- Ingress
ingress:
- action: Deny
source:
nets:
- 0.0.0.0/0
destination: {}
# calico-deny-policy.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: deny-database-from-frontend
namespace: production
spec:
order: 10
selector: app == 'database'
types:
- Ingress
ingress:
- action: Deny
source:
selector: app == 'frontend'
- action: Allow
source:
selector: app == 'backend'
destination:
ports:
- 5432
# sa-based-policy.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-by-service-account
namespace: production
spec:
selector: app == 'api'
ingress:
- action: Allow
source:
serviceAccounts:
names:
- frontend-sa
- monitoring-sa
egress:
- action: Allow
destination:
serviceAccounts:
names:
- database-sa
# host-endpoint-policy.yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: restrict-host-ssh
spec:
order: 10
selector: "has(kubernetes.io/hostname)"
applyOnForward: false
types:
- Ingress
ingress:
- action: Allow
protocol: TCP
source:
nets:
- 10.0.0.0/8
destination:
ports:
- 22
- action: Deny
protocol: TCP
destination:
ports:
- 22
# security-tier.yaml
apiVersion: projectcalico.org/v3
kind: Tier
metadata:
name: security
spec:
order: 100
---
# platform-tier.yaml
apiVersion: projectcalico.org/v3
kind: Tier
metadata:
name: platform
spec:
order: 200
# List all network policies
kubectl get networkpolicy --all-namespaces
# List Calico-specific policies
kubectl exec -n calico-system calicoctl -- calicoctl get networkpolicy --all-namespaces -o wide
kubectl exec -n calico-system calicoctl -- calicoctl get globalnetworkpolicy -o wide
# Check policy evaluation for a specific endpoint
kubectl exec -n calico-system calicoctl -- calicoctl get workloadendpoint -n production -o yaml
# View Calico logs
kubectl logs -n calico-system -l k8s-app=calico-node --tail=100
# Test connectivity
kubectl exec -n production frontend-pod -- wget -qO- --timeout=2 http://backend-svc:8080/health
order field) to control evaluation precedence