Services give pods stable network identities. Pods come and go, but the service DNS name stays constant. Choosing the right service type determines how your application is exposed.
ClusterIP (Default)
Internal-only. Only accessible within the cluster:
apiVersion: v1
kind: Service
metadata:
name: api
spec:
type: ClusterIP # default, can be omitted
selector:
app: api
ports:
- port: 80 # Service port
targetPort: 3000 # Container port
protocol: TCPOther pods → api:80 → Pod 10.0.1.5:3000
→ Pod 10.0.1.6:3000
→ Pod 10.0.1.7:3000Use for: Backend services, databases, internal APIs.
# From any pod in the cluster
curl http://api # Same namespace
curl http://api.default.svc # Full DNS
curl http://api.production.svc # Different namespaceNodePort
Exposes on every node's IP at a static port:
apiVersion: v1
kind: Service
metadata:
name: api
spec:
type: NodePort
selector:
app: api
ports:
- port: 80
targetPort: 3000
nodePort: 30080 # Optional: 30000-32767 rangeExternal → NodeIP:30080 → Service → Pod:3000Accessible at .
Use for: Development, on-prem without load balancer, testing.
Avoid for: Production (no SSL termination, limited port range, exposes node IPs).
LoadBalancer
Provisions a cloud load balancer:
apiVersion: v1
kind: Service
metadata:
name: api
annotations:
# AWS-specific
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
type: LoadBalancer
selector:
app: api
ports:
- port: 80
targetPort: 3000
- port: 443
targetPort: 3000Internet → Cloud LB (public IP) → Node → Pod:3000kubectl get svc api
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# api LoadBalancer 10.96.0.1 203.0.113.50 80:31234/TCPUse for: Simple external access to a single service.
Limitations: One LB per service (expensive), no path-based routing.
Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →ExternalName
DNS alias to an external service:
apiVersion: v1
kind: Service
metadata:
name: database
spec:
type: ExternalName
externalName: db.rds.amazonaws.com# From pods
curl http://database # Resolves to db.rds.amazonaws.comUse for: Pointing to external databases, SaaS APIs, migration from external to internal services.
No proxying — just a CNAME DNS record.
Headless Service
No cluster IP. DNS returns individual pod IPs:
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
clusterIP: None # This makes it headless
selector:
app: postgres
ports:
- port: 5432# DNS returns ALL pod IPs (not load-balanced)
nslookup postgres
# postgres.default.svc.cluster.local → 10.0.1.5
# postgres.default.svc.cluster.local → 10.0.1.6With StatefulSets, each pod gets its own DNS:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres # Must match headless service name
replicas: 3# Individual pod DNS
postgres-0.postgres.default.svc # Primary
postgres-1.postgres.default.svc # Replica
postgres-2.postgres.default.svc # ReplicaUse for: StatefulSets (databases, message queues), client-side load balancing, service discovery.
Multi-Port Services
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- name: http
port: 80
targetPort: 3000
- name: grpc
port: 9090
targetPort: 9090
- name: metrics
port: 9091
targetPort: 9091Port names are required when defining multiple ports.
Get weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Service Discovery
# DNS (preferred)
curl http://service-name # Same namespace
curl http://service-name.namespace # Cross-namespace
curl http://service-name.namespace.svc.cluster.local # Full FQDN
# Environment variables (set at pod start)
echo $API_SERVICE_HOST # 10.96.0.1
echo $API_SERVICE_PORT # 80Comparison
| Type | Access | Cloud LB | Use Case |
|---|---|---|---|
| ClusterIP | Internal only | No | Backend services |
| NodePort | Node IP + port | No | Dev/testing |
| LoadBalancer | External IP | Yes | Simple external access |
| ExternalName | DNS alias | No | External service reference |
| Headless | Pod IPs directly | No | StatefulSets, discovery |
In production, most teams use ClusterIP + Ingress Controller instead of LoadBalancer per service.
What's Next?
Our Docker Fundamentals course covers container networking and Kubernetes services. MLflow for Kubernetes MLOps teaches service architecture for ML platforms. First lessons are free. -e ---
Ready to go deeper? Explore our hands-on DevOps courses — from Docker and Terraform to MLflow on Kubernetes.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Kubernetes Services and Ingress
Expose Kubernetes workloads with ClusterIP, NodePort, LoadBalancer services and Ingress controllers. Practical examples.
Cilium Service Mesh Kubernetes
Cilium replaces kube-proxy and sidecar service meshes with eBPF. Learn how Cilium handles networking, observability, and security in Kubernetes.
Linkerd Lightweight Service Mesh
Linkerd is the lightest Kubernetes service mesh with automatic mTLS, golden metrics, and zero-config retries. Learn how Linkerd compares to Istio and when its.
Kubernetes Storage PV and PVC Guide
Kubernetes persistent storage explained: PVs, PVCs, StorageClasses, dynamic provisioning, StatefulSets, and backup strategies.
Kubernetes Troubleshooting Checklist
Kubernetes troubleshooting checklist. Pod failures, CrashLoopBackOff, networking issues, DNS resolution, and storage fixes.
Kubescape Kubernetes Security Scan
Kubescape scans Kubernetes clusters against NSA, MITRE, and CIS benchmarks. Learn how to audit cluster security, fix misconfigurations, and integrate.
Explore topics
Browse more articles on the topics covered here.