Kubernetes Services: ClusterIP vs NodePort vs LoadBalancer
By LearnSome.tech · Published 2026-11-04
TL;DR
A ClusterIP Service exposes a Service on a cluster-internal IP, and it is the default type. NodePort exposes the Service on each Node's IP at a static port, and LoadBalancer exposes it externally using an external load balancer. The type field is designed as nested functionality, where each level adds to the previous.
What is the difference between ClusterIP, NodePort and LoadBalancer?
A ClusterIP Service assigns an IP address from a pool of IP addresses that your cluster has reserved for that purpose. To make a node port available, Kubernetes sets up a cluster IP address, the same as if you had requested a ClusterIP Service. For a LoadBalancer Service, Kubernetes typically starts off by making the changes equivalent to requesting a NodePort Service. On cloud providers which support external load balancers, the LoadBalancer type provisions a load balancer for your Service.
| Type | Who can reach it | Builds on |
|---|---|---|
| ClusterIP | Clients inside the cluster | Nothing, it is the base |
| NodePort | Anyone who can reach a node | ClusterIP |
| LoadBalancer | Clients of the cloud load balancer | NodePort |
| ExternalName | Not a proxy, a DNS alias | No cluster IP |
Use the table to pick the narrowest type that still reaches your clients.
What does each type look like in a manifest?
Here is one app exposed three ways, with a comment on what each line adds.
# ClusterIP (the default): reachable only inside the cluster
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # pods with this label receive the traffic
ports:
- port: 80 # the Service's port
targetPort: 8080 # the container's port
---
# NodePort: the same, plus a port on every node
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # optional; omit it and the control plane picks one from its range
---
# LoadBalancer: the same again, plus a cloud load balancer in front
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
# kubectl get svc web -> EXTERNAL-IP shows <pending> until the cloud creates itWhen should you use NodePort?
Kubernetes allocates a NodePort from a range set by a flag, which defaults to 30000-32767. You can contact a NodePort Service from outside the cluster by connecting to any node on the port assigned to that Service. A NodePort gives you the freedom to set up your own load balancing solution or to configure environments that are not fully supported by Kubernetes. If you want a specific port, you can set the nodePort field to a valid port inside the configured range.
Reach for NodePort on a lab cluster, on bare metal behind your own load balancer, or for a quick test from your laptop.
Does a LoadBalancer Service also open a NodePort?
Yes: by default, LoadBalancer Services continue to allocate node ports. You can optionally disable node port allocation for a LoadBalancer Service with a field in its spec. The load balancer is created asynchronously, and its details are published in the Service's .status.loadBalancer field.
# A LoadBalancer Service still shows a node port by default
$ kubectl get svc web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
web LoadBalancer 10.96.12.40 203.0.113.10 80:31234/TCP
# ^ 80 is the Service port, 31234 the node port
# Check your firewall rules: that node port is open on the nodes as well.What is an ExternalName Service?
An ExternalName Service maps the Service to the contents of the externalName field, for example a hostname. It is a special case of Service that does not have selectors and uses DNS names instead. Kubernetes cautions that you may have trouble using ExternalName for some common protocols, including HTTP and HTTPS. A headless Service is different again: you set the cluster IP to None, and no cluster IP is allocated.
Service vs Ingress: which do you need?
Ingress is not a Service type, but it acts as the entry point for your cluster. An Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. It does not expose arbitrary ports or protocols. The Kubernetes project recommends using Gateway instead of Ingress, and the Ingress API has been frozen.
You can expose a Service to the public internet using an Ingress or a Gateway. An Ingress lets you consolidate your routing rules into a single resource, so you can expose several components of your workload behind a single listener.
Why does a Service get no traffic?
A control loop inside Kubernetes evaluates the selector of every Service and saves the results into one or more EndpointSlice objects. If the ENDPOINTS column is empty, check that the Service's spec.selector field actually selects for the labels on your Pods. You can then bypass the Service and go straight to the Pods, to check that they are actually working.
Here is that check as commands, with a comment on what each one rules out.
# 1. Does the Service exist, with the type and ports you expect?
kubectl get svc web -o wide
# 2. Did its selector find any pods? An empty ENDPOINTS list means no.
kubectl get endpointslices -l kubernetes.io/service-name=web
# 3. Compare the selector with the pod labels, character by character
kubectl get svc web -o jsonpath='{.spec.selector}'; echo
kubectl get pods --show-labels
# 4. Are the pods Ready? Pods that are not Ready don't receive Service traffic
kubectl get pods -l app=web
# 5. Does targetPort match the port the container listens on?
kubectl get svc web -o jsonpath='{.spec.ports[*].targetPort}'; echoWork through the list in order, and stop at the first step that fails.
Free official resources
Kubernetes Basics is an in-depth interactive tutorial that helps you understand the Kubernetes system and try out some basic Kubernetes features. Its Using a Service to Expose Your App module shows how labels and selectors relate to a Service and how to expose an application outside a Kubernetes cluster. To practise on your own computer, minikube is a tool that lets you run Kubernetes locally on Windows, macOS and Linux PCs.
Introduction to Kubernetes is a free course that gives an in-depth primer on Kubernetes and covers how to set up and access a cluster using Minikube.
From our labs
In our Kubernetes course, you expose pods with a ClusterIP Service, verify its EndpointSlices and resolve its stable DNS name. The next lab has you choose among ClusterIP, NodePort, LoadBalancer and ExternalName according to the traffic boundary you need.
Start the free lesson: From Docker To Desired State (Kubernetes: Production-Grade Container Orchestration)
The course: Kubernetes: Production-Grade Container Orchestration
Terms in this guide
- ClusterIP
- ExternalName
- Gateway API
- headless Service
- Ingress
- Kubernetes Service
- LoadBalancer Service
- NodePort
Sources
- Service | Kubernetes
- Ingress | Kubernetes
- Debug Services | Kubernetes
- Tutorials | Kubernetes
- Using a Service to Expose Your App | Kubernetes
- Install Tools | Kubernetes
- Introduction to Kubernetes (LFS158) - Linux Foundation - Training
Written by the LearnSome.tech team with AI assistance; every fact checked against the cited source.