A Kubernetes service is a logical abstraction for a group of pods in a cluster (all performing the same function).
Since pods are ephemeral, a service enables a group of pods that provide certain functions (web services, image processing, etc.) to be assigned a name and a unique IP address (clusterIP). As long as the service uses this IP address, it does not change. Services also define policies for their access.
In Kubernetes, a deployment is a way to start a pod of containerized applications and ensure that the required number of replicas are always running on the cluster.
A service, on the other hand, is responsible for exposing an interface to these pods which enables network access either within the cluster or between external processes and the service.
Kubernetes services connect a set of pods to an abstract service name and IP address. Services provide discovery and routing between pods. For example, services connect an application frontend to its backend, each of which running in separate deployments in a cluster. Services use labels and selectors to match pods to other applications.
The key attributes of a Kubernetes service are:
labelselector to locate pods
clusterIP— IP address of the cluster and the assigned port number
- Port definitions
- Optional mapping of incoming ports to a
Services can be defined without pod selectors. For example, to point a service to another service in another namespace or cluster.
ClusterIP. Exposes a service that is only accessible within the cluster.
NodePort. Exposes a service through a static port on the IP of each node.
LoadBalancer. Exposes the service through the cloud provider's load balancer.
ExternalName. Maps a service to a predefined externalName field by returning a value for the CNAME record.
ClusterIP is the default type of service used to expose a service on an IP address within the cluster. It can only be accessed from within the cluster.
Services that do not require load balancing and only expose a single IP address can create a “headless” service by specifying
none as the clusterIP.
Headless services can be defined with selectors, in which case, endpoint records are created in the API that modify the DNS to return addresses that point to pods that are exposing the service. Headless services without selectors do not create endpoint records. The DNS system configures either the CNAME record or a record for endpoints with the same name as the service.
NodePorts are open ports on each cluster node. Kubernetes forwards traffic arriving at a NodePort to the service, even if the service is not running on that node. NodePort is intended to be the foundation for other higher-level ingress methods, such as load balancers, and is useful in development.
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 the service was created.
For clusters running on public cloud providers such as AWS or Azure, creating a LoadBalancer service is an equivalent to a clusterIP service, extending it to an external load balancer specific to the cloud provider. Kubernetes automatically creates the load balancer, provides firewall rules as needed, and populates the service with the external IP address assigned by the cloud provider.
Services simply refer to pods via labels. Since services are not node-specific, a service can point to a pod regardless of where it is running in the cluster at any given time. By exposing a service IP address and DNS service name, the application can be reached either way as long as the service exists.
Services, like all Kubernetes objects, are defined in YAML. Let us say you have deployed pods that run a backend service to process data coming from a web frontend. To release a service named
service-backend on the deployment
deployment-backend, you would use:
apiVersion: v1 kind: Service metadata: name: service-backend spec: ports: - port: 4000 protocol: TCP targetPort: 333 selector: run: deployment-backend type: ClusterIP
The service “service-backend” is created, and any pod in the cluster can access it through its port 333 via
http://service-backend:4000 or through the cluster's IP address via port 4000.
Kubernetes services can also be created using the
kubectl expose command, which does not require a YAML file. The same service can be created with the command:
kubectl expose deployment deployment-backend -–port=333 --target-port=4000 --name=service-backend
There are two ways to discover a Kubernetes service:
- DNS (the most common): the DNS method is the recommended method for discovering services. To use this method, you must first install a DNS server on the cluster. The DNS server monitors the Kubernetes API, and when a new service is created, its name becomes available for easy resolution for requesting applications.
- ENV variable: this method relies on the kubelet to add environment variables for each active service for each node on which a pod is running on.
An abstract way to expose an application running on a set of pods as a network service. With Kubernetes, you do not have to modify your application to use an unfamiliar service discovery mechanism. Kubernetes is capable to give pods their own IP addresses and a single DNS name for a set of pods, and can load balance across them.
This article has been written upon the official k8s documentation and is intended to summarize all the concepts. Author hopes, he accomplished this task.