Support domain configuration for sticky cookies

This commit is contained in:
Jorge
2025-03-06 09:38:04 +01:00
committed by GitHub
parent fa76ed57d3
commit 740b4cfd25
24 changed files with 184 additions and 0 deletions
@@ -200,6 +200,7 @@
- "traefik.http.services.service02.loadbalancer.serverstransport=foobar"
- "traefik.http.services.service02.loadbalancer.sticky=true"
- "traefik.http.services.service02.loadbalancer.sticky.cookie=true"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.domain=foobar"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.httponly=true"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.maxage=42"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.name=foobar"
@@ -64,6 +64,7 @@
sameSite = "foobar"
maxAge = 42
path = "foobar"
domain = "foobar"
[[http.services.Service02.loadBalancer.servers]]
url = "foobar"
@@ -122,6 +123,7 @@
sameSite = "foobar"
maxAge = 42
path = "foobar"
domain = "foobar"
[http.services.Service04.weighted.healthCheck]
[http.middlewares]
[http.middlewares.Middleware01]
@@ -72,6 +72,7 @@ http:
sameSite: foobar
maxAge: 42
path: foobar
domain: foobar
servers:
- url: foobar
weight: 42
@@ -123,6 +124,7 @@ http:
sameSite: foobar
maxAge: 42
path: foobar
domain: foobar
healthCheck: {}
middlewares:
Middleware01:
@@ -247,6 +247,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as
@@ -1147,6 +1152,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can
be accessed by client-side APIs, such as JavaScript.
@@ -2737,6 +2747,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -2850,6 +2865,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
@@ -3039,6 +3059,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -3092,6 +3117,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
@@ -275,6 +275,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| `traefik/http/services/Service02/loadBalancer/servers/1/url` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/servers/1/weight` | `42` |
| `traefik/http/services/Service02/loadBalancer/serversTransport` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/domain` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/httpOnly` | `true` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/maxAge` | `42` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/name` | `foobar` |
@@ -294,6 +295,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| `traefik/http/services/Service04/weighted/services/0/weight` | `42` |
| `traefik/http/services/Service04/weighted/services/1/name` | `foobar` |
| `traefik/http/services/Service04/weighted/services/1/weight` | `42` |
| `traefik/http/services/Service04/weighted/sticky/cookie/domain` | `foobar` |
| `traefik/http/services/Service04/weighted/sticky/cookie/httpOnly` | `true` |
| `traefik/http/services/Service04/weighted/sticky/cookie/maxAge` | `42` |
| `traefik/http/services/Service04/weighted/sticky/cookie/name` | `foobar` |
@@ -247,6 +247,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as
@@ -405,6 +405,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can
be accessed by client-side APIs, such as JavaScript.
@@ -273,6 +273,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -386,6 +391,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
@@ -575,6 +585,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -628,6 +643,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
@@ -322,6 +322,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
+8
View File
@@ -437,6 +437,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
+8
View File
@@ -324,6 +324,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
@@ -357,6 +357,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
sameSite: none
maxAge: 42
path: /foo
domain: foo.com
strategy: RoundRobin
weight: 10
nativeLB: true # [16]
@@ -391,6 +391,14 @@ which in turn will create the resulting routers, services, handlers, etc.
traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none"
```
??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
traefik.ingress.kubernetes.io/service.sticky.cookie.domain: "foo.com"
```
??? info "`traefik.ingress.kubernetes.io/service.sticky.cookie.httponly`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
+14
View File
@@ -276,6 +276,14 @@ A Story of key & values
|-----------------------------------------------------------------------|--------|
| `traefik/http/services/myservice/loadbalancer/sticky/cookie/samesite` | `none` |
??? info "`traefik/http/services/<service_name>/loadbalancer/sticky/cookie/domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
| Key (Path) | Value |
|-----------------------------------------------------------------------|-----------|
| `traefik/http/services/myservice/loadbalancer/sticky/cookie/domain` | `foo.com` |
??? info "`traefik/http/services/<service_name>/loadbalancer/sticky/cookie/maxage`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
@@ -340,6 +348,12 @@ A Story of key & values
|------------------------------------------------------------------------|--------|
| `traefik/http/services/<service_name>/weighted/sticky/cookie/samesite` | `none` |
??? info "`traefik/http/services/<service_name>/weighted/sticky/cookie/domain`"
| Key (Path) | Value |
|------------------------------------------------------------------------|-----------|
| `traefik/http/services/<service_name>/weighted/sticky/cookie/domain` | `foo.com` |
??? info "`traefik/http/services/<service_name>/weighted/sticky/cookie/httpOnly`"
| Key (Path) | Value |
+8
View File
@@ -306,6 +306,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
+8
View File
@@ -451,6 +451,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.domain`"
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.domain=foo.com"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
See [response forwarding](../services/index.md#response-forwarding) for more information.
+8
View File
@@ -255,6 +255,12 @@ On subsequent requests, to keep the session alive with the same server, the clie
`SameSite` can be `none`, `lax`, `strict` or empty.
!!! info "Domain"
The Domain attribute of a cookie specifies the domain for which the cookie is valid.
By setting the Domain attribute, the cookie can be shared across subdomains (for example, a cookie set for example.com would be accessible to www.example.com, api.example.com, etc.). This is particularly useful in cases where sticky sessions span multiple subdomains, ensuring that the session is maintained even when the client interacts with different parts of the infrastructure.
??? example "Adding Stickiness -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
@@ -286,6 +292,7 @@ On subsequent requests, to keep the session alive with the same server, the clie
cookie:
name: my_sticky_cookie_name
secure: true
domain: mysite.site
httpOnly: true
```
@@ -297,6 +304,7 @@ On subsequent requests, to keep the session alive with the same server, the clie
name = "my_sticky_cookie_name"
secure = true
httpOnly = true
domain = "mysite.site"
sameSite = "none"
```
@@ -247,6 +247,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as
@@ -1147,6 +1152,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can
be accessed by client-side APIs, such as JavaScript.
@@ -2737,6 +2747,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -2850,6 +2865,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
@@ -3039,6 +3059,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie
can be accessed by client-side APIs, such as JavaScript.
@@ -3092,6 +3117,11 @@ spec:
cookie:
description: Cookie defines the sticky cookie configuration.
properties:
domain:
description: |-
Domain defines the host to which the cookie will be sent.
More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
type: string
httpOnly:
description: HTTPOnly defines whether the cookie can be
accessed by client-side APIs, such as JavaScript.
+3
View File
@@ -199,6 +199,9 @@ type Cookie struct {
// When not provided the cookie will be sent on every request to the domain.
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
Path *string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
// Domain defines the host to which the cookie will be sent.
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
Domain string `json:"domain,omitempty" toml:"domain,omitempty" yaml:"domain,omitempty"`
}
// SetDefaults set the default values for a Cookie.
+4
View File
@@ -179,6 +179,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service0.loadbalancer.sticky.cookie.name": "foobar",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.secure": "true",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.path": "/foobar",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.domain": "foo.com",
"traefik.http.services.Service0.loadbalancer.serversTransport": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar",
@@ -684,6 +685,7 @@ func TestDecodeConfiguration(t *testing.T) {
Name: "foobar",
Secure: true,
HTTPOnly: false,
Domain: "foo.com",
Path: func(v string) *string { return &v }("/foobar"),
},
},
@@ -1224,6 +1226,7 @@ func TestEncodeConfiguration(t *testing.T) {
Cookie: &dynamic.Cookie{
Name: "foobar",
HTTPOnly: true,
Domain: "foo.com",
Path: func(v string) *string { return &v }("/foobar"),
},
},
@@ -1479,6 +1482,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Secure": "false",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.MaxAge": "0",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Path": "/foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Domain": "foo.com",
"traefik.HTTP.Services.Service0.LoadBalancer.ServersTransport": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar",
@@ -260,6 +260,7 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS
HTTPOnly: tService.Weighted.Sticky.Cookie.HTTPOnly,
SameSite: tService.Weighted.Sticky.Cookie.SameSite,
MaxAge: tService.Weighted.Sticky.Cookie.MaxAge,
Domain: tService.Weighted.Sticky.Cookie.Domain,
},
}
sticky.Cookie.SetDefaults()
@@ -382,6 +383,7 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
HTTPOnly: svc.Sticky.Cookie.HTTPOnly,
SameSite: svc.Sticky.Cookie.SameSite,
MaxAge: svc.Sticky.Cookie.MaxAge,
Domain: svc.Sticky.Cookie.Domain,
},
}
lb.Sticky.Cookie.SetDefaults()
@@ -121,6 +121,7 @@ func Test_parseServiceConfig(t *testing.T) {
"traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar",
"traefik.ingress.kubernetes.io/service.sticky.cookie.secure": "true",
"traefik.ingress.kubernetes.io/service.sticky.cookie.samesite": "none",
"traefik.ingress.kubernetes.io/service.sticky.cookie.domain": "foo.com",
"traefik.ingress.kubernetes.io/service.sticky.cookie.path": "foobar",
},
expected: &ServiceConfig{
@@ -131,6 +132,7 @@ func Test_parseServiceConfig(t *testing.T) {
Secure: true,
HTTPOnly: true,
SameSite: "none",
Domain: "foo.com",
Path: pointer("foobar"),
},
},
@@ -30,6 +30,7 @@ type stickyCookie struct {
sameSite string
maxAge int
path string
domain string
}
func convertSameSite(sameSite string) http.SameSite {
@@ -87,6 +88,7 @@ func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer {
sameSite: sticky.Cookie.SameSite,
maxAge: sticky.Cookie.MaxAge,
path: "/",
domain: sticky.Cookie.Domain,
}
if sticky.Cookie.Path != nil {
balancer.stickyCookie.path = *sticky.Cookie.Path
@@ -281,6 +283,7 @@ func (b *Balancer) writeStickyCookie(w http.ResponseWriter, handler *namedHandle
Secure: b.stickyCookie.secure,
SameSite: convertSameSite(b.stickyCookie.sameSite),
MaxAge: b.stickyCookie.maxAge,
Domain: b.stickyCookie.domain,
}
http.SetCookie(w, cookie)
}
@@ -239,6 +239,7 @@ func TestSticky(t *testing.T) {
Secure: true,
HTTPOnly: true,
SameSite: "none",
Domain: "foo.com",
MaxAge: 42,
Path: func(v string) *string { return &v }("/foo"),
},
@@ -276,6 +277,7 @@ func TestSticky(t *testing.T) {
assert.Equal(t, 3, recorder.save["second"])
assert.True(t, recorder.cookies["test"].HttpOnly)
assert.True(t, recorder.cookies["test"].Secure)
assert.Equal(t, "foo.com", recorder.cookies["test"].Domain)
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
assert.Equal(t, 42, recorder.cookies["test"].MaxAge)
assert.Equal(t, "/foo", recorder.cookies["test"].Path)