What Is a Kubernetes Service and Why Do You Need One?

beginner|servicesdevopssreCKACKAD
TL;DR

A Kubernetes Service is an abstraction that provides a stable network endpoint for a set of Pods. Because Pod IPs are ephemeral and change on every restart, a Service gives clients a single DNS name and virtual IP that automatically routes traffic to healthy, matching Pods.

What Is a Kubernetes Service?

A Service in Kubernetes is a resource that provides a stable networking abstraction over a dynamic set of Pods. Pods are ephemeral by design: they can be created, destroyed, and rescheduled at any time, and each time a Pod restarts it receives a new IP address. A Service solves this problem by assigning a single, unchanging virtual IP address (the ClusterIP) and a DNS name to a logical group of Pods.

When a client sends traffic to a Service, Kubernetes transparently load-balances that traffic across all healthy Pods that match the Service's label selector.

The Problem Services Solve

Consider a simple web application backed by three replicas of an API server:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
        - name: api
          image: myregistry/api-server:1.4.0
          ports:
            - containerPort: 8080

Each of the three Pods gets a unique IP, for example 10.244.1.12, 10.244.2.7, and 10.244.3.19. If you hard-code any of those addresses into a frontend configuration, the moment that Pod is rescheduled the address becomes invalid.

A Service fixes this by giving the group a single, stable address.

Creating a Basic Service

apiVersion: v1
kind: Service
metadata:
  name: api-server
spec:
  selector:
    app: api-server
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP

Key fields:

| Field | Purpose | |---|---| | selector | Matches Pods with app: api-server label | | port | The port exposed by the Service itself | | targetPort | The port on the Pod containers where traffic is forwarded | | type | The kind of Service; defaults to ClusterIP |

Once applied, any Pod in the cluster can reach the API server at http://api-server.default.svc.cluster.local:80 (or simply http://api-server from within the same namespace).

How It Works Under the Hood

  1. Endpoints Controller -- The Kubernetes control plane watches for Services and Pods. When a Pod's labels match a Service's selector, the controller adds the Pod's IP to an Endpoints (or EndpointSlice) object associated with that Service.

  2. kube-proxy -- On every node, kube-proxy watches for Service and Endpoints changes and programs the node's networking rules (iptables, IPVS, or nftables depending on the mode) to redirect traffic destined for the Service's ClusterIP to one of the backend Pod IPs.

  3. DNS -- CoreDNS (the default cluster DNS) creates an A record mapping the Service name to its ClusterIP. This is how name-based discovery works.

Client Pod
   |
   |  DNS lookup: api-server -> 10.96.45.12 (ClusterIP)
   |
   v
iptables / IPVS rules on the node
   |
   |  DNAT to one of: 10.244.1.12, 10.244.2.7, 10.244.3.19
   |
   v
Backend Pod (app: api-server)

Service Types at a Glance

Kubernetes offers four Service types, each building on the previous one:

| Type | Accessibility | Use Case | |---|---|---| | ClusterIP | Internal cluster only | Default; microservice-to-microservice communication | | NodePort | External via <NodeIP>:<NodePort> | Development, simple external access | | LoadBalancer | External via cloud load balancer | Production external access on cloud providers | | ExternalName | DNS CNAME to an external address | Aliasing external services |

Verifying a Service

After creating a Service, you can inspect its details:

# List services
kubectl get svc api-server

# Check which pods are selected
kubectl get endpoints api-server

# Inspect the full specification
kubectl describe svc api-server

Example output from kubectl get endpoints:

NAME         ENDPOINTS                                          AGE
api-server   10.244.1.12:8080,10.244.2.7:8080,10.244.3.19:8080 5m

This confirms all three Pods are registered and receiving traffic.

A Common Pitfall: Selector Mismatch

One of the most frequent debugging scenarios is a Service with zero endpoints. This almost always means the label selector in the Service does not match any running Pod's labels. Always verify:

# Check that the selector matches at least one pod
kubectl get pods -l app=api-server

If this returns no results, either the Pods have different labels or they are not running in the same namespace as the Service.

Multi-Port Services

A single Service can expose multiple ports. This is useful when a Pod serves both HTTP and gRPC traffic:

apiVersion: v1
kind: Service
metadata:
  name: api-server
spec:
  selector:
    app: api-server
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
    - name: grpc
      protocol: TCP
      port: 9090
      targetPort: 9090

When defining multiple ports, the name field is required for each entry.

Summary

A Kubernetes Service is the foundational networking primitive that gives a dynamic set of Pods a stable identity. It bridges the gap between Kubernetes' ephemeral Pod lifecycle and the need for reliable, discoverable endpoints. Understanding Services is a prerequisite for working with Ingress, service meshes, and any production Kubernetes deployment.

Why Interviewers Ask This

Interviewers ask this to verify that candidates understand the fundamental networking model in Kubernetes and why direct Pod-to-Pod communication is unreliable in production environments.

Common Follow-Up Questions

What happens to in-flight connections when a Pod behind a Service is terminated?
Kubernetes removes the Pod from the Endpoints list, and kube-proxy updates iptables/IPVS rules. In-flight connections may be reset unless the application handles SIGTERM gracefully with a preStop hook and connection draining.
How does a Service know which Pods to target?
A Service uses a label selector defined in its spec. Any Pod whose labels match the selector is automatically added to the Service's endpoint list by the Endpoints controller.
Can a Service span multiple namespaces?
No. A Service selector only matches Pods within the same namespace. To reach a Service in another namespace, you use its fully qualified DNS name: <service>.<namespace>.svc.cluster.local.

Key Takeaways

  • Services decouple clients from individual Pod IPs by providing a stable virtual IP (ClusterIP) and DNS name.
  • Label selectors dynamically determine which Pods receive traffic from a Service.
  • Kubernetes DNS automatically creates records for every Service, enabling name-based discovery.