(Day 33) Task : Kubernetes Services – Solving the Problem of Dynamic Pod IPs Using Virtual IPs:-

Aditya SharmaAditya Sharma
6 min read

In Kubernetes, Pods are the basic execution units, but they’re also inherently dynamic and short-lived. When scaling, updating, or restarting, Pods get new IP addresses. So how do you build reliable communication in such a constantly changing system?

That’s where Kubernetes Services come into play.

The Problem: Pods Have Their Own IPs – But They Change :

Each Pod in Kubernetes gets a unique IP address when it's created. This is great in theory because it allows direct communication. However, there's a big problem:

In a Deployment or ReplicaSet, the set of Pods running at any given time can change due to updates, scaling, failures, or rolling deployments.

For example, imagine a frontend app that needs to talk to a backend. If the backend is running as a Deployment with multiple Pods:

  • Which IP does the frontend connect to?

  • What happens when one of those Pods is deleted or rescheduled and gets a new IP?

These questions make it clear: Pod IPs are unreliable for stable communication.

The Solution: Services and Virtual IPs :

To solve this issue, Kubernetes introduces a Service object, which acts as a stable access point to a dynamic set of Pods.

Here's how it works:

  • The Service is assigned a virtual IP (ClusterIP).

  • This virtual IP acts as a permanent endpoint, regardless of which Pods are currently running.

  • The Service uses label selectors to dynamically route traffic to healthy Pods matching those labels.

  • If a Pod dies and a new one is created, the Service automatically remaps traffic to the new Pod.

In other words:

Virtual IP stays constant → Kubernetes maintains mapping → You don’t need to track Pod IPs

Example Scenario: 10 Pods, 1 Frontend :

Let’s say you have:

  • 10 backend Pods running in a ReplicaSet

  • A frontend app that needs to send requests to the backend

Without Services:

  • The frontend would need to know all 10 IPs

  • It would have to detect new Pods and remove stale ones

With Services:

  • The frontend just connects to one virtual IP

  • Kubernetes handles load balancing and mapping automatically

Why This Is Critical in Deployments :

When you use:

  • ReplicationController → Pods are scaled up/down dynamically

  • Deployment → Updates cause Pods to be deleted and replaced

  • Rolling updates or restarts → Pod IPs change regularly

So, trying to connect to Pod IPs directly would constantly break communication.

That’s why Services are critical components in Kubernetes networking. They bridge the gap between dynamic Pods and stable connectivity.

What Is a Service in Kubernetes?

A Service is a Kubernetes object that:

  • Provides a virtual IP address

  • Maps to one or more Pods based on labels

  • Load balances traffic to the matching Pods

  • Can optionally be exposed outside the cluster

Virtual IP ≠ Physical IP :

This virtual IP is not tied to any physical network. It’s a cluster-level construct, which internally maps to the actual Pod IPs.

The kube-proxy running on every node is responsible for maintaining this mapping using iptables or IPVS.

  • Virtual IP is reachable within the cluster

  • kube-proxy updates the routing rules dynamically as Pods come and go

Pod IPs Are Private :

Even though each Pod has a unique IP, these IPs are:

  • Assigned from an internal subnet (e.g., 10.244.x.x)

  • Not routable from the outside world

  • Short-lived due to the nature of Pods

Therefore, to allow your app to receive traffic from other components (or users), you need a Service.

How a Service Knows Which Pods to Route To?

This is handled using labels and selectors.

Each Pod has metadata labels like:

labels:
  app: backend

The Service uses a selector:

selector:
  app: backend

That way, it will forward traffic to any Pod with that label.

Types of Services in Kubernetes :

There are four types of services, each used in different scenarios:

TypeDescription
ClusterIPDefault; only accessible from inside the cluster
NodePortExposes the service on a static port on each node (30000–32767)
LoadBalancerUses a cloud provider's load balancer to expose the service externally
HeadlessNo ClusterIP; gives clients direct access to Pod IPs via DNS

Let’s Talk About ClusterIP – The First and Most Common Type :

ClusterIP is the default type of Service.

Features:

  • Allocates a virtual IP inside the cluster

  • Not accessible from outside

  • Used for communication between microservices

Example YAML:

apiVersion: v1
kind: Service
metadata:
  name: demoservice
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
     name: deployment
  type: ClusterIP

Recap: Why Services Are Important in Kubernetes

  • Pods are dynamic – they come and go.

  • Each Pod has a unique IP, but it’s temporary.

  • Virtual IPs (via Services) provide a stable endpoint.

  • kube-proxy keeps mapping between Virtual IP and Pod IP.

  • Services allow internal and external components to reliably connect to apps running inside Pods.

Kubernetes ClusterIP Practical – HTTP Server Deployment and Service Communication :-

In this project, we’ll set up a Deployment running the httpd image and expose it via a Service of type ClusterIP. This helps us simulate internal communication within the Kubernetes cluster using a virtual IP.

We'll go step by step:

  • Create the Deployment using deployHttpd.yml

  • Create the ClusterIP Service using service.yml

  • Test connectivity using minikube ssh and curl

File 1: deployHttpd.yml (Deployment) :

This file defines the Deployment that runs the Apache HTTP server (httpd) container.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployhttpd
spec:
  replicas: 1
  selector:
    matchLabels:
      name: deployment
  template:
    metadata:
      labels:
        name: deployment
    spec:
      containers:
        - name: httpd-container
          image: httpd
          ports:
            - containerPort: 80

Apply the Deployment:

kubectl apply -f deployHttpd.yml

Verify Pod:

kubectl get pods

File 2: service.yml (ClusterIP Service) :

This file creates a ClusterIP Service that targets the Pods from the Deployment above using a label selector.

apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  ports:
    - port: 80
      targetPort: 80
  selector:
    name: deployment
  type: ClusterIP
  • port: The port used inside the cluster.

  • targetPort: The container port defined in the Deployment.

  • selector: Routes traffic to Pods labeled name: deployment.

Apply the Service:

kubectl apply -f service.yml

Check Service and ClusterIP

kubectl get svc or service

Expected output:

NAME            TYPE        CLUSTER-IP      PORT(S)   AGE
demo-service    ClusterIP   10.97.210.158    80/TCP    5s

This 10.96.252.123 is the virtual IP of the Service. It's internal and accessible only within the cluster.

Test ClusterIP Communication from Inside the Cluster

Since ClusterIP is not accessible from outside the cluster, we must test it from within:

Step 1: SSH into Minikube

minikube ssh

Step 2: Install curl inside Minikube (if needed):

sudo apt update
sudo apt install curl -y

Step 3: Curl the ClusterIP

curl <CLUSTER-IP> :80

Or, using the service name:

curl http://demo-service

You should see the default Apache welcome page HTML content.

Final Thoughts :

Kubernetes Services are a foundational component in building robust, scalable, and maintainable applications in Kubernetes.

They:

  • Abstract away Pod lifecycle changes

  • Offer load balancing and discoverability

  • Bridge communication across services internally and externally

Without Services, managing connectivity between Pods in a dynamic, self-healing system like Kubernetes would be nearly impossible.

In the next article, we’ll explore how to expose a service to the outside world using NodePort, and later, how to manage traffic with Ingress.

🙏 Thanks for following along on my 90 Days of DevOps Journey. I’m still recovering from my back injury, so I appreciate your support and patience as I go at a steady pace.

— Aditya Sharma

0
Subscribe to my newsletter

Read articles from Aditya Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aditya Sharma
Aditya Sharma

DevOps Enthusiast | Python | Chef | Docker | GitHub | Linux | Shell Scripting | CI/CD & Cloud Learner | AWS