kubernetes-sigs / gateway-api

Repository for the next iteration of composite service (e.g. Ingress) and load balancing APIs.
https://gateway-api.sigs.k8s.io
Apache License 2.0
1.75k stars 455 forks source link

GEP: Session persistence behavior #1619

Open gcs278 opened 1 year ago

gcs278 commented 1 year ago

What would you like to be added:

See Goals/Non Goals section below. I originally created this as a Google Doc, so I'm keeping the source format below. It's a lot of information for a simple request, but hopefully it describes the context of our request sufficiently. Please let me know if you disagree with verbiage, something is incorrect, have feedback on our objective, or have a suggestion on the next steps we could take.

Why this is needed:

Overview

At the November 28th, 2022 SIG Gateway API meeting, we discussed the idea of standardizing and documenting session persistence (also known as session stickiness). Our request, at a minimum, is that we'd like Gateway API implementations to be required to document how they achieve session persistence and what is their default functionality.

It was recommended that we first generate discussion for how we describe session persistence, agree on how it is achieved, and find out which implementers support session persistence. Once information is gathered, we can move forward with a conformance test for session persistence if deemed appropriate. Furthermore, this information can be used for developing a Gateway API spec to configure session persistence in the future.

Goals

Non-Goals

User Stories

Story: As a user of some Gateway API implementation who depends on session persistence, I need to know whether an alternative Gateway API implementation supports session persistence, so that I know whether switching from one implementation to the other will break my application.

Resolution: Implementations should document how they achieve session persistence.

Story: As the administrator for a load balancer/WAF/proxy in front of a Gateway API implementation, I need to know how a given Gateway API implementation implements session persistence, so that I know whether my LB/WAF/proxy will break it (for example, by filtering cookies or by obscuring source addresses)

Resolution: Implementations should document how they achieve session persistence.

Defining Session Persistence

Session persistence is the act of using application layer information to direct a client request to the same backend server for the duration of a "session". Session persistence, when properly configured, guarantees a user will be directed to the same server. Persistence is an exception to load balancing: a persistent client request bypasses the proxy's load balancing algorithm, going directly to a backend server it has previously established a session with.

Some of the concerns of session persistence are the duration and expiration of the session, security of the transaction stream, and storage of the context or state. Application developers use session persistence to improve the performance and reduce overall storage needs by aligning each transaction and its cached data with the same server.

Session persistence is not to be confused with session affinity, which uses information below the application layer to maintain a client request to a single server. Session affinity can be considered a weaker form of session persistence: it is not guaranteed to persist a connection to the same backend server.

Achieving Session Persistence

True session persistence can be achieved by a few different mechanisms:

Cookie-Based Session Persistence

The most common mechanism is by using cookies (described by RFC6265) with the set-cookie HTTP response header. A client will use the provided value in the set-cookie response header in a cookie request header in subsequent requests. Proxies can use this cookie header to maintain a persistent connection to a single backend server on behalf of the client.

Header-Based Session Persistence

Header-based stateful sessions are achieved by a backend providing an arbitrarily-named HTTP response header and the client using the same arbitrarily-named header in subsequent HTTP requests. Proxies can use this arbitrarily-named header to maintain a persistent connection to a single backend server on behalf of the client.

Session Affinity

Session affinity can be achieved by deterministic load balancing algorithms or a proxy feature that tracks IP-to-backend associations such as HAProxy's stick tables or Cilium's session affinity.

Implementations

To help understand the scope of session persistence and session affinity, we've started to put together a table describing how each implementation achieves it. Input from implementations is appreciated to complete this table.

Implementation Proxy Type Session Persistence Session Affinity Notes
Acnodal EPIC Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Apache APISIX Nginx ? ? ?
Cilium eBPF No Source IP Address Cilium does not have a true session persistence feature, but does implement session affinity by default using source IP address.
Contour Envoy Cookie-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Emissary-Ingress (Ambassador API Gateway) Envoy Cookie-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Envoy Gateway Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Flomesh Service Mesh Pipy ? ? ?
Gloo Edge 2.0 Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Google Kubernetes Engine ? ? ? ?
HAProxy Ingress HAProxy Cookie-Based Stick Tables HAProxy implements cookie-based stateful sessions via the forwardfor option. Stick tables implement stickiness via client attributes.
HashiCorp Consul Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash ?
Istio Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions.Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
Kong Kong Cookie-Based ? Kong has the session plugin which manages persistent sessions with cookie-based stateful sessions.
Kuma Envoy Cookie-Based, Header-Based Consistent Hashing via Maglev and Ring Hash Envoy proxy implements both cookie-based and header-based stateful sessions. Envoy offers Maglev and Ring Hash load balancing algorithms that provide consistent hashing.
LiteSpeed Ingress Controller ? ? ? ?
NGINX Kubernetes Gateway Nginx ? ? ?
Traefik Traefik Proxy Cookie-Based No Traefik implements cookied-based stateful sessions. Docs mention consistent hashing, but Traefik only offers round robin (not consistent).

Conformance Testing

Until the Gateway API spec supports configuring session persistence, we are unsure of the value of conformance testing. Conformance testing will be valuable once we establish a testable definition of session persistence and the ability for Gateway API objects to config it.

Proposal: Gateway API Specification for Session Persistence

Our goal is for Gateway API to specify a requirement for implementations to document session persistence. The exact specification section/page for the requirement is still to be determined. The requirement is proposed as the following:

Session persistence MAY be implemented. The specific mechanism by which session persistence works is implementation-specific. However, implementations MUST document whether they implement session persistence, and how. For example, if session persistence is implemented using a cookie, the implementation's documentation must indicate the same and document salient details (such as the format and maximum lengths of cookie names and values).

Open Questions

  1. Does Gateway API enforce documentation-based requirements on implementation?
candita commented 1 year ago

@gcs278 I really like the chart in this document. It would be great to have this chart for even more features implemented by each of the Gateway API implementations, along the lines of this chart, comparing Kubernetes Ingress Controllers implementations: https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k/edit#gid=907731238 @robscott @shaneutt @youngnick do you know of any plans to create such an implementation chart as a part of the Gateway API documentation?

sunjayBhatia commented 1 year ago

Contour does not have session persistence/affinity by default, but you can opt-in following this documentation (though we use session affinity/sticky sessions where this issue may instead use session persistence):

costinm commented 1 year ago

An API we should probably consider is the existing https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies - Service.sessionAffinity=ClientIP as well as the proposed https://github.com/kubernetes-sigs/mcs-api/blob/master/pkg/apis/v1alpha1/serviceimport.go#L70 ( in context of the proposal to support ServiceImport in gateway ). The Service affinity seems to be specific to L4 - but L7 will also have same affinity.

I think if a Service has this affinity defined the Gateway and any per-node GAMMA implementations should NOT use it blindly ( i.e. have all connections go to a single pod ), but instead enable some form of equivalent affinity using the original client.

Any API we define for session persistence should include how it interacts with the defined sessionAffinity.

k8s-triage-robot commented 1 year ago

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

youngnick commented 1 year ago

/lifecycle frozen