Service

On this page 7

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.

TypeReachable fromMechanismTypical use
ClusterIPInside the cluster onlyVirtual IP from the service rangeInternal APIs and databases
NodePortEvery node on a fixed portPort from 30000 to 32767 by defaultSimple external access, testing
LoadBalancerExternal load balancer addressProvisioned by cloud or bare-metal controllerPublic endpoints of a service
ExternalNameInside the clusterDNS alias to an external hostnameReferencing an outside database
Headless (clusterIP: None)Inside the clusterDNS returns Pod IPs directlyStatefulSets and client-side balancing
Kubernetes Service types and their reach

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.

ObjectResponsibilityNetwork layerRelation to the Service
PodRuns containersHas its own IPSelected as a Service backend
Deployment and ReplicaSetKeep the desired number of Pods runningNoneCreate the Pods the Service selects
ServiceStable address and load balancingLayer 4, TCP, UDP or SCTPCentral object
Ingress or GatewayHTTP routing by host and pathLayer 7Forwards requests to Services
NetworkPolicyAllow or deny trafficLayers 3 and 4Restricts who may reach the Pods
How a Service relates to other objects

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.

SettingValuesEffectTrade-off
externalTrafficPolicyCluster or LocalLocal keeps traffic on the receiving nodePreserves client IP, may balance unevenly
internalTrafficPolicyCluster or LocalLocal uses only Pods on the same nodeLower latency, fails if no local Pod
sessionAffinityNone or ClientIPSame client goes to the same PodUneven load, timeout of 3 hours by default
publishNotReadyAddressesFalse or trueIncludes Pods before they are readyNeeded for some cluster bootstrapping
Service settings that change behavior

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.