Hi Abhijeet,
Problem statement is, how do you drain a node [...] L7 constructs like "Connection:
close" or "GOAWAY
h2 frames"
[...] > * For any map (L4 client IP lookup) based solution, I was unable to
find any http-request operation that sets "drain mode".
Indeed the managed drain mode is an all-or-nothing at the moment. The
"only" missing feature to fully replicate it with http-request rules
would be a way to trigger the GOAWAY H2 frames (which isn't possible at
the moment, as far as I can tell).
But in the meantime, the following might do the job:
frontend foo
# tcp-request connection sees the "real" src in accept-proxy
listeners, according to 7.3.3#src
tcp-request connection set-var(txn.src_l4_ip) src
# assuming a stick-table here, but should work just fine with
maps/lists too
http-after-response set-header Connection close if {
var(txn.src_l4_ip),in_table(draining-clients) }
At that point we have the HTTP/1.1 part handled but that was easy
enough... Now for H2 there's no good way that I can see.
But I can think of a few hacky solutions that might work (ie would need
to test them in practice):
1. Returning an HTTP 421, which H2 clients should interpret as being
instructed to use a different connection to issue the request, which
should also be automatically retried in browsers
2. Adding an Alt-Svc to those responses advertising http/1.1 explicitly,
which clients should pick up and prefer (then they either land on
another LB while establishing the new connection, or get Connection-close'd)
3. Returning an HTTP 426, instructing the client to "upgrade" to
http/1.1 (not sure how that interacts with ALPN but the spec seems to
suggest that the client would give the upgrade request priority), which
ends up with the same outcome as the Alt-Svc solution if it works
Of course it'd be many times better to be able to just trigger a GOAWAY
instead, but it was fun to think about more "creative" options, so here
they are.
Tristan