TL;DR

Calico is a Kubernetes CNI that provides Pod networking and network policy enforcement. In SRE work, check the Calico node DaemonSet, IP pools, BGP or overlay mode, Felix logs, and policy selectors.

Dataplane Model

NodePod APod BFelixiptables/nftcalico-nodeCNI + BGPFelix programs routes and policy; overlay (VXLAN/IPIP) or BGP carries Pod traffic between nodes.

Calico node agent programs local dataplane and enforces NetworkPolicy.

Core Components

ComponentPurposeFirst check
calico-nodeRuns CNI agent, routing, Felix, and often BIRD/BGP.kubectl get ds -n kube-system calico-node
FelixPrograms host routes, iptables/nftables, policy rules.calico-node logs
IPPoolControls Pod CIDR allocation and encapsulation mode.calicoctl get ippool -o wide
TyphaScales Kubernetes API watch load in larger clusters.typha Deployment health

Health Checks

bashcalico-health.sh
kubectl get pods -n kube-system -l k8s-app=calico-node -o wide # One healthy calico-node Pod per node.
kubectl get daemonset -n kube-system calico-node
kubectl logs -n kube-system -l k8s-app=calico-node --tail=100 # Felix, CNI, BGP, or dataplane errors.
kubectl describe pod -n kube-system -l k8s-app=calico-node # Events show image, mount, or permission failures.

# If calicoctl is available and configured:
calicoctl node status # BGP peer state; all peers should be Established in BGP mode.
calicoctl get ippool -o wide # CIDRs, NAT outgoing, and VXLAN/IPIP mode.
calicoctl get workloadendpoints -A # Calico view of Pod interfaces.

Calico NetworkPolicy

yamlcalico-network-policy.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: app
spec:
  selector: app == "web-api" # Selects destination Pods protected by this policy.
  types:
    - Ingress
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: app == "frontend" # Source Pods must have this label.
      destination:
        ports:
          - 8080 # Application listen port inside the target Pod.

IPPool Example

yamlippool.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: default-ipv4-ippool
spec:
  cidr: 192.168.0.0/16 # Must not overlap node, service, VPC, VPN, or on-prem routes.
  vxlanMode: Always # Overlay mode; common when underlay routing cannot carry Pod CIDRs.
  ipipMode: Never
  natOutgoing: true # Allows Pods to reach outside networks through node SNAT.
  disabled: false

Troubleshooting Flow

bashcalico-debug.sh
# 1. Confirm the target Pod has an IP and is Ready.
kubectl get pod -n app -o wide

# 2. Confirm Calico is healthy on the source and destination nodes.
kubectl get pods -n kube-system -l k8s-app=calico-node -o wide
kubectl logs -n kube-system <calico-node-pod-on-destination-node> --tail=200

# 3. Check policies and labels.
kubectl get networkpolicy -A
kubectl get pod -n app --show-labels
calicoctl get networkpolicy -n app -o yaml # Calico-specific policies if calicoctl is available.

# 4. Test direct path from a debug Pod.
kubectl run netshoot -n app --rm -it --image=nicolaka/netshoot -- bash

Gotchas

  • !Pod CIDR overlap with VPC, VPN, or on-prem routes creates strange partial connectivity failures.
  • !Calico GlobalNetworkPolicy can affect traffic across namespaces; check it when namespace policies look clean.
  • !BGP mode needs underlay routing and firewall rules that allow peering.
  • !Selector syntax differs between Kubernetes NetworkPolicy labels and Calico selector expressions.