Working with Services in Kubernetes

Working with Services in Kubernetes

What are Kubernetes Services?

In Kubernetes, Services are objects that provide stable network identities to Pods and abstract away the details of Pod IP addresses. Services allow Pods to receive traffic from other Pods, Services, and external clients.

When you deploy applications on Kubernetes, they usually run inside Pods. While each Pod has its own IP address, these addresses are ephemeral and might change when the Pod restarts. This poses a challenge when other applications or external clients want to consistently and reliably communicate with a specific application. Enter Kubernetes Services.

A Service in Kubernetes is a stable endpoint for Pods. It abstracts the actual Pod IPs and provides a single IP address (and a DNS name) to access the application, regardless of which underlying Pod is serving the request.

Types of Kubernetes Services

ClusterIP (default):

This creates a virtual IP inside the cluster to enable communication between different services, such as between a frontend and a backend. This type of Service is only reachable within the cluster.

Real-time example: Consider a multi-tier application where the front-end communicates with a backend API. The backend API can be exposed as a ClusterIP Service since it only needs to be accessible internally by the front-end.

Create a file clusterip-services.yml

apiVersion: v1
kind: Service
metadata:
  name: backend-api
spec:
  selector:
    app: backend-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP

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

kubectl apply -f clusterip-services.yml

Get the service details using the below command

kubectl get services

NodePort:

In addition to having an internal ClusterIP, a NodePort service opens a specific port on every Node and forwards traffic to that port to the Service. This makes it accessible from outside the cluster.

Real-time example: Imagine a small-scale testing environment where developers need to access a particular application running in the cluster directly. Instead of setting up an external load balancer, they could use the NodePort service to reach the application.

Create a file nodeport-services.yml

apiVersion: v1
kind: Service
metadata:
  name: test-app
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30080
  type: NodePort
kubectl apply -f nodeport-services.yml
kubectl get services test-app

LoadBalancer:

This provisions an external IP to act as a load balancer for the service. Traffic coming to that external IP will be distributed to the Pods of the Service. Most cloud providers offer this service as an integration with their own load balancer products.

Real-time example: A SaaS company has a customer-facing application. This application is containerized and hosted on a Kubernetes cluster in a cloud environment (e.g., AWS, Azure, GCP). They would use a LoadBalancer Service type to expose the application to their users. The cloud provider automatically provisions and configures the required load balancer resources.

Create a file loadbalancer-services.yml

apiVersion: v1
kind: Service
metadata:
  name: customer-app
spec:
  selector:
    app: saas-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer
kubectl apply -f loadbalancer-services.yml
kubectl get services customer-app

ExternalName:

Instead of providing internal IP or routing mechanisms, this maps a Service to a DNS name. It's useful when you need to address an external resource but want to treat it as an internal one.

Real-time example: Suppose you have a database hosted outside your Kubernetes cluster on a platform like Amazon RDS. Instead of managing IP references, you could use an ExternalName Service to point your in-cluster applications to the external database using its DNS name.

Create a file externalname-services.yml

apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: my-database.example.com
kubectl apply -f externalname-services.yml
kubectl get services external-db

Working with Services- Some extra dose!

Creating a Service

To create a Service, you'll need a YAML definition. Here's an example for a NodePort Service:

apiVersion: v1
kind: Service
metadata:
  name: my-nodeport-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30080
  type: NodePort

You can apply this with

kubectl apply -f services.yml

Listing and Describing Services

To list all services in the current namespace:

kubectl get services

To describe a specific service and get detailed information:

kubectl describe service my-nodeport-service

Deleting a Service

To delete a service:

kubectl delete service my-nodeport-service

Best Practices

  1. Use Labels and Selectors: Labels and selectors are the mechanism by which Services select which Pods to expose. Ensure you use clear and descriptive labels.

  2. Understand Service Types: Each Service type has its use cases. Choose the type that aligns best with your requirements.

  3. Security: If using NodePort or LoadBalancer, be aware that these types expose your application externally. Ensure you have adequate security measures, like firewalls or Network Policies, in place.

  4. Use DNS Names: Kubernetes provides DNS resolution for Services out of the box. Make use of these names for inter-service communication.

Conclusion

Kubernetes Services offers a robust way to expose and manage access to the applications running inside Pods. They form the backbone of application communication in a Kubernetes cluster. By understanding and effectively utilizing Services, you can ensure seamless and reliable connectivity for your applications.

Thanks For Reading! ๐Ÿ™๐Ÿ˜ƒ

ย