Is it possible to use sticky lb in k8s based on JWT?

Is it possible to use sticky load balancing in k8s based on UserID inside JWT?
This is needed to ensure all clients (e.g. web and mobile) of some user will be served (using Websocket) by same backend instance.

Somewhat related question: what happens on deploying new backend version, i.e. when each backend instance will restart one-by-one and all clients connected by websockets will auto-reconnect? Will load balancing handle this case nicely, or it might result in all clients occasionally connected to same instance?

We don’t currently have an official k8s helm chart that we support (and I have no experience with k8s in general) so I don’t think really speak to specifics there.

For the load balancing policies, yes that’s something Caddy could do, but probably not via the built-in policies.

The policies are totally pluggable though, so you could write your own to do what you need. You can probably take the code for the header or cookie policies as your basis, make your own Caddy module called http.reverse_proxy.selection_policies.jwt for example, and then build Caddy with that plugin.

The code for all the selection policies are in here (look for CookieHashSelection for example):

That entirely depends on your rollout strategy. If you remove all but one instance and your websocket connection retry logic is faster than your instance restarts, then yeah that might happen.

Thanks. My question about using JWT for load balancing was related to using existing module Modules - Caddy Documentation which will provide placeholder {http.auth.user.id} to somehow plug it into load balancing rules - is it possible to provide this placeholder as a hashing key for load balancing? Or only way is to implement own module?

Ah, thanks. That was unclear.

For next time, please fill out the help topic template, so we understand what you’re trying to do. Otherwise, we have to make assumptions, and that wastes time for both of us.

Hmm, one somewhat roundabout way to do it might be to use request_header immediately after the jwt handler to set a header on the request which could then be read by the header policy.

route {
	jwt {
		...
	}
	request_header X-User-Id {http.auth.user.id}
}

reverse_proxy api:8001 api:8002 api:8003 {
	lb_policy header X-User-Id
	...
}

I’m not certain this’ll work, but it might!

This topic was automatically closed after 30 days. New replies are no longer allowed.