Day34 of #90DaysOfDevOps

Working with Services in Kubernetes

What are Services in Kubernetes?

In Kubernetes, Services are responsible for providing stable network access to a group of Pods. Pods can come and go, but Services offer a fixed point of communication that doesn’t change. Services abstract away the dynamic nature of Pods and allow other Pods, external systems, or users to interact with your application.

Types of Services:

  • ClusterIP: Exposes the service internally to the cluster.

  • NodePort: Exposes the service on a static port on each node.

  • LoadBalancer: Exposes the service externally, typically with a cloud provider's load balancer.


Task 1: Create a Service for Your Todo-App Deployment

Let’s start by creating a Service for your todo-app deployment from Day 32. This will allow external clients or other Pods within the cluster to access the application.

Step 1: Create a Service YAML File

Here’s a simple YAML definition for a Service:

apiVersion: v1 # Specifies the Kubernetes API version used in the configuration.
kind: Service # Indicates that this is a Kubernetes Service resource.
metadata: # Contains metadata about the Service.
  name: todo-service # Names the Service as "todo-service".
  namespace: django-app # Specifies the namespace where the Service exists (a logical partition within the cluster).
spec: # Defines the desired state of the Service.
  type: NodePort # Specifies the type of Service. It exposes the Service on each node's IP at a specific static port (NodePort).
  selector: # Defines how the Service identifies the Pods it routes traffic to.
    app: todo-app # Matches Pods with the label app: todo-app.
  ports: # Defines the ports that the Service will listen on and forward traffic to.
    # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
    - port: 80 # Specifies that the Service will listen on port 80.
      targetPort: 8000 # Directs incoming traffic to the Pods' port 8000.
      # Optional field
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30007 # Optionally specifies a static port on each node (30007) for external access. If not specified, Kubernetes assigns a port from a default range (30000-32767).
  • selector: Ensures that traffic is directed to Pods with the label app: todo-app.

  • port: The port exposed by the Service.

  • targetPort: The port on which your application (todo-app) is listening inside the Pod.

Step 2: Apply the Service to Your Kubernetes Cluster

Use the following command to apply the Service definition to your minikube cluster:

kubectl apply -f service.yml -n my-namespace

Step 3: Verify the Service

You can verify that the Service is working by accessing the todo-app using the Service’s NodePort and IP. To find the IP and port, run:

kubectl get service -n my-namespace

Use the displayed IP and port to access the todo-app from your browser or a curl command.


Task 2: Create a ClusterIP Service

The ClusterIP service allows access to the application from within the cluster. This is useful when other Pods or internal systems need to communicate with your todo-app.

Create a ClusterIP Service YAML File

vim cluster-ip-service.yml
-------------------------------------------------------------------------------
apiVersion: v1 # Specifies the Kubernetes API version used in the configuration.
kind: Service # Defines the type of Kubernetes resource, specifically a Service.
metadata: # Contains metadata about the Service.
  name: todo-app-cluster-ip-service # Names the Service as "todo-app-cluster-ip-service".
  namespace: django-app # Specifies the namespace where the Service exists, providing a scope for the Service within the cluster.
spec: # Defines the desired state of the Service.
  type: ClusterIP # Specifies the type of Service as ClusterIP, meaning the Service is only accessible within the cluster.
  selector: # Specifies the criteria for selecting the Pods that the Service will direct traffic to.
    app: todo-app # Matches Pods with the label app: todo-app.
  ports: # Specifies the ports that the Service will use.
  - port: 80 # Defines the port that the Service listens on within the cluster.
    targetPort: 8000 # Routes incoming traffic to the Pods' port 8000, where the application is running.

Apply the ClusterIP Service definition to your K8s (minikube) cluster using this command.

kubectl apply -f cluster-ip-service.yml -n django-app

Verify that the ClusterIP Service is working by accessing the todo-app from another Pod in the cluster in your Namespace.

kubectl get svc -n django-app && kubectl get svc -o wide -n django-app


Task 3: Create a LoadBalancer Service

A LoadBalancer service exposes your application to external users. This is especially useful when your Kubernetes cluster is running on a cloud platform like AWS, GCP, or Azure, but Minikube also supports LoadBalancer services.

Step 1: Create a LoadBalancer Service YAML File

apiVersion: v1
kind: Service
metadata:
  name: todo-app-loadbalancer-service
  namespace: my-namespace
spec:
  selector:
    app: todo-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
  type: LoadBalancer

Step 2: Apply the LoadBalancer Service

To apply the LoadBalancer service, run:

kubectl apply -f load-balancer-service.yml -n my-namespace

Step 3: Verify the LoadBalancer Service

Once the LoadBalancer service is running, it will allocate an external IP address. You can check the external IP by running:

kubectl get service todo-app-loadbalancer-service -n my-namespace

After the external IP is assigned, you can access your todo-app using the LoadBalancer’s IP address.


Conclusion

Today, you explored the three main types of Services in Kubernetes: NodePort, ClusterIP, and LoadBalancer. Each type serves a different purpose, whether you need internal access, external access, or load balancing across your application’s Pods.