Understanding ClusterIP, NodePort, LoadBalancer, and ExternalName Services in Kubernetes
Bavithran M
Senior Cloud & DevOps Engineer | AWS & Azure Certified | Kubernetes & Automation Advocate | Training | Mentoring | Uplifting Many IT Professionals
In Kubernetes, Services play a crucial role in enabling communication between pods, external users, and third-party applications. But not all services work the same way!
Have you ever wondered:
This guide will provide detailed explanations, step-by-step scenarios, and practical commands to help you fully understand Kubernetes services.
?? What you’ll learn today:
? What are Kubernetes Services, and why are they needed?
? How ClusterIP, NodePort, LoadBalancer, and ExternalName work
? Real-world, hands-on scenarios with detailed steps
Let’s dive in!
?? What is a Kubernetes Service?
A Service in Kubernetes is a logical abstraction that provides a stable network endpoint for a set of pods. Since pod IPs are dynamic (changing when pods restart), a Service ensures consistent networking and load balancing across multiple pod replicas.
?? A Service helps you:
? Expose an application within or outside the cluster.
? Load balance traffic across multiple pod replicas.
? Provide a fixed DNS name for a group of pods.
Types of Kubernetes Services:
Service Type Use Case
ClusterIP - (Default) allows internal pod-to-pod communication.
NodePort - Exposes service on a static port accessible on each node.
LoadBalancer - Exposes service externally via a cloud provider’s LB.
ExternalName - Maps a service to an external domain name.
?? Scenario 1: ClusterIP – The Default Internal Service
?? Overview
A ClusterIP service is the default type in Kubernetes. It assigns a stable internal IP address that is accessible only within the cluster (not from external users).
?? Use Case:
? Best for backend microservices that only need internal communication (e.g., backend-service accessed by a frontend pod).
Step 1: Deploy a Simple Backend Application
Create a backend-deployment.yaml file:
vi backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: nginx
ports:
- containerPort: 80
Apply it:
kubectl apply -f backend-deployment.yaml
Check running pods:
kubectl get pods -o wide
Step 2: Deploy a Simple Frontend Application
Create a backend-deployment.yaml file:
vi frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: alpine
command: ["sleep", "3600"]
Apply it:
kubectl apply -f frontend-deployment.yaml
Check running pods:
kubectl get pods -o wide
Step 2: Create a ClusterIP Service
Create a backend-service.yaml file:
vi backend-service.yaml
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Apply it:
kubectl apply -f backend-service.yaml
Check service details:
kubectl get svc backend-service
Expected output:
? Now, only internal pods can access backend-service:80.
Step 3: Test ClusterIP Service
1?? Exec into another pod (like frontend) and test connectivity:
kubectl exec -it <frontend-pod> -- sh
kubectl exec -it frontend-7cc875c848-cttxp --sh
2?? Ping the ClusterIP:
wget -qO- https://backend-service:80
wget -qO- https://10.0.28.201:80
领英推荐
? Success! The backend service is accessible internally.
?? Scenario 2: NodePort – Exposing a Service on a Fixed Node Port
?? Overview
A NodePort service allows external access to a service by exposing it on a fixed port on each node’s IP.
?? Use Case:
? Best for internal testing or self-managed Kubernetes clusters without a cloud LoadBalancer.
Step 1: Modify the Backend Service to Use NodePort
Modify backend-service.yaml:
vi backend-service.yaml
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007
type: NodePort
Apply it:
kubectl apply -f backend-service.yaml
Check the service:
kubectl get svc backend-service
Expected output:
? Now, the service is accessible externally via https://<NODE_IP>:30007.
?? Scenario 3: LoadBalancer – Cloud-Based External Access
?? Overview
A LoadBalancer service provisions a cloud provider’s load balancer (e.g., AWS ELB, Azure LB, GCP LB) to expose the service externally.
?? Use Case:
? Best for production workloads that need external access with cloud load balancing.
Step 1: Modify the Backend Service to Use LoadBalancer
Note: In the POC we are using managed kubernetes in Azure (AKS). So, standard load balancer has been used in cloud provider side.(Azure). So, we have the public ip address.
Modify backend-service.yaml:
vi backend-service.yaml
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Apply it:
kubectl apply -f backend-service.yaml
Check service details:
kubectl get svc backend-service
Expected output (in a cloud environment):
Note: The above EXTERNAL-IP is the assigned public ip for the AKS cluster.
? You can now access the service via https://<EXTERNAL-IP>
?? Scenario 4: ExternalName – Mapping a Kubernetes Service to an External DNS
?? Overview
An ExternalName service maps a Kubernetes service name to an external domain name (e.g., api.example.com).
?? Use Case:
? Best for integrating external APIs (e.g., connecting to a external apache2 webserver deployed outside Kubernetes).
Now we are going to test to access the above website via domain name.
Step 1: Create an ExternalName Service
apiVersion: v1
kind: Service
metadata:
name: external-website
spec:
type: ExternalName
externalName: cloudev.site
Apply it:
kubectl apply -f externalname-service.yaml
Step 2: Test ClusterIP Service
1?? Exec into another pod (like frontend) and test connectivity:
kubectl exec -it <frontend-pod> -- sh
kubectl exec -it frontend-7cc875c848-cttxp --sh
2?? Ping the ClusterIP:
wget -qO- <domain name>
wget -qO- cloudev.site
? Now, Kubernetes automatically resolves external-db to database.example.com.
?? Key Takeaways
Have you used different service types in Kubernetes? Let’s discuss in the comments! ??