Kubernetes Service - CKA

Kubernetes Service - CKA

In Kubernetes, a Service is an abstraction that defines a logical set of Pods and a policy for accessing them. This allows you to expose a network application running in one or more Pods in your cluster.

One of the primary goals of Kubernetes Services is to enable you to expose your application without modifying it to use a specific service discovery mechanism. Whether you have a cloud-native application or an older, containerized app, Kubernetes Services provide a way to make your Pods accessible on the network. This means clients can interact with your application seamlessly, regardless of how the application was originally designed.

Service Types

Kubernetes supports several types of Services, each serving a specific purpose:

  • ClusterIP

  • NodePort

  • LoadBalancer

  • ExternalName

NodePort Service

  • Purpose: Exposes the Service on the same port of each selected Node in the cluster using a static port.

  • Use Case: Allows external traffic to access the Service.

  • Behavior: Maps the Service to a static port on each Node's IP address. Accessible from outside the cluster.

Example

apiVersion: v1
kind: Service
metadata:
  name: nodeport-svc
  labels:
    env: demo
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30001
  selector:
    env: demo

Create a file nodeport.yaml and paste the above content into the file. Explanation of this file:

  • apiVersion: Specifies the version of the Kubernetes API you're using to create this resource. v1 is the most stable and widely used version for core Kubernetes objects like Services.

  • kind: Specifies the type of Kubernetes resource you're defining. In this case, it's a Service.

  • metadata: Provides metadata about the resource, including its name and labels.

  • name: The name of the Service, which must be unique within the namespace. Here, the Service is named nodeport-svc.

  • labels: Key-value pairs used to organize and select resources. Labels are optional and can be used for grouping and querying resources.

  • env: demo: A label with the key env and the value demo. This can be used to identify the environment (e.g., development, production).

  • spec: Specifies the desired behavior of the Service. This section contains the configuration for how the Service should operate.

  • type: NodePort: Defines the type of Service. NodePort exposes the Service on each Node's IP at a static port (the nodePort).

  • ports: Specifies the ports that the Service will use. This section is an array because a Service can have multiple ports.

    • port: 80: The port that the Service will expose internally (the ClusterIP). Clients within the cluster can connect to this port to access the Service.

    • targetPort: 80: The port on the Pods that the Service should direct traffic to. This allows you to decouple the port exposed by the Service from the port the application listens on.

    • nodePort: 30001: The port on each Node's IP that the Service will be exposed on. This port must be within the range 30000-32767. External traffic can access the Service via this port.

  • selector: Defines how the Service finds the Pods it routes traffic to. The selector matches labels on the Pods.

    • app: v1: The label selector. The Service will route traffic to all Pods that have the label app: v1.

Our NGINX pod has the label app: v1.

Now, run the following command to create the NodePort Service**:**

kubectl apply -f nodeport.yaml

The Service is created. Kubernetes (ClusterIP Service) is already created when you create a cluster.

Now, we can access our application on <nodeIP:30001>.

You can get the Node IP by running the following command:

kubectl get nodes -o wide

Now your NGINX application is running, if not check on your public or localhost IP.

If you want to know the details of your Service, you can use the following command:

kubectl describe svc/<service-name>

ClusterIP Service

Suppose you have a three-tier application with the frontend, backend, and database each running in different Pods. These Pods need to communicate with each other, but the IPs of the Pods are dynamic. This means that if a Pod is deleted and a new one is created, it will have a new IP address. To facilitate communication within the cluster despite these dynamic IPs, we use a ClusterIP Service.

  • Purpose: Provides internal access within the Kubernetes cluster.

  • Use Case: Ideal for communication between internal components of an application, such as frontend to backend, or backend to database.

  • Behavior: Exposes the Service on an internal IP address, accessible only from within the cluster. Ensures stable network endpoints for inter-pod communication despite dynamic Pod IPs.

Example

apiVersion: v1
kind: Service
metadata:
  name: clusterip-svc
  labels:
    env: demo
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    env: demo

Create a file cluster-ip.yaml and paste the above content into the file and run the following command:

kubectl apply -f <yaml-file-name>

If you want to know all information about the ClusterIP Service, you can use the following command:

kubectl describe svc/<service-name>

LoadBalancer Service

  • Purpose: Exposes the Service externally using a cloud provider's load balancer.

  • Use Case: Suitable for production workloads where external access with load balancing is needed.

  • Behavior: Creates an external load balancer that routes traffic to the Service. Requires support from the cloud provider.

Example

apiVersion: v1
kind: Service
metadata:
  name: lb-svc
  labels:
    env: demo
spec:
  type: LoadBalancer
  ports:
    - port: 80
  selector:
    app: v1

Create a file lb.yaml and paste the above content into the file and run the following command:

kubectl apply -f <yaml-file-name>

In above image, the external-ip of lb-svc is pending because we need an external ip that will be provided by our cloud provider to expose our application.

and for more information about this service u can run kubectl describe svc/<service-name command.

ExternalName Service

  • Purpose: Maps a Service to a DNS name.

  • Use Case: Integrating with external services that are outside the Kubernetes cluster.

  • Behavior: Returns a CNAME record with the ExternalName value, allowing traffic to be routed to an external DNS name.

We will be doing more hands-on activities with these services in the future when we deploy our fully-fledged three-tier application on Kubernetes.

Components of a Kubernetes Service

  • Selector: Identifies the Pods that the Service will manage by using labels. For example, if you label your Pods with app=v1, you can create a Service that selects these Pods by specifying this label in the selector field.

  • Cluster IP: A unique IP address assigned to the Service. This IP is stable and doesn’t change, providing a constant endpoint for accessing the Pods managed by the Service.

  • Ports: Defines the port on which the Service is exposed. It includes the port on the Service, the target port on the Pods, and an optional NodePort for external access.

  • Endpoints: Lists the IP addresses and ports of the Pods that are currently selected by the Service.

Benefits of Using Services

  • Decoupling: Services decouple the definition of an application from its actual runtime state.

  • Load Balancing: Distributes incoming traffic across multiple Pods to ensure high availability and reliability.

  • Discovery and Routing: Simplifies the discovery and routing of Pods, making it easier to manage and scale applications.

  • Scalability: As you scale your Pods up or down, the Service automatically adjusts to include the new Pods, ensuring continuous availability.

Thank you for reading my blog! After you finish reading, please go through the tasks provided for hands-on practice. If you have any doubts, feel free to comment on this blog, and I will definitely answer your questions.

  • To get pods with labels also -
kubectl get pods --show-labels
  • To get endpoints -
kubectl get ep #or
kubectl get endpoints