<p>I create a deployment which results in 4 pods existing across 2 nodes.</p>

<p>I then expose these pods via a service which results in the following cluster IP and pod endpoints:</p>

<pre><code>Name:                     s-flask
......
IP:                       10.110.201.8
Port:                     &lt;unset&gt;  9080/TCP
TargetPort:               5000/TCP
NodePort:                 &lt;unset&gt;  30817/TCP
Endpoints:                
192.168.251.131:5000,192.168.251.132:5000,192.168.251.134:5000 + 1 more...
</code></pre>

<p>If accessing the service internally via the cluster IP, the requests are balanced across both nodes and all pods, not just the pods on a single node (e.g. like access via a nodePort).</p>

<p>I know kubernetes uses IP tables to balance requests across pods on a single node, but I can't find any documentation which explains how kubernetes balances internal service requests across multiple nodes (we are don't use load balancers or ingress for internal service load balancing).</p>

<p>The cluster IP itself is virtual, the only way I think this can work, is if the cluster IP is round robin mapped to a service endpoint IP address, where the client would have to look up the cluster IP / service and select an endpoint IP?</p>

<p>Everything you need is explained in second paragraph "Virtual IPs and service proxies" of this documentation: <a href="https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service" rel="noreferrer">https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service</a></p>

<p>In nutshell: currently, depending on the proxy mode, for ClusterIP it's just round robin/random. It's done by kube-proxy, which runs on each nodes, proxies UDP and TCP and provides load balancing. </p>

<p>It's better to think of kubernetes as a whole rather than specific nodes. Abstraction does its thing here.</p>

<p>Hope it answers your question.</p>
