A ClusterIP Service is the default Kubernetes service type. It provides a virtual IP address (VIP) inside the cluster to allow pods to communicate with each other. It is internal-only, meaning it is not accessible from outside the cluster.

Example Manifests

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: nginx:1.25-alpine   # Using Nginx as an example
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - port: 80          # Port exposed by the Service (accessible inside the cluster)
      targetPort: 80    # Port on the Pod container
  type: ClusterIP       # Default type is ClusterIP

You can try it out by running the following commands

Apply the Kubernetes manifest to the test cluster kind-my-cluster. If the test cluster doesn’t exist, you can create it using Kind or Minikube.

kubectl --context kind-my-cluster apply -f deployment-service-clusterip.yaml

Run these commands to check the pods and cluster IPs.

kubectl --context kind-my-cluster get pods
NAME                      READY   STATUS    RESTARTS   AGE
my-app-7849ff97f7-tznb9   1/1     Running   0          35s
my-app-7849ff97f7-vmmvp   1/1     Running   0          35s

kubectl --context kind-my-cluster get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   2m33s
my-service   ClusterIP   10.96.144.131   <none>        80/TCP    45s

Create a temporary test pod in the same cluster, then SSH into it to communicate with another pod.

kubectl --context kind-my-cluster run test-client --rm -it --image=busybox:1.36 -- sh
wget -qO- http://10.96.144.131:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Overall ClusterIP Communication Process

  1. Service Creation
    1. When you create a Service of type ClusterIP, Kubernetes assigns it a virtual IP address (the ClusterIP) from the Service CIDR range (e.g., 10.96.0.0/12).
    2. This IP does not belong to any physical node interface; it only exists virtually inside the cluster.
  2. kube-proxy Programming Rules
    1. Each node runs a component called kube-proxy.
    2. kube-proxy watches the Kubernetes API for Services and their Endpoints (the list of Pods backing the Service).
    3. It installs routing/forwarding rules on the node using either iptables or IPVS.
    4. These rules map the ClusterIP:Port to one of the backend Pod IPs.
  3. Pod Makes a Request
    1. A Pod tries to access the Service, e.g. http://my-service:80.
    2. DNS (CoreDNS) resolves my-service.default.svc.cluster.local to the ClusterIP (e.g., 10.96.0.12).
  4. Traffic Reaches ClusterIP
    1. The request packet is sent to 10.96.0.12:80.
    2. The node’s iptables/IPVS rules intercept it and perform DNAT (destination NAT), rewriting the destination to a real Pod IP:Port, e.g., 10.244.1.5:8080.
  5. Forwarding to the Pod
    1. If the Pod is on the same node, the packet is delivered directly.
    2. If the Pod is on a different node, the packet is forwarded across the cluster network (via the CNI plugin like Calico or Flannel).
  6. Response Path
    1. The Pod sends back the response.
    2. The return traffic goes through the reverse NAT process, so the client Pod sees the response as if it came from the ClusterIP, not the real Pod IP.
    3. This keeps the abstraction consistent.

Summary (data flow)

Client Pod → DNS → ClusterIP (virtual IP) → kube-proxy (iptables/IPVS rules) → One of the backend Pod IPs → Pod processes request and replies → NAT rewrites response back → Client Pod

Share:

Leave a Reply

Your email address will not be published. Required fields are marked *

It might take a few hours to show up the new comment because of our caching system.

This site uses Akismet to reduce spam. Learn how your comment data is processed.