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
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.
Understand Service Types: Each Service type has its use cases. Choose the type that aligns best with your requirements.
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.
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.