Skip to main content

Command Palette

Search for a command to run...

Day-4-kubernetes

Understanding Kubernetes Services: ClusterIP, NodePort, and LoadBalancer

Updated
6 min read
G

Experienced DevOps Engineer with expertise in CI/CD automation, cloud infrastructure, Kubernetes, and GitOps. Provisioned a Jenkins server on AWS EC2 for automated deployments, integrating Terraform to provision VPCs and EKS clusters. Configured a Jump Server for secure Kubernetes access and implemented ArgoCD for GitOps-driven deployments. Integrated SonarQube for static code analysis and enforced quality gates in Jenkins pipelines. Built AWS ECR repositories and automated Docker image management. Ensured security by managing secrets in Jenkins Credentials Manager and implementing IAM policies for AWS resources. Configured Kubernetes Ingress via ArgoCD and deployed MongoDB with persistence strategies. Designed multi-branch Jenkins pipelines for different environments. Installed Prometheus and Grafana for monitoring with automated alerts. Optimized costs using AWS CloudWatch and Lambda for unused resource cleanup. Ensured end-to-end automation, security, and observability.

TLDR: This blog post provides a comprehensive overview of Kubernetes services, including ClusterIP, NodePort, and LoadBalancer, explaining their functionalities, use cases, and practical implementations within a Kubernetes cluster.

Kubernetes is a powerful platform for managing containerized applications, and understanding its services is crucial for effective deployment and management. In this post, we will explore the different types of Kubernetes services: ClusterIP, NodePort, and LoadBalancer. We will also discuss their use cases and provide practical examples to illustrate their functionalities.

In previous discussions, we covered various Kubernetes concepts such as deployments, daemon sets, stateful sets, and the architecture of Kubernetes clusters. However, to effectively utilize Kubernetes in real-world scenarios, especially in interviews, it is essential to understand services and how they expose applications to the external world.

What are Kubernetes Services?

Once you deploy an application using a deployment, it is not sufficient to simply run it. You need to expose this deployment to allow external access. This is where Kubernetes services come into play. Services provide stable endpoints for accessing applications running in a Kubernetes cluster.

Types of Kubernetes Services

Kubernetes offers several types of services, each serving different purposes:

  1. ClusterIP

  2. NodePort

  3. LoadBalancer

  4. ExternalName

  5. Headless Services

ClusterIP

ClusterIP is the default service type in Kubernetes. It exposes the service on a cluster-internal IP. This means that the service is only accessible from within the cluster.

Use Case for ClusterIP

ClusterIP is ideal for internal communication between microservices. For example, if you have multiple microservices such as catalog, payment, and order history, they can communicate with each other using ClusterIP without exposing them to the outside world.

ClusterIP also provides load balancing for requests directed to the service, using a round-robin method to distribute traffic across the available pods.

NodePort

NodePort is another service type that allows you to expose a service on a static port on each node’s IP address. This means that you can access the service from outside the cluster using the node's IP and the assigned port.

How NodePort Works

When you create a NodePort service, Kubernetes allocates a port from a predefined range (usually between 30000 and 32767). When a request is made to the NodePort, it forwards the request to the ClusterIP service, which then routes it to the appropriate pod.

Use Case for NodePort

NodePort is useful for development and testing environments where you need to expose services without setting up a full load balancer. However, it is not recommended for production use due to the complexity of managing static ports.

LoadBalancer

LoadBalancer is a service type that provisions a load balancer for your service in cloud environments. It provides a stable external IP address that can be used to access the service.

How LoadBalancer Works

When you create a LoadBalancer service, Kubernetes interacts with the cloud provider to provision a load balancer. This load balancer will route external traffic to the appropriate pods based on the service configuration.

Use Case for LoadBalancer

LoadBalancer is the preferred method for exposing services in production environments. It allows you to provide a user-friendly DNS name instead of a raw IP address and port combination, making it easier for users to access your application.

ExternalName

The ExternalName service allows you to map a service to an external DNS name. This is particularly useful when you need to integrate external resources, such as databases, into your Kubernetes applications.

Headless Services

Headless services are used primarily with stateful sets. They allow you to directly access the individual pods without a load balancer or ClusterIP.

Practical Implementation

To illustrate the concepts discussed, let’s walk through a practical example of creating and exposing a deployment using ClusterIP, NodePort, and LoadBalancer.

Step 1: Create a Deployment

First, we will create a deployment named app1 with three replicas:

kubectl create deployment app1 --image=your-image-name --replicas=3

Step 2: Expose the Deployment as ClusterIP

To expose the deployment using ClusterIP:

kubectl expose deployment app1 --type=ClusterIP --port=80 --target-port=80

Step 3: Accessing the ClusterIP Service

Since ClusterIP is only accessible within the cluster, you can create a troubleshooting pod to test the service:

kubectl run troubleshooting --image=troubleshooting-image --restart=Never --command -- /bin/bash

Once inside the troubleshooting pod, you can use curl to access the service:

curl http://app1

Step 4: Expose the Deployment as NodePort

Next, we will expose the deployment using NodePort:

kubectl expose deployment app1 --type=NodePort --port=80 --target-port=80

You can find the assigned NodePort by running:

kubectl get svc

Step 5: Accessing the NodePort Service

You can access the application using the node's IP and the assigned NodePort:

http://<node-ip>:<node-port>

Step 6: Expose the Deployment as LoadBalancer

Finally, to expose the deployment using LoadBalancer:

kubectl expose deployment app1 --type=LoadBalancer --port=80 --target-port=80

Once the LoadBalancer is created, you will receive an external IP that can be used to access the application.

Conclusion

In this post, we explored the different types of Kubernetes services: ClusterIP, NodePort, and LoadBalancer. Each service type serves a unique purpose and is suited for different scenarios. Understanding these services is crucial for deploying applications effectively in Kubernetes.

kubectl create deployment app1 --image kiran2361993/kubegame:v1 --replicas 3 --dry-run -o yaml
echo “<paste yml>” | kubectl apply -f -
kubectl get pods # status of pods replica
kubectl get pods -o wide

kubectl expose deployment app1 --port 80 --target-port 80 --type ClusterIP
kubectl get svc -o wide
curl http://app1
kubectl run troubleshooting --image kiran2361993/troubleshootingtools:v1  #creating a pod to access clusterip deployment
kubectl get pods  # status of troubleshooting pod -> running
kubectl exec -it troubleshooting --bash #login to troubleshooting image

nslookup app1
while true; do curl -sL http://app1 | grep -i 'IP Address'; sleep 1; done # to check loadbalancing
# pin every send to app1 -> to check loadbalancing of ClusterIP

sudo su -
kubectl get pods -o wide # 3 ip of relica set 
kubectl describe svc  # endpoints -> 3 ip add of relica
kubectl get svc -o wide # 3 ip add of relica

kubectl delete deployment.apps app1

# ClusterIP
# 1. do internal communication between micro-services
# 2. do load balancing
kubectl create deployment app1 --image kiran2361993/kubegame:v1 --replicas 3 --dry-run -o yaml
echo “<paste yml>” | kubectl apply -f -
kubectl get pods # status of pods replica
kubectl get pods -o wide

kubectl expose deployment app1 --port 80 --target-port 80 --type NodePort
kubectl get svc -o wide # app1 -> port -> 30907

# control plane -> security group -> inbound rule for the port -> tcp , port(30907) , anywhere(target port)
# <public-ip>:30907 -> open it in browser

kubectl delete svc app1

# NodePort
# expose application to inernet for testing -> port : 3000 - 3200
kubectl expose deployment app1 --port 80 --target-port 80 --type LoadBalancer
kubectl get svc  # app1 -> external ip 

# aws -> load balancer -> new loadbalancer is created by svc
# copy DNS name and attach it to Route53
# so that we can share DNS name to access the app

# LoadBalancer
# expose application to inernet for production
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: app1
  name: app1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: app1
  strategy: {}
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
        - image: kiran2361993/kubegame:v2
          name: kubegame
apiVersion: v1
kind: Service
metadata:
  labels:
    app: app1
  name: app-nlb
  annotations:  # annotations
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enable: "true"
    service.beta.kubernetes.io/aws-load-balancer-connection-draining-enable: "true"
    service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "30"
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: app1
  type: LoadBalancer