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!

Categorized in:

Blog,