<p>I am looking for a service proxy (or load-balancer) with URL-based affinity.</p>

<p>This is for using in Kubernetes, inside the cluster: I am looking for an "internal" load balancer, I don't need to expose the service outside.</p>

<p>By default, the Service in Kubernetes is using a "round robin" algorithm.</p>

<p>I would like some affinity based on a part of the HTTP URL: a 1st request would go to a random pod, and subsequent requests that use the same URL would (preferably) go to the same pod.</p>

<p>I have read some doc about affinity based on sourceIP, does this exist based on URLs ?</p>

<p>I have quickly read about Envoy, maybe using the "Ring hash" load-balancing algorithm would do, but I don't know if it's possible to hash based on the URL.</p>

<p>Maybe using the "ipvs" proxy-mode of kube-proxy (<a href="https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-ipvs" rel="noreferrer">https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-ipvs</a>) would do, but I see only "destination hashing" and "source hashing" as load balancing algorithms, and I don't know how to configure it either.</p>

<p>As you have already mentioned, <a href="https://github.com/kubernetes/kubernetes/tree/master/pkg/proxy/ipvs" rel="nofollow noreferrer">IPVS</a> proxy algorithm defines source and destination IP addresses in order to generate a unique hash key for load balancing. However, it operates in L4 transport layer  of intercepting network traffic for TCP or UDP services. Therefore it might be difficult to interact with HTTP request and make a route decision based on URL path.</p>

<p><a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/" rel="nofollow noreferrer">Envoy</a> proxy represents consistent hashing via <a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v1/route_config/route#config-http-conn-man-route-table-hash-policy" rel="nofollow noreferrer">HTTP header</a> values, specified inside <a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/http_routing#arch-overview-http-routing" rel="nofollow noreferrer">HTTP router filter</a> along with <a href="https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/load_balancing.html#ring-hash" rel="nofollow noreferrer">Ring hash</a> load balancing policy. Therefore, you can specify the appropriate header name in Hash policy that can be used to obtain the hash key for load balancing.</p>

<pre><code>hash_policy:
  header:
    header_name: "x-url"
</code></pre>

<p>Alternatively, you can consider to use <a href="https://istio.io" rel="nofollow noreferrer">Istio</a> as an intermediate proxy which uses extended version of Envoy. Kubernetes services are involved into the service mesh by deploying a special sidecar proxy throughout your environment that intercepts all network communication between microservices. Istio can be also used for <a href="https://istio.io/docs/reference/config/networking/v1alpha3/destination-rule/#LoadBalancerSettings-ConsistentHashLB" rel="nofollow noreferrer">Hash</a> consistent load balancing with session affinity based on HTTP headers via <a href="https://istio.io/docs/reference/config/networking/v1alpha3/destination-rule/" rel="nofollow noreferrer">DestinationRule</a> resource.</p>

<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: example
spec:
  host: my-service.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      consistentHash:
        httpHeaderName: x-url
</code></pre>
