Kubernetes Services Explained: ClusterIP, NodePort and LoadBalancer
Pods in Kubernetes are disposable — they get rescheduled, replaced and reassigned new IP addresses constantly. If your application tried to talk directly to a Pod's IP, it would break the moment Kubernetes rescheduled that Pod. Services solve exactly this problem: a stable network identity that sits in front of a changing set of Pods.
Why Services exist
A Deployment might manage 3 replicas of your app right now, scale to 6 under load, and roll each Pod through several IP addresses over its lifetime. A Service gives you one stable DNS name and IP that always routes to whichever Pods currently match its label selector — you never talk to a Pod directly.
Client → Service (stable) → Pod A / Pod B / Pod C (constantly changing)
Kubernetes ships with three Service types you'll use in almost every real cluster.
ClusterIP (the default)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 3000
ClusterIP gives the Service an IP that's only reachable from inside the cluster. This is what you use for internal communication — a backend API talking to a database service, or one microservice calling another. If you don't specify a type at all, this is what you get by default.
NodePort
spec:
type: NodePort
ports:
- port: 80
targetPort: 3000
nodePort: 30080
NodePort opens a specific port (30000-32767 by default) on every node in the cluster, and traffic hitting that port on any node gets routed to the Service. It's useful for quick testing or on-prem clusters without a cloud load balancer, but it's rarely how you expose something in production — the port number is ugly, and you're relying on node IPs being reachable, which usually isn't the case in a cloud VPC.
LoadBalancer
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 3000
LoadBalancer asks your cloud provider to provision an actual external load balancer (on AWS, this means an ELB) and points it at your Service. This is the standard way to expose an application to the public internet on a managed Kubernetes service like Amazon EKS. Under the hood, it's still doing what NodePort does — but with a real, cloud-provisioned entry point in front of it instead of raw node IPs.
Quick decision guide
- Internal-only traffic between services →
ClusterIP - Quick local/on-prem testing →
NodePort - Public-facing production traffic on a cloud cluster →
LoadBalancer(or an Ingress controller sitting in front of a ClusterIP Service — the more common production pattern once you have multiple services to expose under one domain)
Common mistakes
Using LoadBalancer for every internal service. Each LoadBalancer Service provisions a real cloud load balancer — on AWS that's a billed resource per Service. Expose only what actually needs to be public; keep internal service-to-service traffic on ClusterIP.
Forgetting the selector has to match Pod labels exactly. A Service with selector: { app: my-app } routes to zero Pods — silently — if your Pods are labeled app: myapp instead. kubectl get endpoints my-app is the fastest way to check whether a Service actually has any Pods behind it.
Confusing port and targetPort. port is what the Service itself listens on; targetPort is the port your container is actually listening on inside the Pod. They don't have to match, and mixing them up is one of the most common causes of a Service "not working."
Where this fits in the bigger picture
Kubernetes is step 6 in our DevOps roadmap — right after Docker, once you're running enough containers that managing them by hand stops working. If containers themselves are still new to you, start with Docker Tutorial for Beginners first — Services only make sense once you understand what's actually running inside a Pod. Services are one of the first Kubernetes objects worth understanding deeply, since almost nothing else in a cluster is reachable without one. Once your cluster itself needs to be provisioned reliably (not clicked together by hand), Terraform: Providers, Resources and State is the natural next stage.
Want to learn this hands-on, live?
Join Waitlist