Take a moment to think about this
A Pod's IP address is temporary — every time the Deployment creates a new pod, the IP can change. If a frontend wants to connect to a backend, it can't keep up with an IP that keeps shifting — that's what a Service is for. A Service gives all pods matching a label a stable network address (a name) that 'stands in front of' them — no matter how many pods come and go, the Service address never changes. There are three common Service types: ClusterIP (reachable only within the cluster), NodePort (reachable from outside via a server port), and LoadBalancer (auto-creates a load balancer from your cloud provider).
Let's connect this to a real scenario
When a frontend pod connects to a name like `backend-service` (instead of an IP), Kubernetes's built-in DNS routes it to whichever backend pod matches the label — no matter how much the backend scales up or down, the Service name always stays stable. To try out the LoadBalancer type on local minikube, you'll need `minikube tunnel` (since there's no cloud provider).
Let's look at it together
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 80$ kubectl apply -f service.yaml
service/web-service created
$ kubectl get service web-service
NAME TYPE CLUSTER-IP PORT(S) AGE
web-service ClusterIP 10.96.45.201 80/TCP 5s5-minute try-it
Connect web-service to the web-deployment from the deployments lesson (make sure selector: app: web matches) — check with `kubectl get endpoints web-service` to confirm the pod IPs are connected.
A quick word of caution
Deleting a Service can break the connection for every app that was using it — be careful when deleting a Service in production.