๐Ÿ“– Read-only preview โ€” lessons, diagrams, and quizzes only. The hands-on labs, live grading, and progress tracking require running the real course locally against a Kubernetes cluster.Run it locally โ†’

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

Click a pod to simulate it being replaced (crash, rollout, reschedule) โ€” a new pod, a new IP, but the Service's own address never changes, and its Endpoints list updates automatically.

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 only

Goal

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

  1. Apply the starting manifests: kubectl apply -f manifests/
  2. Confirm the pods are up: kubectl get pods -n lab-07-service-types -l app=web โ€” 3 pods, all Running.
  3. 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.
  4. 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.
  5. Fix the mismatch in manifests/app.yaml and re-apply: kubectl apply -f manifests/app.yaml
  6. Confirm: kubectl get endpoints web -n lab-07-service-types now 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.