<p>I created a <code>ReplicaSet</code> with <code>replicas = 3</code>. These pods <code>internal-pod-a</code>, <code>internal-pod-b</code>, <code>internal-pod-c</code> serve for internal needs only. Then I created a service with <code>ClusterIP</code> type to route requests to the pods.</p>

<p>For testing purposes I tried to see how the traffic will be distributed. After port forwarding, I executed several requests to the service:</p>

<pre><code>kubectl port-forward svc/internal-service-cip 8081:80 -n prod
</code></pre>

<p>All the requests were served on the same pod <code>internal-pod-a</code>. </p>

<p>So I'm confused, why does the <code>ClusterIP</code> send all requests to the same pod?</p>

<p>k8s manifests:</p>

<pre><code>apiVersion: apps/v1
kind: ReplicaSet
metadata:
  namespace: prod
  name: internal-pod
  labels:
    app: internal-pod
    environment: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: internal-pod
      environment: prod
  template:
    metadata:
      labels:
        app: internal-pod
        environment: prod
    spec:
      containers:
      - name: internal-pod
        image: bla-bla-repo
        ports:
        - containerPort: 8080
-----------------------------
apiVersion: v1
kind: Service
metadata:
  namespace: prod
  name: internal-service-cip
spec:
  type: ClusterIP
  selector:
    app: internal-pod
  ports:
  - name: http
    port: 80
    targetPort: 8080
    protocol: TCP
</code></pre>

<p>In general, a <a href="https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies" rel="noreferrer">Service</a> <em>does</em> provide load balancing across the selected pods.  You can see this using a debugging shell:</p>

<pre><code>kubectl run --namespace=prod debug \
            --generator=run-pod/v1 \
            --image=busybox --rm --stdin --tty -- \
            /bin/sh
wget -O- http://internal-service-cip/
</code></pre>

<p>(The first command is the Kubernetes equivalent of <code>docker run --rm -it busybox sh</code>, but launches it in your Kubernetes namespace.)</p>

<p>Under the hood, <a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#port-forward" rel="noreferrer"><code>kubectl port-forward</code></a> always connects to some single pod (emphasis mine):</p>

<blockquote>
  <p>Forward one or more local ports <strong>to a pod</strong>.  ...  If there are multiple pods matching the criteria, a pod will be selected automatically.</p>
</blockquote>

<p>So if you <code>kubectl port-forward service/internal-service-cip</code>, internally it looks at the Endpoints of the Service, picks one of the matching pods, and port-forwards to that pod.  Since every connection goes to the same pod, it looks like there's no load balancing in this scenario.</p>
