Services

Services

Pods come and go and their IPs change. A Service is the stable address in front of them, with load balancing built in.

graph LR C[Client] --> S[Service nginx-svc<br/>ClusterIP 10.96.x.x] S --> P1[Pod 10.244.1.5] S --> P2[Pod 10.244.2.7] S --> P3[Pod 10.244.3.9]

The Service selects Pods by label. Matching, ready Pod IPs land in an EndpointSlice, and kube-proxy programs each node accordingly.

Types

TypeReachable fromNote
ClusterIPinside the cluster onlythe default
NodePort<any-node-ip>:30000-32767opens the port on every node
LoadBalanceroutsideneeds a cloud provider or MetalLB - not in this cluster
ExternalName-just a DNS CNAME
spec:
  type: NodePort
  selector:
    app: nginx          # must match the Pod labels
  ports:
    - port: 8080        # the Service port
      targetPort: 80    # the container port
      nodePort: 30080   # the port on every node

DNS

nginx-svc                        # same namespace
nginx-svc.dev                    # other namespace
nginx-svc.dev.svc.cluster.local  # fully qualified

Headless Services

clusterIP: None gives no virtual IP; DNS returns the Pod IPs directly. This is how StatefulSets give each replica a stable name - see StatefulSets.

When it does not work

kubectl get endpointslices -l kubernetes.io/service-name=nginx-svc

No endpoints means the selector matches no ready Pod. Check labels, then the readiness probe, then targetPort.

References