A Service in Kubernetes is an API object that exposes a group of Pods under one stable network identity: a virtual IP address, a DNS name and one or more ports. The Service selects its Pods by labels and distributes incoming connections among those that are ready, so clients never need to know which individual Pods exist at a given moment.
Pods are ephemeral. They are replaced during deployments, rescheduled after node failures and scaled up or down, and each new Pod receives a new IP address. The Service is the abstraction that hides this churn and provides service discovery and basic load balancing inside the cluster and, for some types, from outside it.
How a Kubernetes Service routes traffic
A typical Service definition contains a selector, such as app: checkout, and a list of ports. The control plane continuously finds all Pods whose labels match the selector and records the addresses of those that pass their readiness probe in EndpointSlice objects.
On every node, a networking component, traditionally kube-proxy, watches Services and EndpointSlices and programs packet rules in the kernel. When a Pod connects to the Service’s virtual IP, these rules rewrite the destination to one of the ready Pod addresses, so the virtual IP is never bound to a real network interface.
Each Service also gets a DNS record from the cluster DNS server, in the form name.namespace.svc.cluster.local. Pods in the same namespace can simply connect to the short Service name, which is the usual way microservices find each other.
The Service separates the port that clients use from the targetPort on which containers listen. A Service can therefore accept traffic on port 80 while the application inside the Pods listens on 8080, and the mapping can even refer to a named container port.
Service types
The type field determines where the Service is reachable from. Each type builds on the previous one, adding a further way in from outside the cluster.
| Type | Reachable from | Mechanism | Typical use |
|---|---|---|---|
| ClusterIP | Inside the cluster only | Virtual IP from the service range | Internal APIs and databases |
| NodePort | Every node on a fixed port | Port from 30000 to 32767 by default | Simple external access, testing |
| LoadBalancer | External load balancer address | Provisioned by cloud or bare-metal controller | Public endpoints of a service |
| ExternalName | Inside the cluster | DNS alias to an external hostname | Referencing an outside database |
| Headless (clusterIP: None) | Inside the cluster | DNS returns Pod IPs directly | StatefulSets and client-side balancing |
ClusterIP is the default and by far the most common type. A headless Service is the important special case: it allocates no virtual IP, so DNS returns the individual Pod addresses, which databases and other stateful systems need when clients must reach a specific replica.
Service compared with neighboring Kubernetes objects
Services are often confused with other objects in Kubernetes networking and workload management. Each has a distinct responsibility, and a typical web application uses all of them together.
| Object | Responsibility | Network layer | Relation to the Service |
|---|---|---|---|
| Pod | Runs containers | Has its own IP | Selected as a Service backend |
| Deployment and ReplicaSet | Keep the desired number of Pods running | None | Create the Pods the Service selects |
| Service | Stable address and load balancing | Layer 4, TCP, UDP or SCTP | Central object |
| Ingress or Gateway | HTTP routing by host and path | Layer 7 | Forwards requests to Services |
| NetworkPolicy | Allow or deny traffic | Layers 3 and 4 | Restricts who may reach the Pods |
A Deployment does not make an application reachable on its own; it only keeps Pods running. The Service provides the address, and an Ingress or Gateway adds HTTP routing, TLS termination and host-based rules on top of one or more Services.
Important settings and their effects
Beyond type and ports, a few fields change how traffic is distributed and what client information survives. They matter most for external traffic and for stateful applications.
| Setting | Values | Effect | Trade-off |
|---|---|---|---|
| externalTrafficPolicy | Cluster or Local | Local keeps traffic on the receiving node | Preserves client IP, may balance unevenly |
| internalTrafficPolicy | Cluster or Local | Local uses only Pods on the same node | Lower latency, fails if no local Pod |
| sessionAffinity | None or ClientIP | Same client goes to the same Pod | Uneven load, timeout of 3 hours by default |
| publishNotReadyAddresses | False or true | Includes Pods before they are ready | Needed for some cluster bootstrapping |
The proxy implementation also matters at scale. The iptables mode evaluates rules that grow with the number of Services, while IPVS, nftables and eBPF-based networking plugins handle thousands of Services more efficiently and offer additional balancing algorithms.
Common problems with Services
Most Service failures come from a mismatch between the Service and its Pods, not from the networking layer itself. Checking the Service’s endpoints is therefore the first diagnostic step.
- Selector labels that do not match the Pod labels leave the Service with no endpoints.
- A wrong targetPort sends traffic to a port where nothing listens.
- Failing readiness probes remove Pods from the endpoints and cause connection refusals.
- Long-lived connections, such as gRPC over HTTP/2, stay on one Pod because balancing happens per connection.
- Pinging a ClusterIP usually fails by design, because the virtual IP only handles defined ports.
The per-connection behavior deserves emphasis: a Service balances connections, not individual requests. Applications that multiplex many requests over a few persistent connections need client-side balancing, a headless Service or a service mesh to spread load evenly.
A plain-language summary
Think of a company switchboard. Callers dial one fixed number, and the switchboard connects them to whichever employee in the department is available, even though staff come and go during the day.
A Kubernetes Service is that switchboard for software. The programs behind it are replaced and moved all the time, but the number everyone dials stays the same, and calls go only to those who are ready to answer.
An example from practice
An online booking platform runs its pricing component as a Deployment with six replicas in a namespace called booking. Other components need to call it, but the Pod addresses change with every release and every scaling event.
The team creates a ClusterIP Service named pricing with the selector app: pricing, port 80 and targetPort 8080. Other components simply address the hostname pricing, and the Service distributes connections across the six Pods. During a rolling update, new Pods join the endpoints only after their readiness probe passes, and old Pods leave before they stop.
Releases now complete with no failed pricing calls. Later, when an HTTP/2 client keeps sending all requests to one Pod, the team identifies the per-connection balancing as the cause and adds periodic connection recycling in the client, which evens out the load across replicas.