Pods have their own unique IP addresses but these IP addresses are not reliable (if a Pod get rescheduled it might get a new IP address).
For a large deployment, it will hard to maintain and keep updated a list of all these IP addresses,.
Kubernetes provides a solution that makes accessing the Pods easier and reliable.
The Kubernetes Service is a special object that regroup a set of related Pods.
A Kubernetes Service has a unique IP address (ClusterIP), DNS name, and Port that last for the life of the service.
The Kubernetes Service load balance requests across its associated Pods.
Kubernetes Service uses the Kubernetes Endpoints object (endpoints|ep) to manage Pods.
For each service, an associated EndPoints object (endpoints|ep) will be created.
This object will keep updated the list of all the Pods that their labels match the Service's selector.
Pods (coming from new deployment, scaling up an existing deployment) that their labels match the Service's label selector, will dynamically be added the Endpoints object.
If a Pod get updated (labels), become unhealthy (failure), or terminated (an existing deployment get deleted or rolled back), it will be removed from the Endpoints object.
The EndPoints object will have the name of the Service.
Linking Pods to a Service using labels and label selectors allow Pods to be loosely coupled with the Service.
To be selected, a pod must define all the labels defined in the Service's label selector.
A Pod can define more labels than the one defined in the Service's selector.
The Service object allow you to specify the type (.spec.type) of the Service you want.
The possible values of the .spec.type field are:
-
ClusterIP (default):
The Service (unique IP address, DNS name, and Port) will be, by default, only available within the cluster.
-
NodePort:
Superset of ClusterIP.
It also exposes a node port (TCP/UDP) that allow the Service to be available from outside the cluster.
-
LoadBalancer:
Superset of NodePort.
If supported, It creates an external load balancer in the cloud provider and assigns an external IP address to the Service.
-
ExternalName:
Can be used when there's need to direct requests to applications running outside the Kubernetes cluster.
"Headless" Service (.spec.clusterIP set to None) is a special case of the ClusterIP Service.
A query to the Service will return the Pods' IP addresses (no load balancing).
Statefulset is a known use case where "Headless" Services are used.
To create/deploy a Service, you need first to create a manifest YAML file.
The manifest file describe the Service and its components (name, type, Ports, Selector, ...).
You can use kubectl (or any rest client tool) to post the manifest file to the API server
(same behaviour if you use the imperative command to create the Service via the "kubectl create" command).
If applicable, the API server verifies that the request is authenticated, validates it's authorized, and runs the admission controllers on it.
The API server verifies the manifest file and, if no issues, it writes a record for that manifest in the cluster store (etcd).
The scheduler will then read the record and deploy the Pod of the Service to a healthy worker(s) node(s) with enough available resources.