Need for Services
Each pod gets its own IP address. However, pods in Kubernetes are ephemeral; meaning they are created and destroyed very quickly to match the state of the cluster. When a pod dies, a new pod is created in its place. Every time a new pod is started, it gets a new IP address. This leads to a problem. The client which is communicating with this pod has to keep track of its IP addresses. This is highly inefficient. To tackle this issue we use Services. Services provide consistent and stable IP address. We put a service in front of a pod and access it through the service. Now that this service has a permanent static IP address, we no longer have to keep track of pod's IP addresses.
Features of Services
Stable IP Address
The IP Address of a service stays the same even if the pod dies. We no longer have to worry about adjusting IP address whenever a pod dies or restarts.
Load Balancing
Service will also act as load balancer to your replicas. When a client sends a request to the service, the service will intelligently forward the request to one of the available replica pods which is best equipped to handle the incoming request.
Loose coupling
In a microservice architecture, each application is decoupled. Services can also handle communications within the cluster between these decoupled applications.
Types of Services
Simply put, a service points to pods. It is a component in Kubernetes just like a pod but its not a process. It is just an abstraction layer that basically represents an IP Address. There are following types of services -
ClusterIP
This is the default type. A service of type ClusterIP is accessible only within the cluster. We could use this type of service for a database pod which should only be accessed by internal applications and not outside world.
NodePort
A service of type NodePort will expose a port on every worker nodes to the external traffic; meaning the outside world can access worker nodes on that port. The port is specified by nodePort attribute in the configuration file. The value of nodePort should be in the range 30000-32767. Anything outside this range is not allowed. NodePort is not secured and should be used only for development purpose.
LoadBalancer
For public cloud providers like GCP, AWS a service of type LoadBalancer is accessible only through the load balancer of cloud providers. External traffic must first come to the cloud providers' load balancer and after firewall rules and other logic, the load balancer will route the traffic to this service.
ExternalName
ExternalName services are similar to other Kubernetes services; however, instead of being accessed via a clusterIP address, it returns a CNAME record with a value that is defined in the externalName: parameter when creating the service.
Headless
A service points to a group of pods called replicas. Suppose we want to communicate with 1 specific pod like in the case of stateful applications e.g. database where pod replicas are not identical. To achieve this we use headless service. A headless service is defined by setting clusterIP to None in service configuration file. A headless service will return the address of pod which it is pointing to.
Creating a service
A basic configuration file for creating a service will look like this -
apiVersion: v1
kind: Service
metadata:
name: myapp-service
labels:
app: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 6000
type: ClusterIP
All the pods that match the key value pair provided by spec.selector
are part of the service. Service will map the incoming request on port 80 to the port 6000 on the pod. This is specified by spec.ports.port
and spec.ports.targetPort
respectively.