Pods come and go, and their IPs change. A Service gives a stable name and virtual IP and balances across pods matched by label.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector: { app: web }
ports:
- port: 80
targetPort: 80
| Type | Reachable from |
|---|---|
| ClusterIP (default) | Inside the cluster only |
| NodePort | Every node on a port 30000 to 32767 |
| LoadBalancer | The internet, via the cloud provider’s load balancer |
CoreDNS gives every service a name: web within its namespace, or web.default.svc.cluster.local from anywhere.
kubectl run tmp --rm -it --image=busybox:1.33 -- wget -qO- http://web
kubectl get endpoints web
If a service has no endpoints, its selector does not match any ready pod. That is the first thing to check.