Kubernetes Service Types
A detailed comparison of the four Kubernetes Service types — when to use each, their YAML patterns, and their behavior in different environments. Synthesized from CKA Day 9 — Kubernetes Services Explained.
Quick Comparison
| Type | Scope | External Access | Use Case | CKA Relevance |
|---|---|---|---|---|
| ClusterIP | Internal only | ❌ No | Pod-to-Pod communication | Very High |
| NodePort | External via Node IP | ✅ Port 30,000–32,767 | Dev, bare metal, no cloud LB | High |
| LoadBalancer | External via cloud LB | ✅ Auto-provisioned IP | Production on cloud providers | Medium |
| ExternalName | DNS alias | ❌ (redirects) | External database/API integration | Low |
1. ClusterIP (Default)
ClusterIP is the default Service type. It assigns an internal IP address that is reachable only from within the cluster.
When to Use
- Front-end Pods communicating with back-end Pods
- Microservices talking to each other internally
- Any traffic that should never leave the cluster
YAML
apiVersion: v1
kind: Service
metadata:
name: backend-svc
spec:
type: ClusterIP # Optional — defaults to ClusterIP if omitted
selector:
app: backend
ports:
- port: 8080
targetPort: 8080Access Patterns
# From another Pod in the same namespace
curl http://backend-svc:8080
# Fully Qualified Domain Name (FQDN)
curl http://backend-svc.default.svc.cluster.local:8080Key Characteristics
- Most secure — no external exposure
- Zero cloud-provider dependency
- If
typeis omitted, Kubernetes assumes ClusterIP - The
kubernetesdefault Service indefaultnamespace is a ClusterIP pointing to the API Server
2. NodePort
NodePort extends ClusterIP by exposing the Service on a static port (30,000–32,767) on every node’s IP address.
When to Use
- Local development and testing
- Bare-metal clusters without a cloud load balancer
- Quick external access when you don’t need a fancy LB
YAML
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30001 # Must be in range 30000-32767Access Patterns
# From outside the cluster (any node IP)
curl http://<NodeIP>:30001
# Check which node a Pod runs on
kubectl get pods -o wide
kubectl describe pod <pod-name> | grep Node:Internal Behavior
Even with NodePort, the Service still creates a ClusterIP internally. The flow is:
External Client
│
▼
NodeIP:30001 ──▶ kube-proxy ──▶ ClusterIP ──▶ Pod:targetPort
Kind Cluster Gotcha
Kind runs Kubernetes inside Docker containers. By default, NodePorts are not exposed to the host. You must explicitly map the port:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30001
hostPort: 30001Then recreate the cluster. On cloud VMs, bare metal, or the CKA exam, this extra step is unnecessary. Source: CKA Day 9
3. LoadBalancer
LoadBalancer extends NodePort by provisioning an external cloud load balancer. It provides a single public IP or DNS name that distributes traffic across all nodes.
When to Use
- Production workloads on AWS, Azure, GCP, or any cloud with LB integration
- When you need a stable public endpoint (
myapp.com) - When you want the cloud provider to handle health checks and traffic distribution
YAML
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80Behavior Without Cloud Provider
On clusters without cloud-provider integration (e.g., local Kind, on-prem without CCM):
kubectl get svc nginx-lb
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# nginx-lb LoadBalancer 10.96.123.45 <pending> 80:31234/TCPEXTERNAL-IPstays<pending>indefinitely- Kubernetes still allocates a random
nodePort(e.g., 31234) - The Service behaves exactly like a NodePort — accessible via
NodeIP:31234 - In Kind, you can simulate a real LoadBalancer with
cloud-provider-kind
Cloud Provider Integration
| Cloud | Integration |
|---|---|
| AWS | Creates a Classic ELB or NLB |
| Azure | Creates an Azure Load Balancer |
| GCP | Creates a GCP Network LB |
| On-Prem | Requires MetalLB or cloud-provider-kind |
4. ExternalName
ExternalName is fundamentally different — it does not route to Pods at all. Instead, it acts as a DNS CNAME alias to an external domain.
When to Use
- Your database lives outside the cluster (RDS, Cloud SQL, managed DB)
- You want application code to reference a Kubernetes Service name (
db-svc) while the actual resolution points toprod-db.example.com - Migrating external services into Kubernetes gradually
YAML
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: database.example.comAccess Patterns
# From inside the cluster, this resolves to database.example.com
curl http://external-db
# DNS lookup
nslookup external-db.default.svc.cluster.local
# Server: database.example.comKey Characteristics
- No
selector— it doesn’t select Pods - No
portssection needed - No ClusterIP assigned
- Pure DNS redirection; the actual connection is made to the external domain
- If the external domain changes, update the Service — application code stays unchanged
Selector Behavior Across Types
| Service Type | Requires Selector? | Selects Pods? | Creates Endpoints? |
|---|---|---|---|
| ClusterIP | Yes | Yes | Yes |
| NodePort | Yes | Yes | Yes |
| LoadBalancer | Yes | Yes | Yes |
| ExternalName | No | No | No |
Choosing the Right Service Type
Is the traffic internal only?
├── YES → ClusterIP
└── NO → Is this a cloud production environment?
├── YES → LoadBalancer
└── NO → Do you need external access?
├── YES → NodePort
└── NO → ExternalName (external DNS alias)
Exam Traps & Common Mistakes
- Case Sensitivity:
NodePortandLoadBalancermust use capital N/P and L/B.nodeportorloadbalancerwill be rejected. - Selector vs matchLabels: Services use
selector: {app: nginx}, NOTselector: matchLabels: {app: nginx}. The latter is for Deployments/ReplicaSets. - NodePort Range: Manually specified nodePort must be 30,000–32,767. Values outside this range are rejected.
- Kind Port Mapping: Forgetting
extraPortMappingsin Kind and wondering why NodePort doesn’t work from localhost. - LoadBalancer on Local: Expecting an external IP on Kind/minikube without a cloud provider or MetalLB.
Sources
Related Pages
- Kubernetes Services — Overview, port concepts, and troubleshooting
- Pod Fundamentals — Why Pods need Services
- Deployment, ReplicaSet & Replication Controller — Workloads that Services expose
- Kind Cluster Setup — Port mapping configuration
- Kubernetes Architecture — kube-proxy and network routing
- Kubernetes Namespaces — Cross-namespace DNS and service discovery boundaries
- CKA Certification — Exam structure
Tags: kubernetes services clusterip nodeport loadbalancer externalname networking cka devops yaml