Services
There is a possibility of pod crash so that the ip address will not be consistent and it will be changed dynamically from time to time in the case of pod failure. In order to make it accessible all the time via application without worrying about the change in pod IP.
Why we need?
Let's say we have two replicaset that create pods in node (may vary or differ)
We have two application one is running backend and the other one running frontend. Frontend is using the IP address and the port to access the backend application.
But there is a possibility that the pod might be crashed due to some reason and if that happens the IP address will change dynamically. So, it will be problem to fetch the data from the backend using the same IP address.
In order to avoid this problem and keep the IP static we use this object called services.
Here the replicaset get the Virtual IP address and it is mapped with pods in such a way that if the IP address of an individual pod will change it won't affect the application that was using the application in the pod because the application will be using the VIP.
Replication Controller or Replica Set get virtual IP address
About Service
object
- When using Replication Controller or Replica Set, Ports are terminated and created during scaling or application operation
- When using deployments, while updating the image version the pods are terminated and new pods take the place of the other pods.
- Pods are very dynamic i.e., they come and go on the K8s cluster and on any of the available nodes and it would be difficult to access the pods as the pods IP change once its recreate
- Service object is a logical bridge between pods and end user, which provides virtual IP address (VIP)
- Service allows client to reliably connect to the containers running in the pod using the VIP
- The VIP is not an actual IP connected to a network interface but its purpose is purely to forward traffic to one or more pods
Kube-proxy
is the one which keeps the mapping between the VIP and the pods upto date, which queries theapi-server
to learn about new services in the cluster- Although each pod has a unique IP address those IPs are not exposed outside the cluster
- Service object helps to expose the VIP map to the force and allow application to receive traffic
- Labels are used to select which are the ports to be put under service
- Creating a service will create an endpoint to access the nodes/application in it
- Services can be exposed in different ways by specifying a type in the service specification -
- Cluster IP (default)
- NodePort
- Load Balancer - Created by cloud providers that will route external traffic to every node on the NodePort (Example ELB on AWS)
- Headless - Create several endpoints that are used to produce DNS records each DNS record is bound to a pod
- Invite fault to skin run only between ports 30,000 to 32,767 the set of pods targeted by service ususlly determined by a selector.
Replicaset get Cluster IP (Virtual IP Address), and a Cluster IP Address get NodePort and Load Balancer is applied on Node Port (for more refer to image)_
Cluster IP
- Expose VIP only reachable within the cluster
- Mainly used to communicate between components of Microservices
Example - Cluster IP
Manifest file k8s_example_12.yml
kind: Deployment
apiVersion: apps/v1
metadata:
name: example-12
spec:
replicas: 2
selector:
matchLabels:
name: xander
template:
metadata:
name: container0
labels:
name: xander
spec:
containers:
- name: c00
image: httpd
ports:
- containerPort: 80
Manifest file service.yml
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 80
selector:
name: xander
type: ClusterIP
Create a replica set using manifest
kubectl apply -f k8s_example_12.yml
controlplane $ kubectl apply -f k8s_example_12.yml
replicaset.apps/example-12 created
Verify the rs and pods
kubectl get rs
kubectl get pods -o wide
controlplane $ kubectl get rs
NAME DESIRED CURRENT READY AGE
example-12-7f6f6c744d 2 2 2 14s
controlplane $ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
example-12-7f6f6c744d-2f567 1/1 Running 0 16s 192.168.0.4 controlplane <none> <none>
example-12-7f6f6c744d-cwhzk 1/1 Running 0 16s 192.168.1.4 node01 <none> <none>
Try to access the pod using IP_ADDRESS:PORT
curl 192.168.0.4:80
controlplane $ curl 192.168.0.4:80
<html><body><h1>It works!</h1></body></html>
Now let's say if we delete the pod we need to use new IP address to use the httpd
service running in the container. Create a service to get a virtual IP address.
kubectl apply -f service.yml
controlplane $ kubectl apply -f service.yml
service/my-service created
To get the details of the service using service name (Cluster IP)
kubectl get services
controlplane $ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
my-service ClusterIP 10.108.184.82 <none> 80/TCP 71s
This is the service (my-service) that we have created using manifest.
kubectl describe services my-service
controlplane $ kubectl describe services my-service
Name: my-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: name=xander
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.108.184.82
IPs: 10.108.184.82
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 192.168.1.4:80,192.168.0.4:80
Session Affinity: None
Internal Traffic Policy: Cluster
Events: <none>
So we get the Virtual IP Address i.e., 10.108.184.82
Try to access the pod using VIRTUAL_IP_ADDRESS:PORT
curl 10.108.184.82:80
controlplane $ curl 10.108.184.82:80
<html><body><h1>It works!</h1></body></html>
Now even if the pod get deleted it won't affect the service.
NodePort
- It is applied over the cluster.
- Make a service accessible from outside the cluster that is from Internet using the exposed port.
- Expose the service on the same port of each selected node on the cluster using NAT gateway.
Example - NodePort
Manifest file k8s_example_12.yml
kind: Deployment
apiVersion: apps/v1
metadata:
name: example-12
spec:
replicas: 2
selector:
matchLabels:
name: xander
template:
metadata:
name: container0
labels:
name: xander
spec:
containers:
- name: c00
image: httpd
ports:
- containerPort: 80
Manifest file service.yml
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 80
selector:
name: xander
type: NodePort
Create a replica set using manifest
kubectl apply -f k8s_example_12.yml
controlplane $ kubectl apply -f k8s_example_12.yml
replicaset.apps/example-12 created
Verify the rs and pods
kubectl get rs
kubectl get pods -o wide
controlplane $ kubectl get rs
NAME DESIRED CURRENT READY AGE
example-12-7f6f6c744d 2 2 2 14s
controlplane $ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
example-12-7f6f6c744d-2f567 1/1 Running 0 16s 192.168.0.4 controlplane <none> <none>
example-12-7f6f6c744d-cwhzk 1/1 Running 0 16s 192.168.1.4 node01 <none> <none>
Try to access the pod using IP_ADDRESS:PORT
curl 192.168.0.4:80
controlplane $ curl 192.168.0.4:80
<html><body><h1>It works!</h1></body></html>
Now let's say if we delete the pod we need to use new IP address to use the httpd
service running in the container. Create a service to get a virtual IP address.
kubectl apply -f service.yml
controlplane $ kubectl apply -f service.yml
service/my-service created
To get the details of the service using service name (Cluster IP)
kubectl get services
controlplane $ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
my-service NodePort 10.108.184.82 <none> 80:32214/TCP 27m
This is the service (my-service) that we have created using manifest.
kubectl describe services my-service
controlplane $ kubectl describe services my-service
Name: my-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: name=xander
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.108.184.82
IPs: 10.108.184.82
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32214/TCP
Endpoints: 192.168.1.4:80,192.168.0.4:80
Session Affinity: None
External Traffic Policy: Cluster
Internal Traffic Policy: Cluster
Events: <none>
So we get the Virtual IP Address i.e., 10.108.184.82
Try to access the pod using VIRTUAL_IP_ADDRESS:NODE_PORT
curl 52.65.226.21:80
localhost $ curl 52.65.226.21:80
<html><body><h1>It works!</h1></body></html>
Now even if the pod get deleted it won't affect the service.