<p>I have following setup deployed on an Azure Kubernetes Services (K8S version 1.18.14)  cluster:</p>
<ul>
<li>Nginx installed via <a href="https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx" rel="nofollow noreferrer">helm chart</a> and scaled down to a single instance. It is deployed in namespace &quot;ingress&quot;.</li>
<li>A simple stateful application (App A) deployed in a separate namespace with 5 replicas. The &quot;statefulness&quot; of the application is represented by a single random int generated at startup. The application exposes one http end point that just returns the random int. It is deployed in namespace &quot;test&quot;.</li>
<li>service A of type ClusterIP exposing the http port of App A and also deployed in namespace &quot;test&quot;:</li>
</ul>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: stateful-service
  namespace: &quot;test&quot;
spec:
  selector:
    app: stateful
  ports:
    - name: http
      port: 80
      targetPort: 8080
  type: ClusterIP
</code></pre>
<ul>
<li>service B of type &quot;ExternalName&quot; (proxy service) pointing to the cluster name Service A deployed in namespace &quot;ingress&quot;:</li>
</ul>
<pre><code>apiVersion: &quot;v1&quot;
kind: &quot;Service&quot;
metadata:
  name: &quot;stateful-proxy-service&quot;
  namespace: &quot;ingress&quot;
spec:
  type: &quot;ExternalName&quot;
  externalName: &quot;stateful-service.test.svc.cluster.local&quot;
</code></pre>
<ul>
<li>ingress descriptor for the application with sticky sessions enabled:</li>
</ul>
<pre><code>apiVersion: extensions/v1beta1
kind: &quot;Ingress&quot;
metadata:
  annotations:
    kubernetes.io/ingress.class: internal
    nginx.ingress.kubernetes.io/force-ssl-redirect: &quot;false&quot;
    nginx.ingress.kubernetes.io/affinity: &quot;cookie&quot;
    nginx.ingress.kubernetes.io/session-cookie-name: &quot;route&quot;
  name: &quot;ingress-stateful&quot;
  namespace: &quot;ingress&quot;
spec:
  rules:
    - host: stateful.foo.bar
      http:
        paths:
          - path: /
            backend:
              serviceName: &quot;stateful-proxy-service&quot;
              servicePort: 80
</code></pre>
<p>The issue is that sticky sessions is not working correctly with this setup. The &quot;route&quot; cookie is issued but does not guarantee &quot;stickiness&quot;. Requests are dispatched to different pods of the backend service although the same sticky session cookie is sent. To be precise the pod changes every 100 requests which seems to be the default round-robin setting - it is the same also without sticky sessions enabled.</p>
<p>I was able to make sticky sessions work when everything is deployed in the same namespace and no &quot;proxy&quot; service is used. Then it is OK - request carrying the same &quot;route&quot; cookie always land on the same pod.</p>
<p>However my setup uses multiple namespaces and using a proxy service is the recommended way of using ingress on applications deployed in other namespaces.</p>
<p>Any ideas how to resolve this?</p>

vap78
<p>This is a community wiki answer. Feel free to expand it.</p>
<p>There are two ways to resolve this issue:</p>
<ol>
<li><p>Common approach: Deploy your Ingress rules in the same namespace where the app that they configure resides.</p>
</li>
<li><p>Potentially tricky approach: try to use the <code>ExternalName</code> type of Service. You can define ingress and a service with <code>ExternalName</code> type in namespace A, while the <code>ExternalName</code> points to DNS of the service in namespace B. There are two well-written answers explaining this approach in more detail:</p>
</li>
</ol>
<ul>
<li><p><a href="https://stackoverflow.com/a/51899301/11560878">aurelius' way</a></p>
</li>
<li><p><a href="https://stackoverflow.com/a/61753491/11560878">garlicFrancium's way</a></p>
</li>
</ul>
<p>Notice the <a href="https://kubernetes.io/docs/concepts/services-networking/service/#externalname" rel="nofollow noreferrer">official docs</a> and bear in mind that:</p>
<blockquote>
<p><strong>Warning:</strong> You may have trouble using ExternalName for some common protocols, including HTTP and HTTPS. If you use ExternalName then the
hostname used by clients inside your cluster is different from the
name that the ExternalName references.</p>
<p>For protocols that use hostnames this difference may lead to errors or
unexpected responses. HTTP requests will have a <code>Host:</code> header that
the origin server does not recognize; TLS servers will not be able to
provide a certificate matching the hostname that the client connected
to.</p>
</blockquote>
