Day 34: 90DaysOfChallenge

Day 34: 90DaysOfChallenge

Working with Services in Kubernetes

What are Services in K8s

In Kubernetes, Services are objects that provide stable network identities to Pods and abstract away the details of Pod IP addresses. Services allow Pods to receive traffic from other Pods, Services, and external clients.

Service is an abstract way to expose an application running on a set of Pods as a network service. It enables other Pods within the cluster or external users to access the application. It targets a set of Pods using label selectors. The Service acts as a stable endpoint for accessing the application, abstracting away the details of individual Pod IPs and providing a consistent way to reach the application regardless of Pod changes or scaling. There are three types of services - ClusterIP, NodePort and LoadBalancer.

  • ClusterIP - Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default that is used if you don't explicitly specify a type for a Service. You can expose the Service to the public internet using an Ingressor a Gateway.

  • NodePort - Exposes the Service on each Node's IP at a static port (the NodePort). To make the node port available, Kubernetes sets up a cluster IP address, the same as if you had requested a Service of type: ClusterIP.

  • LoadBalancer - Exposes the Service externally using an external load balancer. Kubernetes does not directly offer a load balancing component; you must provide one, or you can integrate your Kubernetes cluster with a cloud provider.

Task-1:

  • Create a Service for your todo-app Deployment from Day-32.

Let's create a yaml/manifest file with the name service-nodePort.yml using vim editor.

  • Create a Service definition for your todo-app Deployment in a YAML file.

apiVersion: v1
kind: Service
metadata:
  name: todo-app-service
  namespace: todo-app
  labels:
    app: todo
spec:
  selector:
    app: todo
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
      nodePort: 30080

The above example creates a service of type NodePort with the service name as todo-app-service. The set of Pods targeted by a Service is usually determined by a selector that you define. Over here, the selector is todo. The type defines the type of Service used. The ports defines the port mapping for the Service. The Service will listen on port 80 and forward traffic to the target port 8000 on the pods. Additionally, a nodePort is defined as 30080 which will make the Service accessible from outside the cluster by using the IP address of any pod in the cluster and the nodePort defined in the Service.

By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767).

  • Apply the Service definition to your K8s (minikube) cluster using the kubectl apply -f service.yml -n <namespace-name> command.

    To apply the service definition to the Kubernetes cluster, give the following command - kubectl apply -f service-nodePort.yml -n todo-app.

To check whether the service is created in the assigned namespace, give the following command - kubectl get svc -n todo-app. We can see todo-app-service of type NodePort is present.

  • Verify that the Service is working by accessing the todo-app using the Service's IP and Port in your Namespace.

    The minikube service command is used to interact with services in a Minikube cluster. One can fetch the url which can be accessed in the web browser using the following command - minikube service <service-name> -n <name-space> --url. Hence, for the above example it would be minikube service todo-app-service -n todo-app --url. The URL can be accessed from within the Minikube cluster and not from your local.

    We can access the todo-app using the above url i.e. service's IP and NodePort with the curl command - curl -L <service-ip>:<service-port> We are getting the response on hitting the curl request which means the todo-app is working fine.

Task-2:

  • Create a ClusterIP Service for accessing the todo-app from within the cluster.

    Let's create a yaml/manifest file with the name service-clusterIP.yml using vim editor.

  • Create a ClusterIP Service definition for your todo-app Deployment in a YAML file.

apiVersion: v1
kind: Service
metadata:
  name: todo-app-service-clusterip
  namespace: todo-app
  labels:
    app: todo
spec:
  selector:
    app: todo
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000

The only changes in ClusterIP would be the name of Service, type of Service and there would be no NodePort inside ports. The ClusterIP service would allow the node to be accessible only within the cluster.

The above example creates a service of type ClusterIP with the service name as todo-app-service-clusterip. The selector todo determines which Pods to associate with the Service. The type defines the type of Service used. The ports defines the port mapping for the Service. The Service has a single port 80 and is mapped to the target port 8000 on the pods.

  • Apply the ClusterIP Service definition to your K8s (minikube) cluster using the kubectl apply -f <cluster-ip-service.yml> -n <namespace-name> command.

    To apply the service definition to the Kubernetes cluster, give the following command - kubectl apply -f service-clusterIP.yml -n todo-app.

To check whether the service is created in the assigned namespace, give the following command - kubectl get svc -n todo-app. We can see todo-app-service-cluster of type ClusterIP is present.

  • Verify that the ClusterIP Service is working by accessing the todo-app from another Pod in the cluster in your Namespace.

To verify whether the ClusterIP Service is working in another Pod in the same cluster in the given namespace, first we need to get the pod name present in the same namespace using kubectl get pods -n todo-app.

Let's get inside the container using exec with any of the above container using kubectl exec -it <pod-name> -n todo-app bash and make a curl request. We are getting the response on hitting the curl request which means the todo-app is working fine.

Task-3:

  • Create a LoadBalancer Service for accessing the todo-app from outside the cluster.

    Let's create a yaml/manifest file with the name service-loadBalancer.yml using vim editor.

  • Create a LoadBalancer Service definition for your todo-app Deployment in a YAML file.

apiVersion: v1
kind: Service
metadata:
  name: todo-app-service-loadbalancer
  namespace: todo-app
  labels:
    app: todo
spec:
  selector:
    app: todo
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000

The above example creates a service of type LoadBalancer with the service name as todo-app-service-loadBalancer. The selector todo determines which Pods to associate with the Service. The type defines the type of Service used.

  • Apply the LoadBalancer Service definition to your K8s (minikube) cluster using the kubectl apply -f load-balancer-service.yml -n <namespace-name> command.

    To apply the service definition to the Kubernetes cluster, give the following command - kubectl apply -f service-loadBalancer.yml -n todo-app.

To check whether the service is created in the assigned namespace, give the following command - kubectl get svc -n todo-app.

  • Verify that the LoadBalancer Service is working by accessing the todo-app from outside the cluster in your Namespace.

One can fetch the url which can be accessed in the web browser using the following command - minikube service <service-name> -n <name-space> --url. Hence, for the above example it would be minikube service todo-app-service-loadBalancer -n todo-app --url.

Get the URL to access the service from your browser -

One can also get the list of all the services created in the cluster using minikube service list.

Get the list of all the service -

Access the todo-app using the above url i.e. load balancer's IP and the service port with the curl command - curl -L <load-balancer-ip>:<service-port>or simply by using the above url. We are getting the response on hitting the curl request which means the todo-app is working fine.

One can also delete the service using kubectl delete svc <service-name> -n <name-space>. Over here, it is kubectl delete todo-app-service-loadbalancer -n todo-app.

Delete the service -

Hurray! We have completed Day 34 Challenge of #90DaysOfDevops and learned about the different types of Services in Kubernetes.

Thanks for reading!

Happy Learning!