Mastering Kubernetes Pod Security with Calico CNI
Network Policies act as internal firewalls for Kubernetes, allowing you to explicitly control inbound (Ingress) and outbound (Egress) network traffic at the Pod and Namespace levels using labels.
Network Policies require a network plugin (CNI) that explicitly supports them. In our lab, we are using Calico. Command used to set up the cluster via kOps:
kops create cluster --name=cloudrayeez.xyz \
--state=s3://cloudrayeez.xyz --zones=us-east-1a \
--node-count=3 --node-size=t3.medium --control-plane-size=t3.medium \
--topology private --networking calico \
--ssh-public-key ~/.ssh/id_ed25519.pub --dns-zone=cloudrayeez.xyz --yesWe simulate a multi-tier environment deploying utility pods in distinct labeled namespaces.
- Namespaces:
prod(nsp=prod),dev(nsp=dev),qa(nsp=qa) - Pods per NS:
prod1,prod2|dev1,dev2|qa1,qa2
** Setup Namespaces & Pods:**
kubectl apply -f 1-Creating-ns-pods-labels.yml** Validate Pods & Labels (Alias for quick view):**
alias allpods='ku get po -n prod -o wide --show-labels --no-headers && ku get po -n dev -o wide --show-labels --no-headers && ku get po -n qa -o wide --show-labels --no-headers'Blocks all incoming and outgoing traffic across namespaces for strict security. Pods cannot ping each other anymore!
kubectl apply -f 2-block-all-traffic-namespace.yml💡 Verify isolation: kubectl exec -it prod1 -n prod -- ping -c 3 <pod-ip> (Will Fail)
Enables communication between pods living in the same namespace (e.g., prod1 to prod2).
kubectl apply -f 3-Allow-Traffic-single-namspace.yml💡 Verify connection: kubectl exec -it prod1 -n prod -- ping -c 3 <prod2-ip> (Will Succeed)
Permits Egress from dev namespaces directed at prod, and allows Ingress at prod exclusively from dev resources.
kubectl apply -f 4-allow-dev-to-prod-traffic.yml💡 Verify connection: kubectl exec -it dev1 -n dev -- ping -c 3 <prod-ip> (Will Succeed)
Provides granular access control. Allows prod pods to communicate with qa pods only over TCP:8888.
kubectl apply -f 5-allow-prod-to-qa-tcp-8888.ymlBy denying all Ego bounds earlier, Pods lost the capability of DNS resolution. We must explicitly permit Egress to kube-system namespace on DNS ports (53 and 9153).
kubectl apply -f 6-allowing-coredns-ingress-prod.yml💡 Verify DNS Resolution:
kubectl exec -it prod1 -n prod -- bash
nslookup kubernetes.default.svc.cluster.local <kube-dns-ip>
curl http://<kube-dns-ip>:9153/metrics| Operation | Command |
|---|---|
| Fetch all Network Policies in all namespaces | kubectl get netpol -A |
| View Netpols in specific namespace | kubectl get netpol -n dev |
| Ping from one pod to another IP | kubectl exec -it prod1 -n prod -- ping -c 3 <IP> |
| List pods with Labels explicitly | kubectl get pods -n kube-system -o wide --show-labels |
| Change Namespace context (via kubens) | kubens prod or kubens default |
Created by Mohd Rayees. Dive deep into K8s Security! 🌐