Author: Ojas Jawale
What are Services in K8s?
- In Kubernetes, a service is an entity that represents a set of pods running an application or functional component. The service holds access policies, and is responsible for enforcing these policies for incoming requests.
- The need for services arises from the fact that pods in Kubernetes are short lived and can be replaced at any time. Kubernetes guarantees the availability of a given pod and replica, but not the liveness of individual pods.
- This means that pods that need to communicate with another pod cannot rely on the IP address of the underlying single pod. Instead, they connect to the service, which relays them to a relevant, currently-running pod.
- The service is assigned a virtual IP address, known as a clus terIP, which persists until it is explicitly destroyed. The service acts as a reliable endpoint for communication between components or applications.
How to Create a Kubernetes Service
A Kubernetes service can be configured using a YAML manifest. Here is an example of a service YAML:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: nginx
ports:
protocol: TCP
port: 80
targetPort: 8080
Here are important aspects of the service manifest:
- metadata:name—this is the logical name of the service, which will also become the DNS name of the service when it is created.
- spec:selector—the selector identifies which pods that should be included in the service. In this example, pods that have the label app: nginx will become part of the service.
- spec:ports—a list of port configurations (there can be one or more). Each port configuration defines a network protocol and port number. Optionally, the port configuration can define a targetPort, which is the port the pod should send traffic to.
What are the Types of Kubernetes Services?
ClusterIP
- ClusterIP is the default service type in Kubernetes. It receives a cluster-internal IP address, making its pods only accessible from within the cluster. If necessary, you can set a specific clusterIP in the service manifest, but it must be within the cluster IP range.
Manifest example:
apiVersion: v1
kind: Service
metadata:
name: my-clusterip-service
spec:
type: ClusterIP
clusterIP: 10.10.5.10
ports:
—name: http
protocol: TCP
port: 80
targetPort: 8080
NodePort
- A NodePort service builds on top of the ClusterIP service, exposing it to a port accessible from outside the cluster. If you do not specify a port number, Kubernetes automatically chooses a free port. The kube-proxy component on each node is responsible for listening on the node’s external ports and forwarding client traffic from the NodePort to the ClusterIP.
- By default, all nodes in the cluster listen on the service’s NodePort, even if they are not running a pod that matches the service selector. If these nodes receive traffic intended for the service, it is handled by network address translation (NAT) and forwarded to the destination pod.
- NodePort can be used to configure an external load balancer to forward network traffic from clients outside the cluster to a specific set of pods. For this to work, you must set a specific port number for the NodePort, and configure the external load balancer to forward traffic to that port on all cluster nodes. You also need to configure health checks in the external load balancer to determine whether a node is running healthy pods.
- The nodePort field in the service manifest is optional, and lets you specify a custom port between 30000-32767.
Manifest example:
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: nginx
ports:
—name: http
protocol: TCP
port: 80
targetPort: 8080
nodePort: 30000
LoadBalancer
- A LoadBalancer service is based on the NodePort service, and adds the ability to configure external load balancers in public and private clouds. It exposes services running within the cluster by forwarding network traffic to cluster nodes.
- The LoadBalancer service type lets you dynamically implement external load balancers. This typically requires an integration running inside the Kubernetes cluster, which performs a watch on LoadBalancer services.
Manifest example:
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
type: LoadBalancer
clusterIP: 10.0.160.135
loadBalancerIP: 168.196.90.10
selector:
app: nginx
ports:
—name: http
protocol: TCP
port: 80
targetPort: 8080
ExternalName
- An ExternalName service maps the service to a DNS name instead of a selector. You define the name using the spec:externalName parameter. It returns a CNAME record matching the contents of the externalName field (for example, my.service.domain.com), without using a proxy.
- This type of service can be used to create services in Kubernetes that represent external components such as databases running outside of Kubernetes. Another use case is allowing a pod in one namespace to communicate with a service in another namespace—the pod can access the ExternalName as a local service.
Manifest example:
apiVersion: v1
kind: Service
metadata:
name: my-externalname-service
spec:
type: ExternalName
externalName: my.database.domain.com
Task 1 : Service creation & definition
- Create a Service for your todo-app Deployment from Day-32
- Create a Service definition for your todo-app Deployment in a YAML file.
- Apply the Service definition to your K8s (minikube) cluster using the
kubectl apply -f service.yml -n <namespace-name>
command. - Verify that the Service is working by accessing the todo-app using the Service’s IP and Port in your Namespace.
Namespace
apiVersion: v1
kind: Namespace
metadata:
name: todo-app
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: todo-app
namespace: todo-app
spec:
replicas: 3
selector:
matchLabels:
app: todo-app
template:
metadata:
labels:
app: todo-app
spec:
containers:
- name: todo-app
image: ojasjawale/node-app:v1
ports:
- containerPort: 8000
Service
apiVersion: v1
kind: Service
metadata:
name: todo-service
namespace: todo-app
spec:
selector:
app: todo-app
ports:
- protocol: TCP
port: 80
targetPort: 8000
- Use a temporary pod to access the service,
kubectl run curlpod --image=curlimages/curl -i --tty --rm -- sh
- Inside the pod,
curl http://<Cluster_IP>:80
Task 2 : Using ClusterIP service
- Create a ClusterIP Service for accessing the todo-app from within the cluster
- Create a ClusterIP Service definition for your todo-app Deployment in a YAML file.
- Apply the ClusterIP Service definition to your K8s (minikube) cluster using the
kubectl apply -f cluster-ip-service.yml -n <namespace-name>
command. - Verify that the ClusterIP Service is working by accessing the todo-app from another Pod in the cluster in your Namespace.
Task 3 : Using Load-Balancer service
- Create a LoadBalancer Service for accessing the todo-app from outside the cluster
- Create a LoadBalancer Service definition for your todo-app Deployment in a YAML file.
- Apply the LoadBalancer Service definition to your K8s (minikube) cluster using the
kubectl apply -f load-balancer-service.yml -n <namespace-name>
command. - Verify that the LoadBalancer Service is working by accessing the todo-app from outside the cluster in your Namespace.
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: todo-app
namespace: todo-app
spec:
replicas: 3
selector:
matchLabels:
app: todo-app
template:
metadata:
labels:
app: todo-app
spec:
containers:
- name: todo-app
image: ojasjawale/node-app:v1
ports:
- containerPort: 8000
Service
apiVersion: v1
kind: Service
metadata:
name: todo-service
namespace: todo-app
spec:
type: LoadBalancer
selector:
app: todo-app
ports:
- protocol: TCP
port: 80
targetPort: 8000
- Accessing the application,
curl -L http://<minikube_ip>:<node_port>
or
curl http://<minikube_ip>:<node_port>
Connect With Me,
Thank you for reading. I hope you were able to understand and learn something new from my blog.
Happy Learning!