In the world of Kubernetes, Services are the backbone of networking. there are multiple types of services in Kubernetes
Every Service is different and used for different use cases, In this article I am trying to talk about the Fine-grained details of each service.
If you are a Kubernetes practitioner or beginner there might be some details in this article for you to learn I hope.
This would be a theoretical reference article with no source code or the yaml file references. the objective of this article is to cover the hidden details of each service.
Let's dive in.
What are Kubernetes services?
Kubernetes services are a way to abstract a set of pods and provide a stable endpoint for accessing them.
A service can be thought of as a logical grouping of pods that serve a common purpose. For example, a service might represent a set of backend pods that provide a database service.
A Kubernetes service has an IP address and port, which other pods can use to access the pods associated with the service.
The service acts as a load balancer, distributing traffic evenly among the pods that it represents. This ensures that even if some of the pods fail, the service remains available (failover)
The following image represents how a Kubernetes service works ( most of them - not all of them)
The default service type is cluster ip
and as the name suggests you would get a static CLUSTER IP for the lifetime of the service
the IP address of the Service does not change unless the service is deleted and re-created.
Because this is a Cluster IP, this IP is accessible only from inside the cluster not the outside world.
There are more ways to expose your service to the world like Ingress Controller (or) Load Balancer Service. Either way, you need to map your service to a Network Component such as an Application (Layer 7) or Network ( Layer4) load balancer
Let us learn further which service can be used where and their use cases along with limitations.
Types of Kubernetes Services
Kubernetes provides several types of services to meet different use cases:
- ClusterIP: This is the default type of service in Kubernetes. It provides a stable IP address within the cluster that other pods can use to access the service. This type of service is useful for internal communication within the cluster.
- NodePort: This type of service exposes the service on a static port on each node's IP address. It is useful when you need to access the service from outside the cluster.
- LoadBalancer: This type of service exposes the service on an external load balancer. This is useful when you need to distribute traffic across multiple nodes.
- ExternalName: This type of service maps the service to an external name that is outside the Kubernetes cluster. This is useful when you need to access an external service that is not running inside the cluster.
Discovering and Connecting to Service
Every Service in Kubernetes has a DNS entry in the svc.cluster.local subdomain of Kubernetes
When you are trying to reach the service which is present on the same namespace. you can simply refer to it by the name like testservice
When you want to refer a service from another namespace, you have to use the fully qualified URL like testservice.mynamespace.svc.cluster.local
As we have seen when you try to DNS LOOKUP the service you would get a single IP which abstracts the actual POD IPs. As pods are ephemeral in nature having a Static service level IP does not get affected if the pod count increase or decreases change
But it's not always this way. In cases where you want to expose your POD IP instead of a Single Static IP. You can set ClusterIP: None
it while creating a service and your service would become a Headless service
We have an exclusive article on Headless service you can refer
In the following diagram, you can find the difference between Normal Cluster IP service vs Headless service
Kubernetes services - A Deep Dive
Let's explore these Kubernetes services briefly and understand how they work and what they are used for.
ClusterIP service
This is the default type of Kubernetes service, this creates a Cluster IP which can be used internally.
With this service type, we can make a set of pods available behind a single cluster IP or service DNS name with Load Balancing and failover
As we have learnt already you can discover all the services with their name or with the subdomainsvc.cluster.local
and their corresponding name
this service is mostly used to expose a set of pods to the other pods within the cluster.
Imagine you have an application with a following tech stack
- Nginx - Reverse Proxy
- NodeJS - Backend Application Server
- MySQL - Database
when all of these services are hosted on the same cluster they can refer and connect to each other using their names or by the FQDN
In the preceding diagram, you can see that nginx PODS are connecting to nodejs pods using nodejs service and nodejs pods connecting to SQL pods using MySQL service
we have used only cluster IP service for this implementation as all these communications are happening within the cluster
Now what if we want to expose our services to the public? there are other service types to do that for us.
NodePort service
In the previous Cluster IP
service type, we have learnt how to create a load balancing and failover and publish pods as a service internally
Now let us go further and learn how to expose our service to the world
When you set your service as NodePort service, Kubernetes creates a Port for that service in all available worker nodes.
yes, you read it right, It blocks that Port on all the worker nodes. but why on all nodes? you might wonder
During the lifecycle of the POD, a POD can be reassigned to any node.
Let's suppose Kubernetes reserves the node port only on the selected nodes and the pod gets re-assigned during the lifecycle. The service has to manually create a node port at that time which might create downtime and there is no guarantee that the port being available on demand.
Since the NodePorts are reserved in all the nodes, You can access the service through any node as long as you have the NodePort right ( Irrespective of the IP changes)
Let me explain this with a quick diagram
The NodePort range is controlled by the Kubernetes Controller flag --service-node-port-range
(default: 30000-32767). but the range can be extended further
Additionally, Your Node Port service can be accessed directly by accessing the Node IP and Port combination as well as Internal Cluster IP
Let's say you want temporarily give access to a developer without having to create a Load Balancer or Ingress you can do that by sharing the Node IP and the Port
As long as your Security Group is permissive the service would work fine
http://node_ip:node_port - works on the Subnet (as long as the security group is permitting) http://cluster-internal-ip:node_port - works only inside the cluster
When the node is evicted or removed from the cluster for a reason. the Node IP and Port might not be useful. that's another reason we have the NodePort created on all the available Nodes in the cluster.
LoadBalancer service
This is an extension of the Node Port type. while the Node Port service opens the Port in all the nodes and does 50% of the job in making the service available through the external clients through Load Balancer or ingress
This Load Balancer type of service goes one step above and creates the Load Balancer itself using the underlying Cloud infrastructure like AWS, GCP or Azure
Created Load Balancer would be redirecting the calls to the node port created by this type of service
In GKE, you would get a static IP for the Load Balancer type of service which is a public IP which can be mapped to any Domain Name as A record
in your DNS
In AWS EKS, you would get a domain name like *elb.amazonaws.com
for your load balancer type of service which you can map to any Domain Name with CNAME
record
I have covered this Load Balancer
type of service in detail on an exclusive article please refer
AWS EKS Load Balancer from Kubernetes Service | Devops Junction
ExternalName service
The ExternalName type of Kubernetes service is to create an internal service reference or an alias service for any external world APIs and services
Let's say you are using multiple API vendors, One for Billing, One For ESignature another for Email notification
Instead of referring their URL explicitly inside our code and environment, you create an internal reference for the external endpoint ( like CNAME in DNS)
Instead of using api.v3.sendgrid.com
you can use mailservice.svc.cluster.local
This enables you to abstract the vendor name inside the configuration and also reduces the code changes if you have to replace the vendor in future. for example, SendGrid to mailgun
you can think external service is an internal CNAME entry for your external service
Hope the following image represents this clearly
As shown in the preceding illustration, you can see we are creating an alias service for all the vendor services with the name matching the business use case
Conclusion
In this article, I have tried to cover the finer details of Kubernetes services and their use cases with nice illustrations.
Hope you have learnt something new if you already know the services or were introduced well to the Kubernetes services.
Let me know in the comments section if you would like me to cover anything more in detail with examples. feedback welcome.
Cheers
Sarav
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content