Kubernetes Networking
Service types and how they route to Pods, Ingress and controllers, kube-proxy and CNI, cluster DNS, and NetworkPolicy.
9 questions
JuniorTheoryVery commonWhat is a Kubernetes Service, and how does it give Pods a stable address?
What is a Kubernetes Service, and how does it give Pods a stable address?
A Service is a stable virtual IP and DNS name in front of Pods selected by labels. Pods are ephemeral and their IPs change, but the Service address stays fixed and load-balances requests across the ready Pods, so clients never hit a Pod IP directly.
Common mistakes
- ✗Thinking a Service is a Pod or a running proxy process, not a virtual IP
- ✗Believing the Service IP changes when its backing Pods are replaced
- ✗Assuming clients must connect to individual Pod IPs directly
Follow-up questions
- →How does a Service know which Pods are currently ready to receive traffic?
- →What happens to in-flight connections when a backing Pod is removed?
JuniorTheoryCommonWhat is an Ingress, and how does it differ from a Service?
What is an Ingress, and how does it differ from a Service?
An Ingress is an L7 HTTP/HTTPS router: it maps hostnames and URL paths to backend Services and terminates TLS. A Service works at L4 (TCP/UDP) and only balances to Pods. An Ingress needs an ingress controller to enforce its rules.
Common mistakes
- ✗Thinking an Ingress works without any ingress controller installed
- ✗Confusing L7 path/host routing (Ingress) with L4 load-balancing (Service)
- ✗Believing an Ingress replaces the Service rather than routing to it
Follow-up questions
- →What component actually implements the Ingress rules, and how is it installed?
- →For a non-HTTP TCP service, would you use an Ingress or a Service type?
JuniorTheoryCommonWhat is a NetworkPolicy, and what is the default behavior when no policy selects a Pod?
What is a NetworkPolicy, and what is the default behavior when no policy selects a Pod?
A NetworkPolicy is a label-based firewall for Pod traffic. It is NOT deny-by-default: a Pod no policy selects allows all traffic. Isolation begins only once a policy selects that Pod — then only the directions it explicitly permits pass, and a supporting CNI enforces it.
Common mistakes
- ✗Believing an empty namespace is deny-by-default rather than allow-all
- ✗Thinking one policy locks down the whole cluster, not only selected Pods
- ✗Assuming policies work without a CNI (Container Network Interface) plugin that enforces them
Follow-up questions
- →How do you achieve an actual default-deny posture for a namespace?
- →If two policies select the same Pod, how do their allow rules combine?
MiddleTheoryCommonWhat does kube-proxy do, and how do its iptables and IPVS modes differ?
What does kube-proxy do, and how do its iptables and IPVS modes differ?
kube-proxy runs on each node and programs the rules behind a Service's virtual IP, steering each connection to a ready backend Pod. iptables mode writes sequential rules whose cost grows with the Service count; IPVS mode uses in-kernel hash tables that scale far further.
Common mistakes
- ✗Thinking kube-proxy is an L7/HTTP proxy rather than L4 Service plumbing
- ✗Believing kube-proxy resolves DNS instead of CoreDNS
- ✗Assuming iptables and IPVS modes scale identically with Service count
Follow-up questions
- →Why does a cluster with thousands of Services often switch to IPVS mode?
- →Which component assigns Pod IPs, if kube-proxy only handles Service VIPs?
MiddleDebuggingCommonClients get timeouts calling the web Service though the Pods are up — diagnose it.
Clients get timeouts calling the web Service though the Pods are up — diagnose it.
The endpoints list is empty, so the Service has no backends and requests time out. The Pods are Ready, but their label app=webapp does not match the Service selector app=web, so none is enrolled. Fix it by aligning the selector or relabelling the Pods.
Common mistakes
- ✗Blaming kube-proxy or DNS instead of reading the empty Endpoints
- ✗Thinking a Service matches Pods by name prefix, not by label selector
- ✗Assuming more replicas or waiting will populate an empty Endpoints list
Follow-up questions
- →How would an empty Endpoints list look instead if readiness were failing?
- →Which command quickly confirms whether a selector matches any Pods?
MiddleTheoryCommonCompare the ClusterIP, NodePort, and LoadBalancer Service types.
Compare the ClusterIP, NodePort, and LoadBalancer Service types.
ClusterIP, the default, is an internal-only virtual IP inside the cluster. NodePort also opens the Service on a fixed port on every node, so external clients reach it via any node IP. LoadBalancer builds on that, asking the cloud for an external load balancer.
Common mistakes
- ✗Thinking ClusterIP is externally reachable by default
- ✗Missing that LoadBalancer is layered on top of NodePort
- ✗Believing NodePort opens a port on only one node, not all
Follow-up questions
- →What is a headless Service (
clusterIP: None) and when do StatefulSets use it? - →Why prefer one Ingress over many
LoadBalancerServices?
MiddleTheoryOccasionalHow does in-cluster DNS resolve a name like svc.namespace.svc.cluster.local?
How does in-cluster DNS resolve a name like svc.namespace.svc.cluster.local?
CoreDNS serves the internal cluster.local zone. Each Service has an A record at service.namespace.svc.cluster.local resolving to its ClusterIP. A Pod's search domain covers its namespace, so a bare svc resolves locally and svc.ns reaches another namespace.
Common mistakes
- ✗Thinking DNS returns Pod IPs rather than the Service ClusterIP
- ✗Believing resolution uses /etc/hosts instead of CoreDNS
- ✗Missing the namespace segment, so cross-namespace names fail
Follow-up questions
- →Why does a bare Service name resolve without typing the full FQDN?
- →How would you resolve a headless Service, which has no ClusterIP?
MiddleCodeOccasionalComplete a NetworkPolicy so api Pods accept traffic only from role=frontend.
Complete a NetworkPolicy so api Pods accept traffic only from role=frontend.
Set policyTypes to Ingress and one ingress rule whose from is a podSelector on role=frontend, limited to TCP port 8080. Selecting the api Pods flips them to deny-by-default for ingress, so only that rule passes. It works only if the CNI enforces NetworkPolicy.
Common mistakes
- ✗Restricting the sender with egress instead of selecting the api Pods
- ✗Forgetting the ports block, which leaves all ports open
- ✗Assuming the policy works without a CNI (Container Network Interface) that enforces NetworkPolicy
Follow-up questions
- →How would you also allow ingress from a monitoring namespace by label?
- →What happens to existing connections the moment this policy is applied?
SeniorDesignOccasionalYou run a three-tier app in one namespace: a public frontend, an internal backend API, and a postgres database. Security wants a default-deny posture — no Pod receives traffic unless explicitly allowed. The permitted paths are exactly: external users reach frontend over HTTPS; frontend reaches backend on port 8080; backend reaches postgres on 5432. Nothing else may connect — frontend must not reach the database directly, and no external client may reach backend or postgres. Describe the design: how you expose frontend for outside users, and how you use Kubernetes NetworkPolicy resources to enforce exactly these east-west paths while keeping the default-deny guarantee.
You run a three-tier app in one namespace: a public frontend, an internal backend API, and a postgres database. Security wants a default-deny posture — no Pod receives traffic unless explicitly allowed. The permitted paths are exactly: external users reach frontend over HTTPS; frontend reaches backend on port 8080; backend reaches postgres on 5432. Nothing else may connect — frontend must not reach the database directly, and no external client may reach backend or postgres. Describe the design: how you expose frontend for outside users, and how you use Kubernetes NetworkPolicy resources to enforce exactly these east-west paths while keeping the default-deny guarantee.
Apply a default-deny NetworkPolicy over all Pods, so nothing connects until allowed. Then add three ingress allows: backend from frontend on 8080, postgres from backend on 5432, and outside traffic to frontend. Keep backend/postgres ClusterIP-only; expose only frontend. No rule lets frontend reach the DB, so that east-west path stays denied.
Common mistakes
- ✗Assuming Kubernetes is default-deny without an explicit deny-all policy
- ✗Exposing backend or postgres externally instead of ClusterIP-only
- ✗Enforcing tier isolation with an Ingress instead of NetworkPolicies
Follow-up questions
- →How would you extend this to a second namespace that also needs the DB?
- →How do you verify the frontend-to-DB path is actually blocked?