DEV Community

Subham Nandi
Subham Nandi

Posted on

40 Days Of Kubernetes (9/40)

GitHub link - https://github.com/SUBHAM-NANDI/40DaysKubernetes/blob/main/Day%209/Readme.md

Kubernetes Services Explained: ClusterIP, NodePort, LoadBalancer and External

1. Introduction to Kubernetes Services

Kubernetes services define a logical set of pods and provide a reliable mechanism to access them, regardless of pod IP changes. Services act as an abstraction layer over individual pods and enable communication both within and outside the cluster.

Key Concept: What is a Kubernetes Service?

A Kubernetes service is an abstraction that groups pods with specific labels and provides a consistent interface to access them. Without services, communication between pods would be challenging due to dynamic IP changes each time pods are restarted or rescheduled.

2. Problem Definition

Let’s consider a deployment of four nginx pods serving a frontend application. While these pods are accessible internally within the Kubernetes cluster, they are not exposed to external users. Our goal is to make this application accessible externally using Kubernetes services.


3. Types of Kubernetes Services

1. ClusterIP: For Internal Communication

The ClusterIP service is the default Kubernetes service type. It creates an internal IP within the cluster that is accessible only to other services or pods inside the cluster. This makes it ideal for service-to-service communication.

Example Use Case: Internal Pod Communication

In a scenario where a frontend application needs to communicate with a backend or database service, a ClusterIP can ensure stable communication without worrying about changing pod IPs. For instance, a frontend pod running Nginx may need to communicate with backend pods running Node.js or database pods running MySQL.

Key Benefit: Pods don't need to rely on dynamic IP addresses; they can access services through a consistent ClusterIP.

ClusterIP Service YAML Example

Here is how you can define a simple ClusterIP service in Kubernetes:

apiVersion: v1
kind: Service
metadata:
  name: cluster-svc
spec:
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • selector: This matches the backend pods using the label app: backend.
  • port: Defines the port on which the service will be exposed internally.
  • targetPort: Refers to the port where the backend application (Node.js) is running inside the pod.

Deploying a ClusterIP Service

  1. Apply the Service:
   kubectl apply -f cluster-ip.yaml
Enter fullscreen mode Exit fullscreen mode
  1. Verify the Service:
   kubectl get svc
Enter fullscreen mode Exit fullscreen mode

Once created, your frontend pods can now use the service name (cluster-svc) to access the backend service reliably.


2. NodePort: Exposing Services Outside the Cluster

The NodePort service type allows applications to be accessed externally by assigning a specific port (between 30,000-32,767) on each node in the Kubernetes cluster. External users can access services via NodeIP:NodePort.

Example Use Case: External Communication

Consider a scenario where you want users to access your frontend application externally without using a load balancer. By setting up a NodePort, the service will be accessible via a specific port on the cluster nodes.

NodePort Service YAML Example

Here is how you can define a NodePort service:

apiVersion: v1
kind: Service
metadata:
  name: nodeport-svc
  labels:
    env: demo
spec:
  type: NodePort
  selector:
    env: demo
  ports:
  - nodePort: 30001
    port: 80
    targetPort: 80
    nodePort: 30001
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • type: NodePort: This specifies that the service will be accessible via a node port.
  • selector: Matches the pods with the label env: demo.
  • port: Defines the internal port (80) where the service is available.
  • nodePort: Assigns a fixed external port (30001) through which the service will be accessible outside the cluster.

Deploying a NodePort Service

  1. Apply the Service:
   kubectl apply -f nodeport.yaml
Enter fullscreen mode Exit fullscreen mode
  1. Verify the Service:
   kubectl get svc
Enter fullscreen mode Exit fullscreen mode

Once created, you can access your service externally using http://<Node-IP>:30001.

Special Case: Using NodePort with Kind Cluster

If you're using Kind (Kubernetes in Docker), the NodePort services are not automatically accessible externally due to Kind's internal network structure. To solve this, you must map the NodePort to your local machine using port mapping in the Kind configuration.

Example Kind Cluster Configuration for Port Mapping:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30001
        hostPort: 30001
        protocol: TCP
Enter fullscreen mode Exit fullscreen mode

After configuring this file, you will need to recreate the Kind cluster:

  1. Delete the existing cluster:
   kind delete cluster --name <your-cluster-name>
Enter fullscreen mode Exit fullscreen mode
  1. Create a new cluster with the updated configuration:
   kind create cluster --config kind-config.yaml --name <your-cluster-name>
Enter fullscreen mode Exit fullscreen mode

You can then access your service locally using localhost:30001.


3. LoadBalancer: Production-Level Scaling for External Traffic

The LoadBalancer service type is commonly used in cloud environments (such as AWS, GCP, Azure) to distribute traffic to multiple backend pods. It automatically provisions a cloud provider's load balancer, assigns a public IP, and routes external traffic to the application.

Example Use Case: Scaling for External Traffic

In a production environment, you may have multiple backend pods running your application. A LoadBalancer service allows you to evenly distribute incoming traffic across these pods, ensuring high availability and fault tolerance.

LoadBalancer Service YAML Example

Here’s a sample YAML file for creating a LoadBalancer service:

apiVersion: v1
kind: Service
metadata:
  name: lb-svc
spec:
  type: LoadBalancer
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • type: LoadBalancer: Specifies that a cloud provider's load balancer should be used.
  • selector: Matches the backend pods with the label app: backend.
  • port: Exposes the service on port 80 externally.
  • targetPort: Refers to the internal application port (80).

Deploying a LoadBalancer Service

  1. Apply the Service:
   kubectl apply -f lb.yaml
Enter fullscreen mode Exit fullscreen mode
  1. Check for the External IP:
   kubectl get svc
Enter fullscreen mode Exit fullscreen mode

Once the service is created, an external IP will be provisioned by the cloud provider. You can use this IP to access the service externally.


4. ExternalName: Mapping Services to External DNS

The ExternalName service type maps an internal Kubernetes service to an external DNS name. This can be useful when you want to access external resources, such as a database hosted outside your Kubernetes cluster, through Kubernetes services.

Example: Mapping to an External Database

Here is an example of creating an ExternalName service that maps to an external database:

apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com
Enter fullscreen mode Exit fullscreen mode

Once this service is applied, any internal application that needs to access the external database can use external-db as the hostname, which resolves to db.example.com.


Top comments (0)