Kubernetes Service Types LoadBalancer ClusterIP NodePort
Understand Kubernetes Service types: ClusterIP, NodePort, LoadBalancer, and ExternalName. When to use each type, configuration examples, and traffic routing
π‘ Quick Answer:
ClusterIP(default) β internal access only via cluster DNS.NodePortβ exposes on each nodeβs IP at a static port (30000-32767).LoadBalancerβ provisions external cloud load balancer.ExternalNameβ CNAME alias to external DNS. Use ClusterIP for service-to-service; LoadBalancer or Ingress for external traffic.
The Problem
- Need to expose applications internally (to other pods) and externally (to users)
- Different environments require different access patterns (dev vs production)
- Cloud vs on-premises clusters have different external access options
- Understanding when to use LoadBalancer vs Ingress vs NodePort
- Service discovery and DNS resolution for pod-to-pod communication
The Solution
Service Types Overview
Type β Access Scope β Use Case β Port Range
βββββββββββββββΌββββββββββββββββββββΌββββββββββββββββββββββββββββββΌβββββββββββ
ClusterIP β Internal only β Service-to-service comms β Any
NodePort β External via node β Dev/testing, on-prem β 30000-32767
LoadBalancer β External via LB β Production cloud β Any
ExternalName β DNS alias β External service reference β N/A
βββββββββββββββ΄ββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄βββββββββββClusterIP (Default)
apiVersion: v1
kind: Service
metadata:
name: api-server
namespace: production
spec:
type: ClusterIP # Default β can be omitted
selector:
app: api-server
ports:
- name: http
port: 80 # Service port (what clients connect to)
targetPort: 8080 # Container port (where app listens)
protocol: TCP# Access from within cluster:
curl http://api-server.production.svc.cluster.local:80
curl http://api-server.production:80 # Short form (same namespace)
curl http://api-server:80 # Shortest (same namespace)NodePort
apiVersion: v1
kind: Service
metadata:
name: api-server-nodeport
spec:
type: NodePort
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Optional: auto-assigned if omitted (30000-32767)# Access from outside cluster:
curl http://<any-node-ip>:30080
# Also accessible internally via ClusterIP (NodePort includes ClusterIP)LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: api-server-lb
annotations:
# Cloud-specific annotations:
# AWS:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
# GCP:
# cloud.google.com/neg: '{"ingress": true}'
spec:
type: LoadBalancer
selector:
app: api-server
ports:
- port: 443
targetPort: 8080
protocol: TCP
# Optional: restrict source IPs
loadBalancerSourceRanges:
- "203.0.113.0/24"
- "198.51.100.0/24"# Get external IP
kubectl get svc api-server-lb
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# api-server-lb LoadBalancer 10.96.1.100 203.0.113.50 443:31234/TCP
# Access externally:
curl https://203.0.113.50:443ExternalName
# DNS alias to external service (no proxying)
apiVersion: v1
kind: Service
metadata:
name: external-database
spec:
type: ExternalName
externalName: database.example.com
# Pods can now access: external-database.namespace.svc.cluster.local
# Resolves to: database.example.com (CNAME)Headless Service (No ClusterIP)
# For StatefulSets β each pod gets its own DNS record
apiVersion: v1
kind: Service
metadata:
name: database
spec:
clusterIP: None # Headless
selector:
app: database
ports:
- port: 5432# DNS returns individual pod IPs:
nslookup database.production.svc.cluster.local
# database-0.database.production.svc.cluster.local β 10.0.1.5
# database-1.database.production.svc.cluster.local β 10.0.1.6When to Use What
Scenario β Recommended
βββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ
Internal microservice communication β ClusterIP
Database accessed by apps β ClusterIP (or Headless)
Web app for external users (cloud) β LoadBalancer + Ingress
Web app for external users (on-prem) β NodePort + external LB
β or MetalLB + LoadBalancer
Development/testing quick access β NodePort or port-forward
Reference external service by DNS β ExternalName
StatefulSet pod-specific DNS β Headless (clusterIP: None)
βββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββCommon Issues
LoadBalancer stuck in βPendingβ for EXTERNAL-IP
- Cause: No cloud provider or MetalLB installed (bare-metal cluster)
- Fix: Install MetalLB for on-prem; or use NodePort + external LB
Service has no endpoints
- Cause: Selector labels donβt match any pod labels; or pods not ready
- Fix: Compare
kubectl get endpoints <svc>withkubectl get pods --show-labels
NodePort not reachable from outside
- Cause: Firewall blocking high ports; or security group missing rule
- Fix: Open port range 30000-32767 on node firewalls/security groups
ExternalName not resolving
- Cause: DNS lookup returns CNAME but client doesnβt follow it
- Fix: Ensure app handles CNAME; note: ExternalName doesnβt support ports or TLS termination
Best Practices
- Default to ClusterIP β most services only need internal access
- Use Ingress/Gateway over LoadBalancer β one LB for many services (cost savings)
- Donβt expose NodePort in production β use LoadBalancer or Ingress instead
- Set
targetPortby name β reference container port name for flexibility - Use headless for StatefulSets β enables pod-specific DNS records
- Restrict LoadBalancer source ranges β
loadBalancerSourceRangesfor IP allowlisting
Key Takeaways
- ClusterIP: internal only (default) β accessed via
<svc>.<ns>.svc.cluster.local - NodePort: external via any node IP on port 30000-32767
- LoadBalancer: provisions cloud LB with external IP β includes NodePort + ClusterIP
- ExternalName: DNS CNAME to external service β no proxying
- Headless (
clusterIP: None): returns individual pod IPs β for StatefulSets - In production: use Ingress/Gateway API with one LoadBalancer for many services

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
