Exploring Services in Kubernetes

Welcome to day 33 of the #90DaysOfDevOps challenge initiated by Shubham Londhe . In today's blog post, we'll dive into What are Services in K8s, why do we need services? We will launch the k8s cluster through #kubeadm. Let's get started!

  • Services distribute incoming network traffic across multiple Pods that are part of the Service.

  • Services have a stable DNS name and IP address that can be used by other components within the cluster to access the Pods.

  • When scaling the number of Pods or performing rolling updates, the Service automatically adjusts the routing of traffic to the available Pods.

  • Services can be used for internal communication between different components within the cluster.

  • Services can be configured to expose applications externally, allowing access from outside the cluster.

Types of services in Kubernetes:

  1. ClusterIP Service

  2. NodePort Service

  3. LoadBalancer Service

  4. ExternalName Service (This type of service is used to provide DNS aliases to external services)

We will discuss a few of the above-mentioned services.

This is the default service type in Kubernetes. It creates a virtual IP address within the cluster to access the pods that are part of the service.

ClusterIP services expose a set of pods in a K8s cluster to the other pods in the same cluster using a virtual IP address.

A common practical use case for ClusterIP service would be when a web application consists of a backend API service and a frontend service. The frontend service can access the backend API service which can be exposed as a ClusterIP service. The backend pods are not directly accessible from outside the Kubernetes cluster, but they can be accessed by the frontend pods that are running in the same cluster.

So, the ClusterIP will provide access to an application within a Kubernetes cluster but without access from the world, and will use an IP from the cluster’s IP pool and will be accessible via a DNS name in the cluster’s scope.

We will be working in the namespace, we will create as follows

kubectl create namespace django-todo-app-ns
kubectl get namespaces

Update the deployment file.

Let's create a ClusterIP service in k8s, which is the default service type in k8s.

Create a manifest file named django-service.yml. To know about the API version, you can use command as follow

apiVersion: v1
kind: Service
metadata:
    name: django-service-clusterip
    namespace: django-todo-app-ns
spec:
    type: ClusterIP
    selector:
         app: django-todo-app
    ports:
      - protocol: TCP
        name: http
        port: 8000
        targetPort: 8000

Let's apply this ClusterIP to the k8s cluster. Also, check the service created using the 'kubectl get svc' command.

kubectl apply -f django-service.yml -n <namespace>
kubectl get svc -n <namespace>

Now let's try accessing the application internally. First, Connect to any of the pods using the following command:

kubectl exec -it <Pod_name> bash -n <namespace>

Let's create another Pod to test the service in the same namespace.

apiVersion: v1
kind: Pod
metadata:
    name: pod-test
    namespace: django-todo-app-ns
spec:
    containers:
          - name: busybox
            image: busybox
            command: ['sh', '-c', 'while true; do wget -q -O- my-django-app-cluster-ip:8000; done']

Apply this pod.yml to the k8s cluster. Along with this, I have opened port 10250 for the pod to be accessible.

kubectl apply -f test-pod.yml -n django-todo-app-ns

You can check all the pods present in this namespace.

Get into the pod using the following command:

kubectl exec -it pod-test -n django-todo-app-ns -- sh

Check the application connectivity inside the pod using clusterIP and port.

wget -qO- http://<clusterIP>:<Port>

And yay! The application is accessible. The ClusterIP service is successfully working in the k8s cluster.

A NodePort service is a type of Kubernetes service that allows access to a set of pods running on a cluster from outside the cluster. It exposes the pods to the outside world by opening a specific port on all the nodes of the cluster.

This type of service exposes the container to the outside world by mapping a static port on the worker node(s) to the pod. This is useful for testing or accessing a service from outside the cluster.

When a NodePort is created, K8s assigns a random port number (between 30000 and 32767 by default) on each node in the cluster. The service can then be accessed using the IP address of any node in the cluster and the assigned port number.

The NodePort type is: tied to a specific host like ЕС2, if the host isn’t available from the world – then such a Service will not provide external access to pods, and will use an IP from a provider’s pool, for example, AWS VPC CIDR, and will provide access to pods only on the same Worker Node.

A practical example is, NodePort Service can be used to expose a web application to the internet.

Here in this task, we will use the service NodePort.

In the NodePort service type, the K8s control plane allocates a port range from 30000-32767.

Let's create a service named service.yml.

vim django-service.yml

In the text editor, write the following:

apiVersion: v1
kind: Service
metadata:
    name: django-service
    namespace: django-todo-app-ns
spec:
    type: NodePort
    selector:
         app: django-todo-app
    ports:
      - protocol: TCP
        port: 80
        targetPort: 8000
        nodePort: 30008

Save and exit the editor.

Now let's apply this service to the K8s cluster using the:

kubectl apply -f django-service.yml -n django-todo-app-ns

Let's verify if the service is created:

kubectl get svc -n=django-todo-app-ns

To access the pod outside, we would need port 30008 open to the external world. So edit the inbound rules of the worker node.

Verify if the ToDo application is accessible using the node Public IP and the port you just opened.

And yes, the website is accessible! Yay!

A LoadBalancer service is a type of Kubernetes service that provides external network access to a set of pods running on a cluster. It creates a load balancer that distributes incoming traffic across multiple backend pods, providing scalability and high availability for the application.

When you create a LoadBalancer service, Kubernetes creates a cloud load balancer (if you are running on a cloud provider) or a software load balancer (if you are running on-premises) that distributes traffic across the pods in the service. The load balancer provides a stable IP address that external clients can use to connect to the service.

So, the LoadBalancer Service type will provide external access to pods, will provide a basic load-balancing to pods on different EC2, will give the ability to terminate SSL/TLS sessions, and doesn’t support level-7 routing.

It can be used to distribute traffic across a set of pods running a web application or a backend API service, for example.

Create a load-balancer-service.yml file.

apiVersion: v1
kind: Service
metadata:
      name: loadbalacer-service
      namespace: django-todo-app-ns
spec:
     selector:
      app: django-todo-app
     ports:
        - port: 80
          targetPort: 8000
     type: LoadBalancer

Let's apply this service to the k8s cluster and verify if the service is created using the:

kubectl apply -f load-balancer-service.yml -n django-todo-app-ns
kubectl get svc -n django-todo-app-ns

Copy the port that is exposed for the load balancer and edit the inbound rules for your EC2 instance.

Connect to the application in your web browser using node-PublicIP: load balancer-port.

And yesss! The application is connected via the port that is exposed through the load balancer service.

Kubernetes networking is the process of enabling communication between the various components of a Kubernetes cluster. It involves configuring networking resources such as pods, services, and ingress to allow traffic to flow between them.

Kubernetes has fundamental requirements for networking implementations:

  1. Pods should be able to communicate with other pods on other nodes also without NAT.

  2. Agents on the node should be able to communicate with all the pods on that node.

In Kubernetes, each pod gets its IP address, and services act as a stable endpoint for accessing a set of pods. This allows for load balancing and automatic scaling of application traffic.

In addition, Kubernetes provides network policies that allow for fine-grained control over traffic flow between pods.

In this blog, I have discussed different types of services in Kubernetes and how to create and manage them in this blog. If you have any questions or would like to share your experiences, feel free to leave a comment below. Don't forget to read my blogs and connect with me on LinkedIn and let's have a conversation.

In the next blog post, we will explore more advanced topics in the realm of DevOps. Also, I will be deploying projects using K8s. So, stay tuned and let me know if there is any correction.