diff --git a/geps/gep-1619.md b/geps/gep-1619.md
index 965f80d1d8..5511fd7c23 100644
--- a/geps/gep-1619.md
+++ b/geps/gep-1619.md
@@ -3,9 +3,11 @@
* Issue: [#1619](https://github.com/kubernetes-sigs/gateway-api/issues/1619)
* Status: Provisional
-(See definitions in [GEP Status][/contributing/gep#status].)
+(See status definitions [here](overview.md#status).)
-## Graduation Criteria for Implementable Status
+## Graduation Criteria
+
+### Implementable
This GEP was accidentally merged as Provisional before the required approval
from 2 maintainers had been received. Before this graduates to implementable,
@@ -20,6 +22,12 @@ graduate:
2. Should we leave room for configuring different forms of Session Persistence?
If so, what would that look like?
+### Standard
+
+Before this GEP graduates to the Standard channel, we must fulfill the following criteria:
+
+- Sign-off from the GAMMA leads to ensure service mesh gets fully considered.
+
## TLDR
This GEP initially proposes a definitions for session persistence, followed by the definition of an API spec for
@@ -49,6 +57,7 @@ session affinity, as this design is expected to be addressed within a separate G
Session persistence is when a client request is directed to the same backend server for the duration of a "session". It is achieved when a client directly provides information, such as a header, that a proxy uses as a reference to direct traffic to a specific 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.
Session persistence enables more efficient application workflows:
+
1. Better performance: Maintaining a single session allows a server to cache information about a client locally reducing the need for servers to exchange session data and overall storage needs.
2. Seamless client experience: Clients can reconnect to the same server without re-authenticating or re-entering their information.
@@ -56,6 +65,18 @@ Some of the concerns of session persistence are the duration and expiration of t
Session affinity, not to be confused with session persistence, uses an existing attribute of the request to consistently send to the same backend. Session affinity can be considered a weaker form of session persistence: it is not guaranteed to persist a connection to the same backend server if certain attributes of the request or the backends are changed.
+#### Session vs. Session Persistence
+
+It's important to understand the subtle differences between a session and session persistence. A session is a period
+of interaction between a client and server where a client identifies itself using a session ID. Session persistence
+ensures the continuity of this session by directing the client's requests to the same backend server throughout the
+entire session. Session persistence becomes essential for load-balanced applications, but is unnecessary when only a
+single backend is in use.
+
+A session can exist without session persistence, but the session data must be accessible to every backend in the server
+pool. However, as we defined it, session persistence cannot exist without a session, as the initiation of session
+persistence also initiates a session.
+
### Security and Privacy Implications
Session persistence can introduce security and privacy vulnerabilities if not properly implemented. These vulnerabilities can include:
@@ -95,9 +116,10 @@ sources, including the gateway, intermediary gateway, backend, a sidecar in a ba
component.
Let's consider a simple implementation comprised of gateways and backends. The following rules apply based on who initiates the session:
+
- If the gateway initiates the session, the backend will be presented with session attributes regardless if it enabled them.
- If the backend initiates the session, the gateway should allow this and not force persistent connections, unless
- specifically configured to[^1]. The gateway may decode and alter the cookie established by the backend to achieve
+ specifically configured to. The gateway may decode and alter the cookie established by the backend to achieve
session persistence.
It's important to note that we can have more complex implementations which involve traversing global load balancers,
@@ -211,8 +233,8 @@ sequenceDiagram
R->>R: Initiates session by
adding set-cookie header
R-->>-G: Response
[set-cookie]
G->>G: Add or modify
set-cookie header
- G-->>-C: Response
[set-cookie]
- Note right of G: [set-cookie] indicates a response
with a set-cookie header.
May include other set-cookie
headers from backend or GLB.
+ G-->>-C: Response
[set-cookie*]
+ Note right of G: [set-cookie] indicates a response
with a set-cookie header
[set-cookie*] indicates a response with a
modified or additional set-cookie header
C->>C: Create Cookie
from set-cookie header
Note right of C: [cookie] indicates a request
with one or more cookies
C->>+G: Request Web Page
[cookie]
@@ -220,7 +242,8 @@ sequenceDiagram
G->>+R: Request
[cookie]
R->>R: Consistent lookup of backend
using cookie value
R->>+B: Request
[cookie]
- B-->>-G: Response
+ B-->>-R: Response
+ R-->>-G: Response
G-->>-C: Response
```
@@ -248,15 +271,20 @@ persistent connections to the same backend server.
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](https://www.haproxy.com/blog/introduction-to-haproxy-stick-tables/) or [Cilium's session affinity](https://docs.cilium.io/en/v1.12/gettingstarted/kubeproxy-free/#id2).
We can also examine how session persistence and session affinity functionally work together, by framing the relationship into a two tiered logical decision made by the data plane:
+
1. If the request contains a session persistence identity (e.g. a cookie or header), then route it directly to the backend it has previously established a session with.
2. If no session persistence identity is present, load balance as per load balancing configuration, taking into account the session affinity configuration (e.g. by utilizing a hashing algorithm that is deterministic).
This tiered decision-based logic is consistent with the idea that session persistence is an exception to load balancing. Though there are different ways to frame this relationship, this design will influence the separation between persistence and affinity API design.
+We acknowledge the discrepancies in the definitions of session persistence and session affinity in the industry.
+However, for the purpose of establishing a common language for this GEP, we have opted to utilize these definitions.
### Implementations
+
In this section, we will describe how implementations achieve session persistence, along with a breakdown of related configuration options. Input from implementations is appreciated to complete this information.
In the following tables, we will example two types of APIs:
+
1. Dataplane APIs
2. Implementation APIs
@@ -265,20 +293,25 @@ Generally, the implementation API programs the dataplane API; however these two
| **Technology** | **Technology Type** | **Session Persistence Type** | **Configuration Options** | **Configuration Association (Global, Gateway, Route, or Backends)** | **Notes** |
|--- |--- |--- |--- |--- |--- |
| Acnodal EPIC | Implementation (Envoy) | N/A | Supports Gateway API Only* | N/A | *Acnodal Epic solely uses Gateway API; therefore, it doesn’t yet have a way to configure session persistence. [Acnodal EPIC Docs](https://www.epick8sgw.io/docs/) |
+| Amazon Elastic Kubernetes Service | Implementation / Dataplane | N/A | Supports Gateway API Only* | N/A | *Amazon Elastic Kubernetes Service solely uses Gateway API; therefore, it doesn’t yet have a way to configure session persistence. [Amazon Elastic Kubernetes Service Docs](https://www.gateway-api-controller.eks.aws.dev/) |
| Apache APISIX | Implementation (Nginx) | [Cookie-Based](https://apisix.apache.org/docs/apisix/admin-api/#upstream) | hash_on=[vars \| header \| cookie \| consumer]
key=cookie_name | [Upstream](https://apisix.apache.org/docs/apisix/admin-api/#upstream) (Route or Backends) | N/A |
| | Implementation (Nginx) | [Header-Based](https://apisix.apache.org/docs/apisix/terminology/upstream/#header) | hash_on=[vars \| header \| cookie \| consumer]
key=header_name | [Upstream](https://apisix.apache.org/docs/apisix/admin-api/#upstream) (Route or Backends) | N/A |
| Apache httpd | Web Server | [Cookie-Based / URL-Encoded](https://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html) | Cookie Attributes | N/A | N/A |
+| Avi Kubernetes Operator | Implementation / Dataplane | [Cookie-Based](https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/administration/GUID-8B5C8D64-2B69-4C95-86A5-C5396CB9E51F.html) | Shared Persistence Cookie Mode=[Insert \| Prefix \| Rewrite] Cookie Name=name Cookie Domain=domain Cookie Fallback=domain Cookie Path=path Cookie Garbling Cookie Type=[ Session Cookie \| Persistence Cookie] Http Only Flag Secure Flag Max Idle Time=time Max Cookie Age=time | [Route](https://docs.vmware.com/en/VMware-NSX-Advanced-Load-Balancer/1.11/Avi-Kubernetes-Operator-Guide/GUID-E8F3C338-46FB-412E-8B46-16EE2C12A8AF.html) | N/A |
+| Azure Application Gateway for Containers | | | | | |
+| BIG-IP Kubernetes Gateway | | | | | |
| Cilium | Implementation / Dataplane | None | None | None | Cilium has no documented way of doing session persistence. [Cilium Docs](https://cilium.io/) |
| Contour | Implementation (Envoy) | [Cookie-Based](https://projectcontour.io/docs/1.24/config/api/#projectcontour.io/v1.CookieRewritePolicy) | Name=name
pathRewrite=path
domainRewrite=domain
secure
sameSite | [Route](https://projectcontour.io/docs/1.24/config/api/#projectcontour.io/v1.Route) and [Service](https://projectcontour.io/docs/1.24/config/api/#projectcontour.io/v1.Service) (Backends) | Envoy does not natively support cookie attribute rewriting nor adding attributes other than path and TTL, but rewriting and adding additional attributes is possible via Lua ([Contour design reference](https://github.com/projectcontour/contour/blob/main/design/cookie-rewrite-design.md), [Envoy Issue](https://github.com/envoyproxy/envoy/issues/15612)). |
+| Easegress | | | | | |
| Emissary-Ingress | Implementation (Envoy) | [Cookie-Based](https://www.getambassador.io/docs/emissary/latest/topics/running/load-balancer#cookie) | Name=name
Path=path
TTL=duration | [Module or Mapping](https://www.getambassador.io/docs/emissary/latest/topics/running/load-balancer#cookie) (Global or Route) | N/A |
| | | [Header-Based](https://www.getambassador.io/docs/emissary/latest/topics/running/load-balancer#header) | Name=name | [Module or Mapping](https://www.getambassador.io/docs/emissary/latest/topics/running/load-balancer#cookie) (Global or Route) | N/A |
| Envoy | Dataplane | [Cookie-Based](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/stateful_session/cookie/v3/cookie.proto) | Name=name
Path=path
TTL=duration | [HttpConnectionManager](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto) (Route) | Envoy does not natively support cookie attribute rewriting nor adding attributes other than path and TTL, but rewriting and adding additional attributes is possible via Lua ([Contour design reference](https://github.com/projectcontour/contour/blob/main/design/cookie-rewrite-design.md), [Envoy Issue](https://github.com/envoyproxy/envoy/issues/15612)). |
| | | [Header-Based](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/stateful_session/header/v3/header.proto) | Name=name | [HttpConnectionManager](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto) (Route) | N/A |
| Envoy Gateway | Implementation (Envoy) | N/A | Supports Gateway API Only* | N/A | *Envoy Gateway solely uses Gateway API; therefore, it doesn’t yet have a way to configure session persistence. [Envoy Gateway Docs](https://gateway.envoyproxy.io/v0.3.0/index.html) |
| Flomesh Service Mesh | Implementation / Dataplane (Pipy) | ? | ? | ? | ? |
-| Gloo Edge 2.0 | Implementation (Envoy) | [Cookie-Based](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#cookie) | Name=name
Path=path
TTL=duration | [Route](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#route) (Route) | N/A |
+| Gloo Gateway | Implementation (Envoy) | [Cookie-Based](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#cookie) | Name=name Path=path TTL=duration | [Route](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#route) (Route) | N/A |
| | | [Header-Based](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#hashpolicy) | Name=name | [Route](https://docs.solo.io/gloo-edge/latest/reference/api/envoy/api/v2/route/route.proto.sk/#route) (Route) | N/A |
-| Google CloudRun | Implementation / Dataplane | [Cookie-Based](https://cloud.google.com/run/docs/configuring/session-affinity) | Enabled / Disabled | [Service](https://cloud.google.com/run/docs/configuring/session-affinity) (Backends) | Only allowed to turn off or on, no other configuration items |
+| Google CloudRun | Dataplane | [Cookie-Based](https://cloud.google.com/run/docs/configuring/session-affinity) | Enabled / Disabled | [Service](https://cloud.google.com/run/docs/configuring/session-affinity) (Backends) | Only allowed to turn off or on, no other configuration items |
| Google Kubernetes Engine | Implementation / Dataplane | [Cookie-Based](https://cloud.google.com/load-balancing/docs/backend-service#session_affinity) | GENERATED_COOKIE or HTTP_COOKIE=name
cookieTtlSec | [Backend Policy](https://cloud.google.com/kubernetes-engine/docs/how-to/configure-gateway-resources#session_affinity) (Backends) | Google Kubernetes Engine [lists](https://cloud.google.com/load-balancing/docs/backend-service#bs-session-affinity) the products that can do persistence/affinity mode. All persistence/affinity options are exclusive and can’t be used at the same time.
Note: Google Kubernetes Engine defines everything (persistence and affinity) as session affinity. |
| | | [Header-Based](https://cloud.google.com/load-balancing/docs/backend-service#header_field_affinity) | httpHeaderName=name | [Backend Policy](https://cloud.google.com/kubernetes-engine/docs/how-to/configure-gateway-resources#session_affinity) (Backends) | N/A |
| HAProxy | Dataplane | [Cookie-Based](https://docs.haproxy.org/2.6/configuration.html#4.2-cookie) | name=name
[rewrite \| insert \| prefix ]
indirect
nocache
postonly
preserve
httponly
secure
domain=domain
maxidle=idle
maxlife=life
dynamic
attr=value | [Default or Backends](https://docs.haproxy.org/2.6/configuration.html#4.2-cookie) (Global or Backends) | HAProxy allows for operational cookie strategy configuration (i.e. when/how HAProxy should inject cookies) |
@@ -290,9 +323,14 @@ Generally, the implementation API programs the dataplane API; however these two
| Kong | Implementation / Dataplane | [Cookie-Based](https://docs.konghq.com/hub/kong-inc/session/) | cookie_name=name
rolling_timeout=timeout
absolute_timeout=timeout
idling_timeout=timeout
cookie_path=path
cookie_domain=domain
cookie_same_site=[Strict \| Lax \| None \| off]
cookie_http_only
cookie_secure=[true \| false]
stale_ttl=duration
cookie_persistent=[true \| false]
storage=storage_type | [Route, Service, Global](https://docs.konghq.com/hub/kong-inc/session/) (Route or Backends or Global) | N/A |
| | | [Header-Based](https://docs.konghq.com/gateway/latest/how-kong-works/load-balancing/#balancing-algorithms) | name | [Upstreams](https://docs.konghq.com/gateway/3.2.x/admin-api/#add-upstream) (Backends) | N/A |
| Kuma | Implementation (Envoy) | None | None | None | Kuma has no documentation on how it supports session persistence or cookies. [Kuma Docs](https://kuma.io/docs/2.1.x/) |
+| Linkerd | | | | | |
+| LiteSpeed Ingress Controller | | | | | |
| Nginx | Dataplane | [Cookie-Based (Nginx Plus Only)](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence) | Name=name
Expires=time
Domain=domain
HttpOnly
SameSite = [strict \| lax \| none \| $variable]
Secure
path=path | [Upstream](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence) (Backends) | See also [Sticky Cookie](https://nginx.org/en/docs/http/ngx_http_upstream_module.html?&_ga=2.184452070.1306763907.1680031702-1761609832.1671225057#sticky_cookie) |
| NGINX Gateway Fabric | Implementation (Nginx) | N/A | Supports Gateway API Only* | N/A | *NGINX Gateway Fabric solely uses Gateway API; therefore, it doesn’t yet have a way to configure session persistence. [NGINX Gateway Fabric Docs](https://github.com/nginxinc/nginx-gateway-fabric) |
+| STUNner | | | | | |
| Traefik | Implementation / Dataplane | [Cookie-Based](https://doc.traefik.io/traefik/routing/services/#sticky-sessions) | name=name
secure
httpOnly
sameSite=[none \| lax \| strict ] | [Services](https://doc.traefik.io/traefik/routing/services/#sticky-sessions) (Backends) | N/A |
+| Tyk | | | | | |
+| WSO2 APK | | | | | |
### Sessions in Java
@@ -320,7 +358,7 @@ In this section, we will explore the questions and design elements associated wi
// SessionPersistencePolicy provides a way to define session persistence rules
// for a service or route.
//
-// Support: Core
+// Support: Extended
type SessionPersistencePolicy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -339,34 +377,17 @@ type SessionPersistencePolicySpec struct {
// TargetRef identifies an API object to apply policy to.
// The TargetRef may be a Service, HTTPRoute, GRPCRoute,
// or a HTTPRouteRule or GRPCRouteRule section.
- // At least one of these targets must be supported for
- // core-level compliance.
//
- TargetRef gatewayv1a2.PolicyTargetReference `json:"targetRef"`
-
- // AbsoluteTimeoutSeconds defines the absolute timeout of the
- // persistent session measured in seconds. Once
- // AbsoluteTimeoutSeconds has elapsed, the session becomes invalid.
+ // Support: Core (At least one of Service, HTTPRoute,
+ // GRPCRoute, or a HTTPRouteRule or GRPCRouteRule must
+ // be supported for core-level compliance.)
//
- // Support: Core
- //
- // +optional
- AbsoluteTimeoutSeconds int64 `json:"absoluteTimeoutSeconds,omitempty"`
-
- // IdleTimeoutSeconds defines the idle timeout of the
- // persistent session measured in seconds. Once the session
- // has been idle for more than specified IdleTimeoutSeconds
- // duration, the session becomes invalid.
- //
- // Support: Core
- //
- // +optional
- IdleTimeoutSeconds int64 `json:"idleTimeoutSeconds,omitempty"`
+ TargetRef gatewayv1a2.PolicyTargetReference `json:"targetRef"`
// SessionName defines the name of the persistent session token
// (e.g. a cookie name).
//
- // Support: Extended
+ // Support: Implementation-specific
//
// +optional
// +kubebuilder:validation:MaxLength=4096
@@ -520,6 +541,7 @@ A cookie is composed of various attributes, each represented as key=value pairs.
values, the cookie name attribute is the only mandatory one, and the rest are considered optional.
The cookie attributes defined by [RFC6265](https://www.rfc-editor.org/rfc/rfc6265#section-5.2) are:
+
- Name=_value_
- Expires=_date_
- Max-Age=_number_
@@ -530,6 +552,7 @@ The cookie attributes defined by [RFC6265](https://www.rfc-editor.org/rfc/rfc626
Other cookie attributes not defined by RFC6265, but are captured in draft RFCs and could be considered de facto
standards due to wide acceptance are:
+
- SameSite=[Strict|Lax|None]
- Partitioned
@@ -543,12 +566,15 @@ The `Name` cookie attribute can be configured via the `SessionName` field on `Se
field is considered extended support level. This is because some implementations, such as ones supporting global load
balancers, don't have the capability to configure the cookie name.
-#### TTL
+#### Expires / Max-Age
-The `TTL` cookie attribute may be influenced by the `AbsoluteTimeoutSeconds` field on `SessionPersistencePolicy`.
-However, it's important to understand that `AbsoluteTimeoutSeconds` represents the duration of the entire session, not
-just the cookie duration. Conversely, the cookie's `TTL` attribute does not have to be configured in order to implement
-`AbsoluteTimeoutSeconds`.
+The `Expires` and `Max-Age` cookie attributes are important in distinguishing between session cookies and persistent
+cookies. Session cookies do not include either of these attributes, while persistent cookies contain one of them.
+Implementations that achieve session persistence through cookies MUST utilize session cookies, meaning that `Expires`
+or `Max-Age` MUST NOT be set. This ensures that cookies remain usable as long as the associated backend is operational
+and not restarted. This requirement is subject to review if there are use cases that require the creation of persistent
+cookies (utilizing client-side `Max-Age` or `Expires`) or session cookies where the data plane monitors the cookie
+lifetime or idle time through a timestamp in the cookie value.
#### Path
@@ -569,7 +595,7 @@ It is also important to note that this design makes persistent session unique pe
distinct routes, one with path prefix `/foo` and the other with `/bar`, both target the same service, the persistent
session won't be shared between these two paths.
-Conversely, if the `SessionPersistencePolicy` policy is attached to a service, the `Path` attribute should be left
+Conversely, if the `SessionPersistencePolicy` policy is attached to a service, the `Path` attribute MUST be left
unset. This is because multiple routes can target a single service. If the `Path` cookie attribute is configured in this
scenario, it could result in problems due to the possibility of different paths being taken for the same cookie.
Implementations should also handle the case where client is a browser making requests to multiple persistent services
@@ -577,7 +603,7 @@ from the same page.
#### Secure, HttpOnly, SameSite
-The `Secure`, `HttpOnly`, and `SameSite` cookie attributes are security-related. The API implementers should follow the
+The `Secure`, `HttpOnly`, and `SameSite` cookie attributes are security-related. The API implementers SHOULD follow the
security-by-default principle and configure these attributes accordingly. This means enabling `Secure` and `HttpOnly`,
and setting `SameSite` to `Strict`. However, in certain implementation use cases such as service mesh, secure values
might not function as expected. In such cases, it's acceptable to make appropriate adjustments.
@@ -597,11 +623,18 @@ session persistence needs in GAMMA and service mesh scenarios.
As illustrated in the examples provided in [Session Persistence Initiation](#session-persistence-initiation),
implementations must consider how to manage sessions initiated by other components. As mentioned in [Backend Initiated Session Example](#backend-initiated-session-example),
this GEP does not support configuring backend-initiated persistent sessions. We leave the decision of handling existing
-sessions with each specific implementation. In the case of cookie-based session persistence, an implementation has the
-freedom to either rewrite the cookie or insert an additional cookie, or to do nothing (resulting in the lack of a
+sessions with each specific implementation. In the case of cookie-based session persistence, an implementation MAY
+either rewrite the cookie or insert an additional cookie, or to do nothing (resulting in the lack of a
persistent session). In general, inserting an additional cookie is a generally safe option, but it's important for
implementations to exercise their own discretion. However, regardless of the implementation's design choice, the
-implementation must be able to handle multiple cookies.
+implementation MUST be able to handle multiple cookies.
+
+### Session Persistence Failure Behavior
+
+In a situation where session persistence is configured and the backend becomes unhealthy, this GEP doesn't specify a
+prescribed fallback behavior mechanism or HTTP status code. Implementations MAY exhibit different behaviors depending
+on whether active health checking is enabled. Data planes have the option to fall back to available backends,
+disregarding the broken session, and reestablish session persistence when the backend becomes available again.
### Expected API Behavior
@@ -611,6 +644,7 @@ configuration scenarios (use cases) and how implementations should handle them.
#### Attaching Session Persistence to both Service And Route
In a situation which:
+
- `ServiceA` with `SessionPersistencePolicy` attached
- `RouteX` with `SessionPersistencePolicy` attached and backend `ServiceA`
@@ -629,6 +663,7 @@ graph TB
#### Two Routes Share Backends with Session Persistence Applied only on one Route
In the situation in which:
+
- `ServiceA` with`SessionPersistencePolicy` attached
- `ServiceB` with no session persistence
- `RouteX` with no session persistence backends `ServiceA` and `ServiceB`
@@ -636,6 +671,7 @@ In the situation in which:
At this point, traffic through `RouteX` to `ServiceB` doesn't use session persistence.
A new route is added:
+
- `RouteY` with `SessionPersistencePolicy` attached
Even though it's not explicitly configured, traffic flowing through `RouteX` to `ServiceB` should utilize session
@@ -716,6 +752,7 @@ spec:
```
A potentially unexpected situation occurs when:
+
1. Curl to `/a` which establishes a persistent session with `servicev1`
2. Curl to `/b` routes to `servicev1` due to route persistence despite `weight: 0` configuration
@@ -740,14 +777,18 @@ The expected behavior is that the gateway will retain existing persistent sessio
selected, and establish new persistent sessions after a selector update. This use case is uncommon and may not be
supported by some implementations due to their current designs.
+### Conformance Details
+
+TODO
+
### Open Questions
-- What happens when session persistence is broken because the backend is not up or healthy? If that's an error case, how should that be handled? Should the API dictate the http error code? Or should the API dictate fall back behavior?
- What happens when session persistence causes traffic splitting scenarios to overload a backend?
- Should we add status somewhere when a user gets in to a "risky" configuration with session persistence?
- Should there be an API configuration field that specifies how already established sessions are handled?
## TODO
+
The following are items that we intend to resolve before we consider this GEP implementable:
- We need to identify and document requirements regarding session draining and migration. How do implementations drain established sessions during backend upgrades without disruption?
@@ -761,87 +802,7 @@ predicable way.
## Alternatives
-### Alternate Session Persistence API
-
-Alternatively, the API for Session Persistence could define a loosely-typed list of attributes instead of strongly-typed
-attribute fields. This approach offers a more flexible specification, particularly when new attributes need to be
-introduced. However, loosely-typed lists may not be as user-friendly due to the lack of validation.
-
-```go
-// HttpCookie defines a cookie to achieve session persistence.
-//
-// Support: Core
-type HttpCookie struct {
- // Name defines the cookie's name.
- //
- // Support: Core
- //
- // +kubebuilder:validation:MaxLength=4096
- Name String `json:"name,omitempty"`
-
- // CookieAttributes defines the cookie's attributes.
- //
- // Support: Core
- // +optional
- CookieAttributes []CookieAttribute `json:cookieAttributes`
-}
-
-// CookieAttribute defines the cookie's attributes.
-type CookieAttribute map[string][]string
-)
-```
-
-The API could also be a mix of individual fields and listed attributes. More specifically, we could separate the key
-attributes with no value into a list. This approach is taken by [Haproxy Ingress](https://haproxy-ingress.github.io/docs/configuration/keys/#affinity)
-with their `session-cookie-keywords` field. This provides flexibility for simple boolean-typed attributes, while
-validating attributes that have values. However, this approach may be confusing to users as uses two different API
-patterns for cookie attributes.
-
-```go
-// HttpCookie defines a cookie to achieve session persistence.
-//
-// Support: Core
-type HttpCookie struct {
- // Name defines the cookie's name.
- //
- // Support: Core
- //
- // +kubebuilder:validation:MaxLength=4096
- Name String `json:"name,omitempty"`
-
- // SameSite defines the cookie's SameSite attribute.
- //
- // Support: Extended
- //
- // +optional
- // +kubebuilder:validation:Enum=Strict;Lax;None
- SameSite SameSiteType `json:"sameSite,omitempty"`
-
- // Domain defines the cookie's Domain attribute.
- //
- // Support: Extended
- //
- // +optional
- // +kubebuilder:validation:MaxLength=4096
- Domain String `json:"domain,omitempty"`
-
- // CookieKeywords defines the cookie's attributes that have no value.
- //
- // Support: Extended
- // +optional
- CookieKeywords []CookieKeyword `json:cookieKeywords`
-}
-
-// CookieKeyword defines the cookie's attributes that have no value.
-type CookieKeyword string
-
-const (
- // CookieKeywordsHttpOnly specifies the HttpOnly cookie attribute.
- CookieKeywordsHttpOnly HttpOnlyMode = "HttpOnly"
- // CookieKeywordsSecure specifies the Secure cookie attribute.
- CookieKeywordsSecure HttpOnlyMode = "Secure"
-)
-```
+## LoadBalancerPolicy API
Taking a different approach, this GEP could design a generic approach to configuring load balancing policy. Instead of
only having a metaresource specifically for session persistence, a metaresource called `LoadBalancerPolicy` of which
@@ -855,8 +816,6 @@ current and future implementations.
```go
// LoadBalancerPolicy provides a way to define load balancing rules
// for a service.
-//
-// Support: Core
type LoadBalancerPolicy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -885,14 +844,28 @@ type LoadBalancerPolicySpec struct {
}
// SessionPersistence defines and configures session persistence.
-//
-// Support: Core
type SessionPersistence struct {
- // HttpCookie defines and configures a cookie to achieve
- // session persistence.
+ // AbsoluteTimeoutSeconds defines the absolute timeout of the
+ // persistent session measured in seconds. Once
+ // AbsoluteTimeoutSeconds has elapsed, the session becomes invalid.
+ //
+ // +optional
+ AbsoluteTimeoutSeconds int64 `json:"absoluteTimeoutSeconds,omitempty"`
+
+ // IdleTimeoutSeconds defines the idle timeout of the
+ // persistent session measured in seconds. Once the session
+ // has been idle for more than specified IdleTimeoutSeconds
+ // duration, the session becomes invalid.
//
- // Support: Core
- HttpCookie *HttpCookie `json:"httpCookie"`
+ // +optional
+ IdleTimeoutSeconds int64 `json:"idleTimeoutSeconds,omitempty"`
+
+ // SessionName defines the name of the persistent session token
+ // (e.g. a cookie name).
+ //
+ // +optional
+ // +kubebuilder:validation:MaxLength=4096
+ SessionName String `json:"sessionName,omitempty"`
}
```
@@ -901,7 +874,7 @@ type SessionPersistence struct {
This GEP describes session persistence and session affinity as the idea of strong and weak connection persistence respectively. Other technologies use different names or define persistence and affinity differently:
- Envoy defines [stateful sessions](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/stateful_session/cookie/v3/cookie.proto) as what we've defined as session persistence
-- Google Cloud defines [session affinity](https://cloud.google.com/run/docs/configuring/session-affinity) as what we've defined as session persistence
+- Google Cloud Run defines [session affinity](https://cloud.google.com/run/docs/configuring/session-affinity) as what we've defined as session persistence
- Nginx defines [session persistence](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence) as what we've defined as both session persistence and affinity
- Traefik defines [sticky sessions](https://doc.traefik.io/traefik/routing/services/#sticky-sessions) as what we've defined as session persistence
- Apache httpd defines [sticky sessions or stickiness](https://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html) as what we've defined as session persistence