Open In App

What are Kubernetes Services? | Complete Guide

Last Updated : 28 May, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In Kubernetes, each pod is assigned its IP address but the pods are ephemeral that is they can be destroyed easily and when a new pod is created in place of them a new IP address is assigned to them. Here the role of services comes into the picture. A service is like a permanent IP address assigned to a pod. A service IP address is stable. So instead of sending a request to a pod, the client requests a service, and the service forwards that request to the desired pod. Services also help in load-balancing.

What Are Services in Kubernetes?

Service in Kubernetes will expose the application which is running in the pods to the internet. Each service will have its own set of endpoints from where they can be accessed from the internet.

For example, if you deployed a web application in the Kubernetes cluster with five replicas then you can access the five replicas with a single URL. The traffic will be routed to all the pods based on their incoming traffic. You can use ingress control to control the incoming traffic.

How do Kubernetes Service Work?

Kubernetes services act as an abstraction layer that exposes the applications in the running pods to other services or external clients. They provide a stable endpoint and load balancing features for accessing pods within a kubernetes cluster. It provides a seamless communication between different parts of an application. Kubernetes services use labels and selectors for dynamically routing the traffic to the appropriate pods. It ensure high availability and reliability to the application.

kubernetes Service works

How do You Define A Kubernetes Service?

In the kubernetes cluster, there are no.of objects which are having there own use cases and individual advantages. Same way service is part of objects which are present in kubernetes. To create an object or operate an object you can use the kubectl tool.

Example

apiVersion: v1
kind: Service
metadata:
name: deployment-service
spec:
selector:
Tomcat: deploymentapp
ports:
- protocol: TCP
port: 80
targetPort: 8080

In the above we are exposing the Tomcat application deployed in the kubernetes cluster with labels of Tomcat: deployment app port: 80 is the port exposed internally in the cluster and port 8080 is the port of the Tomcat application.

Port Definitions

In the kubernetes service, there is one section called targetPort in the nodePort service instead of using the port number you can directly use the name of the pods.

Example

kind: Pod
metadata:
name: tomcat
labels:
deployemnt: deployemnet-java
spec:
containers:
- name: tomcat
image: tomact:latest
ports:
- containerPort: 8080
name: http-deplyment-port

---
apiVersion: v1
kind: Service
metadata:
name:tomcat-service
spec:
selector:
deployemnt: deployemnet-java
ports:
- name: name-of-service-port
protocol: TCP
port: 80
targetPort:http-deplyment-port

For example, we can see that instead of using the "targetPortnumber" you can use the name of the container as mentioned below. The target port is the port number that the service or pod is forwarding requests to.

Services Without Selectors

This type of service will be exposed to all the pods in the kubernetes cluster. If the service is having selectors then that service will be exposed to only certain pods in the kubernetes cluster. We can use this special case of pods for different situations as the following:

Example

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 8080

You can map the service to the required object by using the network address and port with the help of the Endpoint slice object manually.

EndpointSlices

EndpontSlices are the object available in the kubernetes cluster from Kubernetes v1.21 [stable]. Endpontslice main function is to break endpoints into smaller manageable segments. The limit of pods that can find in each endpoint slice was 100 pods. The new endpoint slice will be created only when the Endpointslice is filled up with 100 endpoints.

Custom EndpointSlices

The custom name can be given to endpoint slices when you create a new endpoint slice. By using the following EndpointSlices you can create custom Endpoint Slices.

Example

apiVersion: discovery.k8s.io/v1beta1
kind: EndpointSlice
metadata:
name: my-custom-endpointslice
spec:
endpoints:
- addresses:
- 10.1.2.3
ports:
- name: http
protocol: TCP
port: 80

Application Protocol

The application protocol is the field where you can mention the type of protocol that a specific service is listening to. The protocol can be anything that depends upon our requirements here are the some of application protocols.

  1. TCP
  2. UDP
  3. HTTP
  4. HTTPS

Mostly the service will listen to the TCP protocol. If the service is TCP protocol the service will be load balancing service and if it is HTTP protocol the service type will be ingress.

Multi-Port Services

Multi-port Service allows you to expose different protocols to the same service or different applications on the same service. You can configure multiple ports using the object in kubernetes called to service.

Example

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
- name: http
port: 8080
protocol: TCP
- name: https
port: 43
protocol: TCP

By using the yaml which is mentioned above you can expose multiple ports but the IP address and DNS name will be the only one with that you can use various services.

Load Balancers With Mixed Protocol Types

The service type LoadBalancer can have multiple ports but it should have only one protocol and which is supported by the cloud provider. You can have a kubernetes service that exposes protocols like TCP and UDP ports, which is called a mixed protocol service.

Choosing Your Own IP Address

Kubernetes will assign the IP address from within the service-cluster-ip-range CIDR range or you can choose your own customized IP address. You can reuse the DNS or IP address already in the kubernetes cluster. For reusing, you need to request while creating the service itself.

Example

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
clusterIP: 10.10.10.10
ports:
- name: http
port: 8080
protocol: TC

Once you applied the above specification after that you can access the Tomcat application from the internet by using the IP address you mentioned in the yaml file our case it will be 10.10.10.10. You can also try the above yaml file to create your own customized IP address.

Choosing Your Own Port

While exposing the pod to the internet we will use service objects in the Kubernetes cluster. We will use mainly the nodePort service in Kubernetes while exposing the pod in Kubernetes. You can mention your own port in the yaml in the section which is called nodePort: <PortNumber>. On this port, the users can access the service from the internet and the service will listen on the port which you have mentioned.

Example

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
type: NodePort
selector:
app: Webapp
ports:
- port: 80
targetPort: 8080
# Control Plane in kubernetes will allocates an default
IPaddress which is in the range of various between 30000-32767.
nodePort: 300023
Service type

Types of Services

There are four major types of services which are having their advantages in their perspective as explained following.

  1. ClusterIP
  2. NodePort
  3. LoadBalancer
  4. ExternalName
  5. Headless

1. ClusterIP

When we create a service we will get one Virtual IP (Cluster IP) it will get registered to the DNS(kube-DNS). Using this Other Pds can find and talk to the pods of this service using the service name. Service is just a logical concept, the real work is being done by the “kube-proxy” pod that is running on each node. It redirects requests from Cluster IP(Virtual IP Address) to Pod IP.

Example

apiVersion: v1
kind: Service
metadata:
name: nginxsvc
spec:
selector:
app: nginx
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP

ClusterIP Service ( Internal Service)

In this service type when a Client makes a request then that request is first forwarded to the ingress controller and the ingress controller forwards it to the cluster service and then this service forwards it to the appropriate pod. When there are many replicas of a pod then these replicas serve as the endpoints of service and here service also works as a load balancer and forwards requests to the pod replica having the least load. This service is an Internal service because external traffic cannot directly access the cluster service. It can only be accessed via the Ingress Controller.

Example: Let us make a ClusterIP service for the Nginx Web Server using the following configuration:

Nginx Service Yaml File

Also, the ClusterIP service is the default service if we do not specify the service type in the config file as in the example above.

  • Now we can create this service by applying the following command:

$ kubectl apply -f [file-name]

kubectl apply

2. NodePort Service (External Service)

In NodePort Service, external service has access to a fixed port on each Worker Node. In this case, instead of ingress, the browser request will directly come to the node at the port defined in the service config file and be exposed at the node port. The node port can range between 30000 to 32767. 

Example: 

yaml file for node port
  • Now we can create this service by applying the following command

$ kubectl apply -f [file-name]

3. LoadBalancer

Exposes the service externally using a cloud provider’s load balancer. NodePort and ClusterIP services, to which the external load balancer will route, are automatically created. If you are using a custom Kubernetes Cluster (using minikube, kubeadm, or the like). In this case, there is no LoadBalancer integrated (unlike AWS EKS or Google Cloud, KOPS, and AKS). With this default setup, you can only use NodePort.

Example

apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: javawebapp
type: LoadBalancer

4. ExternalName

  • An ExternalName is a type of service in kubernetes that maps the service to a DNS name outside the cluster. It redirects the requests to the specified DNS name.
  • The following yaml based configuration file of ExternalName service:
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
type: ExternalName
externalName: example.com

5. Headless Service

Headless is a type of service in kubernetes that doesn't assign a ClusterIP to the service instead it returns a DNS records for individual pods. It allows the direct communication with pods without using a load balancer.

  • The following yaml based configuration file of Headless service:
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
clusterIP: None
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
  • To know more about the types of services, refer this - Article

How do You Access A Kubernetes Service? A Step-By-Step Guide

We can access the kubernetes service using the services such as ClusterIP, NodePort ot LoadBalancer IP along with defining the port number. Clients within the cluster uses the service name and port. And the clients who are outside the cluster uses the cluster's external IP or DNS name. The following are the step by step guide for accessing the kubernetes service.

Step 1: Create A Pod

  • Firstly create a yaml file for defining a pod application with a file name my-pod.yaml
  • The following is the pod yaml file code that is used here:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
ports:
- containerPort: 80
  • After once the file has created, then apply the definitions for creating the pod resources using the following command:
kubectl apply -f my-pod.yaml

Accessing Service Using NodePort

Step 2: Create A Service With NodePort

  • For accessing the pod application externally from the cluster, we have to expose the service using NodePort. For that we creating service yaml file with name my-service.yaml .The file code looks as follows:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
  • Apply the service yaml file definitions using the following command:
kubectl apply -f my-service.yaml

Step 3: Access The Service

  • Now, get the NodePort that is assigned to the service:
kubectl get svc my-service
  • Access the service using any node's IP and the NodePort as shown in below:
curl http://<node-IP>:<NodePort>

Accessing Application Using Service Type ClusterIP

Step 2: Create A Service Using ClusterIP

  • For creating a ClusterIP kind service to communicate with the application within the cluster, create a yaml file with name "my-clusterIP-service.yaml" as shown in the below:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
  • Once, the my-clusterIP-service.yaml file is defined, then apply the definition to create the service as per requirement with ClusterIP type using the following command to apply.
kubectl apply -f my-service.yaml

Step 3: Access the Service Using ClusterIP

  • Access the service within the cluster using the service name will looks as follows:
curl http://my-service:80

Accessing Service Using Load Balancer

Step 2: Create A Service With Load Balancer

  • For creating a load balancer service, create a yaml file with name "my-loadbalancer-service.yaml" as shown in the below:
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
  • After once created the my-loadbalancer-service.yaml file then apply the definition changes with the following command:
kubectl apply -f my-loadbalancer-service.yaml

Step 3: Access The Load Balancer

  • Fristly in this get the external IP address of the Load balancer with the following command:
kubectl get svc my-loadbalancer-service
  • Access the application using the service using the LoadBalancer's External IP:
curl http://<LoadBalancer-External-IP>:80

Accessing Service Using External IP

Step 2: Create A Service External IP

  • For creating a External IP service, create a yaml file with name "external-service.yaml" as shown in the below assuming that the IP is already available:
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
externalIPs:
- <External-IP>
  • After once created the external-service.yaml file then apply the definition changes with the following command:
kubectl apply -f external-service.yaml

Step 3: Access The Service using External IP

  • Access the service using the External IP as shown in the following:
curl http://<External-IP>:80

Accessing Service using Headless Service

Step 2: Create A Service of Headless Type

  • For creating a Headless service, create a yaml file with name "my-headless-service.yaml" as shown in the below assuming that the IP is already available:
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
selector:
app: my-app
clusterIP: None
ports:
- protocol: TCP
port: 80
targetPort: 80
  • After once created the my-headless-service.yaml file then apply the definition changes with the following command:
kubectl apply -f my-headless-service.yaml

Step 3: Access Pods Directly via Headless Service

  • Now, get the IPs of the pods that are managed by headless service with the following command:
kubectl get pods -o wide
  • Use the Pod IPs to access the pods directly. The URL looks as follows:
curl http://<pod-IP>:80

Headless Services

Headless Services in Kubernetes comes with specifying the setting of `.spec.clusterIP` to None and doesn't provide the load balancing features with single IP allocation. Instead it facilitates to have a direct connections to the pods individually. It facilitates with interfacing the external service discovery mechanisms. DNS records, DNS services that are managed by Kubernetes provides endpoint IP's for these Headless Services.

Headless Service With Selector

Deployments are usually used for stateless applications. However, you can save the state of deployment by attaching a Persistent Volume to it and make it stateful, but all the pods of deployment will be sharing the same Volume, and data across all of them will be the same. SatefulSet is a Kubernetes resource used to manage stateful applications. It manages the deployment and scaling of a set of Pods and provides a guarantee about the ordering and uniqueness of these Pods.

Example

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
clusterIP: None
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080

When we are using the type of service you will use, you need to give the name "clusterIP: None".

Headless Service Without Selector

On without using the selectors features kubernetes doesn't able to create the ENdpointSlice objects. The configuration of DNS depends on the type of service, some of them discussed as follows:

  • For ExternalNames services, It configures DNS CNAME records.
  • For other types, DNS will generates A or AAAA records for mapping to all IP addresses of ther Service's ready endpoints.

How to Create and Use A Kubernetes Service to Expose Your Application?: A Step-By-Step Guide

The following are the steps that guides on how to use a service to expose your application:

Step 1: Deploy your Application

Deploy your application using a Deployment or Pod yaml file. Here we are taking deployment yaml configure file that is provided as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx
ports:
- containerPort: 80
  • Apply the defined yaml configuration file with the following command:
kubectl apply -f deployment.yaml 

Step 2: Create A Kubernetes Service

Create a yaml file for defining the service to the created deployment and making the application be exposed. The service configured yaml file is given as follows:

apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
  • Apply the service resource configuration containing yaml file using the following command:
kubectl apply -f service.yaml

Step 3: Access Your Application

  • Findout the NodePort that is exposed to the created service for the application with the following command:
 kubectl get svc my-app-service
  • Now access your application using any node's IP and the NodePort.
 curl http://<node-IP>:<NodePort>

Step 4: Optional: Use Ingress

  • If you want to provide the more advanced routing and external access control to the cluster. Consider on using the ingress resource along with the your service.

What are the Differences between Kubernetes Service vs pod?

The following are the differences between Kubernetes Service and Kubernetes Pod:

Feature

Kubernetes Service

Kubernetes Pod

Purpose

It abstracts and exposes a set of pods as a network service

It acts as smallest deployable unit with consisting of one or more containers.

Lifecycle

It is persistent and provides the stable endpoints

It is ephemeral, the containers can be restarted individually.

Networking

It provides a single stable IP address

In each pod kubernetes provides it own IP address.

Scaling

It facilitates with laod balancing across the multiple pods

It facilitates with scaling the pods at container level with a pod.

Discovery

It enables service discovery using DNS

These are directly discoverable, it needs a service for exposure.

What are the Differences between a Service and a Deployment?

The following are the differences between a Service and A Deployment:

Features

Service

Deployment

Purpose

It used for exposing a set of pods as a network service

It used for managing the lifecycle of a set of pods

Functionality

It provides the access to the pods via networking

It defines the desired pod state and ensure to maintain the current is equal to desired state.

Scaling

It doesn't handle the scaling feature

It can scale the pods up or down based on the defined rules

Internal IP

It provides a stable internal IP for pod access

It doesn't provide the internal IP

Exposing Ports

It facilitates to connect with other services or external users by exposing the ports

It doesn't expose the ports directly.

What are the Differences of Docker Service and Kubernetes Service?

The following are the differences of Docker Serive and Kubernetes Service:

Features

Docker Service

Kubernetes Service

Orchestration

It uses Docker Swarm for the orchestration

It uses Kubernetes for the orchestration of containers.

Load Balancing

It built-in as a simple load balancer

It come switch multiple types of load balancer such as ClusterIP, NodePort, LoadBalancer

Scaling

It basically scales the capabilities

It advances the auto-scaling with Horizantal Pod Autoscaler

Networking

It comes with simple networking

It comes with advance networking with namespaces and NetworkPolicies

Serivce Discovery

It facilitates with DNS based service discovery

It comes with label and selector-based service discovery.

Discovering services

The kubernetes service can be discovered by using two methods as follows.

  1. DNS discovery
  2. Environmental Variables

DNS discovery

When you first create a service kubernetes will automatically create DNS records for the service. The application finds the service in kubernets with the help of DNS discovery which will point to the IP address of the service.

All the cluster services will be stored in the cluster-wide domain which is svc. cluster. local. The format of the DNS record is as follows.

<service-name>.<namespace>.svc.cluster.local

DNS in Kubernetes assigns the domain and sub-domain name to the pods and for service. By which other objects or resources in the Kubernetes cluster can discover services by the domain names.

Environmental Variables

Environmental variables will be helpful for the DNS discovery to discover the service in the Kubernetes cluster. You need to mention the environmental variables in the service yaml file as follows then only DNS discovery will discover the service which is available in the Kubernetes cluster;

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
selector:
app: my-app
ports:
- name: http
port: 8080
protocol: TCP
env:
- name: SERVICE_IP
value: "127.0.0.1"
- name: SERVICE_PORT
value: "80"

Similar Reads