Kubernetes
Intermediate 15 min read Kubernetes

Services & Service Networking

Stability atop ephemeral pods

Pods are ephemeral, so Services supply stable DNS + virtual IP: ClusterIP (indirect), NodePort (host-port), LoadBalancer (cloud LB), ExternalName. kube-proxy (iptables/ipvs/eBPF) wires ClusterIP; CoreDNS resolves names.

ServiceClusterIPNodePortLoadBalancerkube-proxyCoreDNSheadless
Before we start

What you will learn

  • Explain Service types and when each applies
  • Trace kube-proxy + CoreDNS resolution to endpoints
  • Use selectors and ports correctly for multi-port services
In 60 seconds

A Service = a stable label selector + a virtual IP (ClusterIP) + port mapping. kube-proxy programs the datapath (iptables/ipvs/eBPF) so ClusterIP:port → one of the Pod endpoints. CoreDNS names the service: my-svc.ns.svc.cluster.local.

Introduction

What is this?

Service spec: selector → endpoints population (Endpoints object); ports (name, port, targetPort); type: ClusterIP, NodePort, LoadBalancer, ExternalName, Headless (clusterIP: None → DNS A records per pod). kube-proxy backends: iptables (default, SNAT), ipvs (scale, faster), eBPF/Cilium (offload). DNS: CoreDNS → service/cluster.local names; SRV for named ports. Service topologies/trafficPolicy, sessionAffinity for sticky, internalTrafficPolicy, plus multi-port and port names.

Motivation

Why do you need it?

  • A direct pod IP breaks on every reschedule — services carry the load when pods shuffle.
  • DNS-based discovery lets services find each other by name, not IP archaeology.
  • NodePort/LoadBalancer expose your workload without editing each pod.
  • Headless services unlock StatefulSet member discovery (DB clustering) cleanly.
Think about it

Mental model

Imagine

A PBX switchboard: dial a fixed number, get whichever employee (whoever is free)

Think of

Service → endpoints

Customers dial the department number (ClusterIP:port); the switchboard (kube-proxy) connects to an available agent (ready Pod); the agent list (Endpoints) updates as staff change.

Mechanics

How it works

  • You create Service → selector matches Pod labels → Endpoints controller fills pod IP:port set.
  • Service' virtual IP lands in iptables/ipvs rules on every node.
  • Traffic to clusterIP:port matches a rule → DNAT to a selected endpoint; conntrack returns.
  • CoreDNS answers svc.ns.svc.cluster.local → ClusterIP (or per-pod A/AAAA for headless).
  • LoadBalancer type asks the cloud provider to front NodePorts with an LB.

Service resolution path.

Client
CoreDNS
kube-proxy
Endpoints
Pod
Hands-on

Examples

Multi-port service with named ports

Multi-port service with named ports
apiVersion: v1
kind: Service
metadata: { name: api, namespace: prod }
spec:
selector: { app: api }
ports:
- name: http
port: 80
targetPort: 8080
- name: metrics
port: 9090
targetPort: 9090
type: ClusterIP

Two named ports expose HTTP and scraping; DNS name api.prod.svc.cluster.local routes to ready pods.

Real world

In production

  • Front Service → Deployment (ClusterIP) fronted by an Ingress.
  • DB read replicas behind a headless Service for client-side discovery.
  • Standalone metrics Service scraped by Prometheus; NodePort only in legacy-onprem.
Guidelines

Best practices

  • Name ports; never rely on positional port numbers.
  • Let readiness decide membership — the Endpoints list is only as good as your probes.
  • Prefer ClusterIP + Ingress/LB over NodePort spread.
  • For StatefulSets, headless Services + stable DNS unlock member-to-member clustering.
  • Set serviceAccount and network policies to bound cross-namespace reach.
Watch out

Common mistakes

  • Selector mismatches → empty Endpoints → the service has no backends
  • targetPort pointing at the container's listen-but-not-route port.
  • kube-proxy iptables vs ipvs perf assumptions — measure big clusters.
  • Using NodePort for internal traffic and leaking host ports.
When things break

Debugging tips

  • kubectl get endpoints <svc> first — if empty, the selector is the bug.
  • Resolve the name: kubectl run --rm -it curl -- /bin/sh; nslookup api.prod.svc.cluster.local.
  • From a pod, curl <svc>.<ns>.svc.cluster.local — not the raw ClusterIP you memorized.
  • Check multiport: a curl to port 80 mapping wrong targetPort is a top reset offender.
Interviews

Interview checkpoint

Practice

Hands-on lab

Wire a Service and Resolve It by DNS
30 min · beginner
In progress
Objectives
  • Expose a Deployment via a Service
  • Verify endpoint population and DNS resolution
  • Hit the service across pods

Wire a Service and Resolve It by DNS

30 min · beginner

0/4 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Service with no matching labels →

2

Headless Service (clusterIP: None) primarily enables:

Go deeper

Official documentation