Exploring Kubernetes Services: ClusterIP, NodePort, LoadBalancer, and ExternalName

SHRIRAM SAHUSHRIRAM SAHU
5 min read

Welcome to Day 9 of #40DaysOfKubernetes! Today, we delved into the world of Kubernetes services, understanding how they enable communication between various components within a cluster. We also explored different service types, each serving unique purposes in managing network traffic.

What is a Kubernetes Service?

A Kubernetes Service is an abstraction that defines a logical set of pods and a policy by which to access them. Services enable loose coupling between dependent services, providing a stable endpoint (IP and port) for clients, even as the underlying pods are created and destroyed.

Types of Kubernetes Services

1. ClusterIP

  • Description: The default service type, ClusterIP, exposes the service on an internal IP in the cluster. This makes the service accessible only within the cluster.

  • Use Case: Ideal for communication between pods within the same cluster.

  • Command Example:

      apiVersion: v1
      kind: Service
      metadata:
        name: cluster-svc
        labels:
          env: demo
      spec:
        type: ClusterIP
        ports:
        - port: 80
          targetPort: 80
        selector:
          env: demo
    

2. NodePort

  • Description: NodePort exposes the service on each node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service routes, is automatically created.

  • Use Case: Useful for exposing services to external traffic.

  • Command Example:

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

3. LoadBalancer

  • Description: LoadBalancer exposes the service externally using a cloud provider’s load balancer. The external load balancer routes traffic to your service.

  • Use Case: Ideal for services that need to be accessible from the internet.

  • Command Example:

      apiVersion: v1
      kind: Service
      metadata:
        name: lb-svc
        labels:
          env: demo
      spec:
        type: LoadBalancer
        ports:
        - port: 80
        selector:
          env: demo
    

4. ExternalName

  • Description: ExternalName maps a service to a DNS name. It returns a CNAME record with the provided name, without using a proxy.

  • Use Case: Useful for integrating external services.

  • Command Example:

      apiVersion: v1
      kind: Service
      metadata:
        name: my-externalname-service
      spec:
        type: ExternalName
        externalName: my.database.example.com
    

Additional Information

Each Service type serves different networking needs within Kubernetes, allowing flexibility in how applications are exposed and accessed both internally and externally. Understanding these types helps in designing robust and scalable Kubernetes applications.


Hands-on Tasks

  1. Create a Service named myapp of type ClusterIP that exposes port 80 and maps to the target port 80.

     apiVersion: v1
     kind: Service
     metadata:
       name: cluster-svc
       labels:
         app: myapp
     spec:
       type: ClusterIP
       ports:
       - port: 80
         targetPort: 80
       selector:
         app: myapp
    

    Apply the configuration:

     kubectl apply -f myapp.yaml
    

  2. Create a Deployment named myapp that creates 1 replica running the image nginx:1.23.4-alpine. Expose the container port 80.

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: myapp
       labels:
         app: myapp
     spec:
       template:
         metadata:
           labels:
             app: myapp
         spec:
           containers:
           - image: nginx:1.23.4-alpine
             name: nginx
             ports:
             - containerPort: 80
       replicas: 1
       selector:
         matchLabels:
           app: myapp
    

    Apply the configuration:

     kubectl apply -f myapp-dep.yaml
    

  3. Scale the Deployment to 2 replicas:

     kubectl scale deploy myapp --replicas=2
    

  4. Create a temporary Pod using the image busybox and run a wget command against the IP of the service:

     kubectl run busybox --image=busybox --rm -it -- wget -O- http://myapp
    
  5. Run a wget command against the service outside the cluster:

    • First, expose the service using NodePort:

        apiVersion: v1
        kind: Service
        metadata:
          name: myapp-nodeport
          labels:
            app: myapp
        spec:
          type: NodePort
          ports:
          - nodePort: 30001
            port: 80
            targetPort: 80
          selector:
            app: myapp
      

      Apply the configuration:

        kubectl apply -f myapp-nodeport.yaml
      

    • Then, get the external IP of your node and run:

        wget -O- http://<NodeIP>:30001
      

  6. Change the service type so the Pods can be reached outside the cluster:

    • Change the service type to LoadBalancer:

        apiVersion: v1
        kind: Service
        metadata:
          name: myapp-loadbalancer
          labels:
            app: myapp
        spec:
          type: LoadBalancer
          ports:
          - port: 80
          selector:
            app: myapp
      

      Apply the configuration:

        kubectl apply -f myapp-lb.yaml
      
  7. Run a wget command against the service outside the cluster:

    • Get the external IP of your load balancer and run:

        wget -O- http://<LoadBalancerIP>
      

Discussion

  • Can you expose the Pods as a service without a deployment? Yes, you can create a Service that targets standalone Pods by using labels to select the Pods directly. However, this is not recommended for production environments because Deployments provide better management, scalability, and updates.

  • Under what condition would you use the service types LoadBalancer, NodePort, ClusterIP, and ExternalName?

    • LoadBalancer: Use when you need to expose your service to the internet. Ideal for production workloads in cloud environments.

    • NodePort: Use for exposing services for external access when LoadBalancer is not available, usually in development or testing environments.

    • ClusterIP: The default type for internal cluster communication. Use for services that only need to be accessed within the cluster.

    • ExternalName: Use for services that need to map to an external DNS name, useful for integrating external services without using a proxy.


Conclusion

Understanding Kubernetes services and their types is crucial for managing network traffic and ensuring seamless communication within your cluster. By mastering these concepts, you can efficiently expose your applications and integrate external services, enhancing the robustness of your Kubernetes environment.


Reference Section

10
Subscribe to my newsletter

Read articles from SHRIRAM SAHU directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SHRIRAM SAHU
SHRIRAM SAHU