← all cheatsheets
K8s Networking

K8s Networking

CNI · Services · Ingress

1. The Kubernetes Network Model2. CNI Plugins Compared3. Service Types4. Ingress & Gateway API5. DNS Inside the Cluster6. NetworkPolicy = Microsegmentation7. Troubleshooting Toolkit

1. The Kubernetes Network Model

  • Every Pod gets its own IP — no NAT between pods
  • All pods can reach all pods across nodes (flat network)
  • Agents on a node (kubelet) can reach all pods on that node
  • Implementation is delegated to a CNI plugin

Mental model

Think of the cluster as one big flat L3 network where every pod is a host. Everything else (Services, Ingress, NetworkPolicy) is built on top.

2. CNI Plugins Compared

CNIDataplaneNotable
CalicoL3 / eBPF optionBGP to physical network, rich NetworkPolicy
CiliumeBPFL7 policy, Hubble observability, kube-proxy replacement
FlannelVXLAN overlaySimple, no NetworkPolicy by itself
AWS VPC CNINative VPC IPsPods get real VPC IPs — subnet sizing matters
Azure CNINative VNet IPsSame idea in AKS

For network engineers

Calico speaks BGP — you can peer top-of-rack switches with cluster nodes and route pod CIDRs natively. Familiar territory.

3. Service Types

TypeWhat it doesUse
ClusterIPVirtual IP reachable only inside the clusterDefault — service-to-service
NodePortOpens a port (30000-32767) on every nodeQuick external access, labs
LoadBalancerProvisions an external LB (cloud or MetalLB)Production external services
ExternalNameDNS CNAME to an external serviceAliasing external dependencies
HeadlessNo VIP; DNS returns pod IPs directlyStatefulSets, databases
Service + how kube-proxy implements it
kubectl get svc my-api
# kube-proxy programs iptables/IPVS (or Cilium eBPF) rules:
# ClusterIP 10.96.4.7:80 -> pod endpoints 10.244.1.5:8080, 10.244.2.9:8080

4. Ingress & Gateway API

  • Ingress = L7 (HTTP) routing: host/path rules to Services
  • Needs an ingress controller (NGINX, Traefik, HAProxy, cloud-native)
  • TLS termination happens at the controller
  • Gateway API is the successor — role-separated, protocol-aware, more expressive
Minimal Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80

5. DNS Inside the Cluster

NameResolves to
my-svc.my-ns.svc.cluster.localService ClusterIP
my-svc.my-nsSame (short form from another namespace)
my-svcSame (from the same namespace)
pod-ip.my-ns.pod.cluster.localIndividual pod

CoreDNS runs as a Deployment; every pod's /etc/resolv.conf points at its Service VIP. Most "app can't reach database" tickets are DNS or NetworkPolicy.

6. NetworkPolicy = Microsegmentation

Allow only frontend -> backend on 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-allow-frontend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - port: 8080
  • Default = all traffic allowed; policies are additive allow-lists
  • An empty ingress policy on a pod = deny all inbound
  • Enforced by the CNI — Flannel alone ignores them
  • Think of it as distributed stateful firewall rules per label

7. Troubleshooting Toolkit

CommandPurpose
kubectl get pods -o widePod IPs and nodes
kubectl get endpoints my-svcDoes the Service actually have backends?
kubectl exec -it pod -- nslookup my-svcDNS resolution from inside
kubectl exec -it pod -- curl -v ip:portDirect pod-to-pod reachability
kubectl logs -n kube-system -l k8s-app=kube-dnsCoreDNS logs
kubectl describe networkpolicyWhat policy is blocking you

Debug order

Endpoints exist? → DNS resolves? → direct pod IP reachable? → NetworkPolicy? → CNI/node routing. Bottom of that list is rarely the problem.