<p>I have the following <a href="https://kubernetes.io/docs/concepts/services-networking/service/#headless-services" rel="nofollow noreferrer">headless service</a> in my kubernetes cluster :</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: foobar
  name: foobar
spec:
  clusterIP: None
  clusterIPs:
  - None
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: foobar
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  type: ClusterIP
</code></pre>
<p>Behind are running couple of pods managed by a statefulset.</p>
<p><strong>Lets try to reach my pods individually :</strong></p>
<ul>
<li>Running an alpine pod to contact my pods :</li>
</ul>
<pre class="lang-bash prettyprint-override"><code>&gt; kubectl run alpine -it --tty --image=alpine -- sh
</code></pre>
<ul>
<li>Adding curl to fetch webpage :</li>
</ul>
<pre><code>alpine#&gt; add apk curl
</code></pre>
<ul>
<li>I can curl into each of my pods :</li>
</ul>
<pre><code>alpine#&gt; curl -s pod-1.foobar
hello from pod 1
alpine#&gt; curl -s pod-2.foobar
hello from pod 2
</code></pre>
<p>It works just as expected.</p>
<p>Now I want to have a service that will loadbalance between my pods.
Let's try to use that same <code>foobar</code> service :</p>
<pre><code>alpine#&gt; curl -s foobar
hello from pod 1
alpine#&gt; curl -s foobar
hello from pod 2
</code></pre>
<p>It works just well. At least almost : In my headless service, I have specified <code>sessionAffinity</code>. As soon as I run a <code>curl</code> to a pod, I should stick to it.</p>
<p>I've tried the exact same test with a <em>normal</em> service (not headless) and this time it works as expected. It load balances between pods at first run BUT then stick to the same pod afterwards.</p>
<p><strong>Why sessionAffinity doesn't work on a headless service ?</strong></p>

Will
<p>The affinity capability is provided by kube-proxy, only connection establish thru the proxy can have the client IP &quot;stick&quot; to a particular pod for a period of time. In case of headless, your client is given a list of pod IP(s) and it is up to your client app. to select which IP to connect. Because the order of IP(s) in the list is not always the same, typical app. that always pick the first IP will result to connect to the backend pod randomly.</p>
