Understanding ClusterIP, NodePort, LoadBalancer, and ExternalName Services in Kubernetes

Understanding ClusterIP, NodePort, LoadBalancer, and ExternalName Services in Kubernetes

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:

  • How do pods communicate inside the cluster?
  • How do you expose a Kubernetes service externally?
  • What’s the difference between ClusterIP, NodePort, LoadBalancer, and ExternalName?

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

  • ClusterIP → Default, internal-only networking.
  • NodePort → Exposes service externally on a node’s static port.
  • LoadBalancer → Uses a cloud provider’s load balancer.
  • ExternalName → Maps to an external DNS.

Have you used different service types in Kubernetes? Let’s discuss in the comments! ??

要查看或添加评论,请登录

Bavithran M的更多文章

社区洞察

其他会员也浏览了