Module 4 ยท Lesson 4.1
Service Types: ClusterIP, NodePort, LoadBalancer
The problem a Service solves
Pods are disposable. A Deployment replaces them constantly โ rollouts, crashes, rescheduling โ and every replacement gets a new IP. Nothing that depends on "the app" can hardcode a pod IP and expect it to keep working.
A Service is a stable virtual IP and DNS name that sits in front of a changing set of pods, found the same way you already know: a label selector. You met the mechanics of selectors in Module 2 โ a Service is just one more controller doing exactly that continuous "watch and match" loop, this time to build a routing table instead of to own replicas.
One stable Service, a churning set of pods
Service: web (ClusterIP 10.96.12.34)
selector: app=web โ never changes
Endpoints right now: web-a1, web-b2, web-c3
The three types you'll actually use
- ClusterIP (the default) โ a virtual IP reachable only from inside the cluster. This is what most pod-to-pod traffic uses: frontend to API, API to database.
- NodePort โ additionally opens the same port on every node's own IP. Mostly a building block for the next one, or a quick way to reach something from outside without a cloud load balancer.
- LoadBalancer โ asks the cloud provider (AWS, in Module 15) to
provision a real external load balancer that forwards to the Service.
On a local cluster like yours, this type stays
<pending>forever โ there's no cloud underneath to fulfill it.
Endpoints: where the selector match actually lands
Every Service continuously populates an Endpoints (or EndpointSlice)
object with the IPs of every currently-matching, ready pod. This is the
layer where Module 2's silent-failure problem bites hardest: a selector
typo doesn't error anywhere โ the Service object creates successfully, it
just never gets any endpoints, and traffic sent to it has nowhere to go.
kubectl get endpointslice -l kubernetes.io/service-name=<service> is always
your first move when a Service "isn't working": zero addresses means a
selector mismatch, full stop. (You'll also see the older kubectl get endpoints <service> in a lot of existing docs and muscle memory โ it still
works today, but it's deprecated as of Kubernetes 1.33 in favor of
EndpointSlice, which scales better and supports dual-stack IPs, so this
course teaches the new one.)
The infrastructure analogy
A ClusterIP Service is the closest thing in Kubernetes to a VIP on an internal load balancer, with its pool membership rewritten automatically and continuously instead of through a change ticket. NodePort is closer to opening a static port on every box in a fleet โ crude, but occasionally exactly what you need. LoadBalancer is the only one of the three that reaches outside the cluster to provision something real, which is also why it's the only one that does nothing useful without a cloud provider behind it.
In the lab, you'll hit the exact zero-endpoints failure described above, and fix it the same way you would in production: by comparing a Service's selector against your pods' actual labels.
๐งช Lab: lab-07-service-types
Preview onlyGoal
Hit the single most common Service bug there is โ a selector that doesn't match any pod โ diagnose it the right way, and fix it.
Tasks
- Apply the starting manifests:
kubectl apply -f manifests/ - Confirm the pods are up:
kubectl get pods -n lab-07-service-types -l app=webโ 3 pods, allRunning. - Check the Service:
kubectl get svc web -n lab-07-service-typesโ it exists, no error. Now check what it's actually routing to:kubectl get endpoints web -n lab-07-service-types. Empty. - Compare the Service's selector against the pods' real labels:
kubectl get service web -n lab-07-service-types -o jsonpath='{.spec.selector}'vs.kubectl get pods -n lab-07-service-types --show-labels. - Fix the mismatch in
manifests/app.yamland re-apply:kubectl apply -f manifests/app.yaml - Confirm:
kubectl get endpoints web -n lab-07-service-typesnow lists 3 pod IPs.
Check
Run the check once the Service has endpoints for all 3 pods.
This lab runs against a real local Kubernetes cluster with an automated grader โ clone the repo and run make start to do it for real.
๐ Quiz
1. Why do pods need a Service in front of them instead of talking to each other's pod IPs directly?
2. How does a Service know which pods are currently 'behind' it?
3. You create a LoadBalancer-type Service on your local kind cluster. What happens?scenario
4. `kubectl get endpoints my-svc` returns an empty list, but the Service object itself exists with no errors. What's the most likely cause?scenario
5. Which statements about the three Service types are correct? (select all that apply)
Progress isn't saved in this preview โ run the course locally to track completion and grade labs for real.