Session persistence / sticky cookie in front proxy mode

3,281 views
Skip to first unread message

Sathish Santhanam

unread,
Feb 23, 2018, 12:41:19 PM2/23/18
to envoy-users
I am evaluating Envoy as a front/edge proxy. We have a use case where the requests from the same client should use the same backend server.
Is there a way to achieve sticky sessions when using Envoy? Note that this behavior is required only for few requests identifiable by the url path pattern (say, /cometd)

Thanks.

Mark McBride

unread,
Feb 23, 2018, 1:02:28 PM2/23/18
to Sathish Santhanam, envoy-users
Hi Sathish, you should be able to accomplish this by using a hashing load balancer (https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/load_balancing.html#arch-overview-load-balancing-types), and having your clients specify a header that can be used to hash to a consistent backend server (https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto.html#envoy-api-msg-routeaction-hashpolicy). If you only want this behavior for a few endpoints it's probably a good idea to set up one cluster that uses the hashing load balancer specific for these routes, and then set up another cluster with the same endpoints that uses a non-hashing load balancer.

   ---Mark

--
You received this message because you are subscribed to the Google Groups "envoy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to envoy-users...@googlegroups.com.
To post to this group, send email to envoy...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/envoy-users/8da20654-8631-41b1-9927-1afab789655f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sathish Santhanam

unread,
Feb 23, 2018, 4:47:27 PM2/23/18
to envoy-users
Hi Mark,
Is there a way to achieve this without requiring the client to send a new header? We may not have the luxury to make this change in our code base.

I am thinking of something like this:
1. When a request come for the first time, it won't have any special header or cookie to hash on. Envoy can pick a random backend host and send this request. ==> This seems to be possible
2. On the way back, add a cookie such that it represents the backend server that served that request (the cookie should hash to the same backend server next time when the request comes with that cookie) ==> I don't know how to do this with Envoy
3. When the client sends the request again, it will have the cookie that can be used on the hash policy such that it lands on the same back end server.

Any way to do step 2 above?

Thanks a lot.

Sathish

Mark McBride

unread,
Feb 23, 2018, 4:58:57 PM2/23/18
to Sathish Santhanam, envoy-users
Yup, see https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto.html#envoy-api-msg-routeconfiguration. You can specify headers to add at the listener, vhost or routeaction level. You can substitute any of the values available in the access logging formatter (https://www.envoyproxy.io/docs/envoy/v1.5.0/configuration/access_log.html#config-access-log-format). Note that with Cookies it'll be challenging if there is more than one cookie set, as other cookies will modify the hashed value. E.g. Cookie: stickyhost=192.168.10.12:3000,userid=some_user will not hash the same as stickyhost=192.168.10.12:3000,userid=some_other_user

   ---Mark

Sathish Santhanam

unread,
Feb 23, 2018, 7:50:25 PM2/23/18
to envoy-users
As per this - https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto.html#envoy-api-field-routeaction-hashpolicy-cookie

the session affinity should work out of the box (pl. refer to the 'Generated' option in the above doc). However, I am not able to get this working when I test. I don't see Envoy generating any cookie and sending it in the response and the subsequent requests from the same client goes to different back end servers.

Here is my config:

static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 12060 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: csr
hash_policy:
cookie:
name: csr_id
http_filters:
- name: envoy.router
clusters:
- name: csr
connect_timeout: 0.25s
type: STATIC
lb_policy: RING_HASH
hosts:
- socket_address: { address: <my_ip>, port_value: 6001 }
- socket_address: { address: <my_ip>, port_value: 7001 }
- socket_address: { address: <my_ip>, port_value: 8001 }




Sathish Santhanam

unread,
Feb 23, 2018, 8:14:57 PM2/23/18
to envoy-users
Adding a 'ttl' to the 'cookie' field seems to solve the problem. I see cookie getting generated and sticky balancing working.

Thanks a lot Mark!

Sathish

rras...@gmail.com

unread,
Jan 3, 2019, 3:29:22 PM1/3/19
to envoy-users
Hi, 

I was exploring the same option. 

Thanks to Mark's and Satish's comments I also made it work. Thanks a million guys!

Regards,
Rashid

Ramesh Bhanan

unread,
Feb 12, 2021, 1:32:48 AM2/12/21
to envoy-users
Just wanted understand what happens in following case in a 2 node cluster with ttl=300:
1. client One has got csr_id='c_one' and assigned to host m1.
2. client Two has got csr_id='c_two' and assigned to host m2.
3. host m2 went down and started serving from m1.
4. when m2 comes up,... how to make sure the  request coming from client Two is continued to serve from m1 for ttl time.

Ramya Karuna

unread,
Jun 7, 2021, 11:16:32 AM6/7/21
to envoy-users
Hi Ramesh Bhanan,

Did you get the solution for the above problem you mentioned ? If so, can you please share it here ?

Thanks,
Ramya

Reply all
Reply to author
Forward
0 new messages