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
| Type | Reachable from | Note |
|---|---|---|
ClusterIP | inside the cluster only | the default |
NodePort | <any-node-ip>:30000-32767 | opens the port on every node |
LoadBalancer | outside | needs 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.