Add p2c load-balancing strategy for servers load-balancer

Co-authored-by: Ian Ross <ifross@gmail.com>
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
Romain 2025-03-10 12:12:04 +01:00 committed by GitHub
parent 550d96ea67
commit 9e029a84c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 1621 additions and 382 deletions

View file

@ -187,3 +187,18 @@ and will be removed in the next major version.
In `v3.3.4`, the OpenTelemetry Request Duration metric (named `traefik_(entrypoint|router|service)_request_duration_seconds`) unit has been changed from milliseconds to seconds.
To be consistent with the naming and other metrics providers, the metric now reports the duration in seconds.
## v3.3 to v3.4
### Kubernetes CRD Provider
In `v3.4`, the HTTP service definition has been updated.
The strategy field now supports two new values: `wrr` and `p2c` (please refer to the [HTTP Services Load Balancing documentation](../../routing/services/#load-balancing-strategy) for more details).
CRDs can be updated with this command:
```shell
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
```
Please note that the `RoundRobin` strategy value is now deprecated, but still supported and equivalent to `wrr`, and will be removed in the next major release.

View file

@ -221,6 +221,7 @@
- "traefik.http.services.service02.loadbalancer.sticky.cookie.path=foobar"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.samesite=foobar"
- "traefik.http.services.service02.loadbalancer.sticky.cookie.secure=true"
- "traefik.http.services.service02.loadbalancer.strategy=foobar"
- "traefik.http.services.service02.loadbalancer.server.port=foobar"
- "traefik.http.services.service02.loadbalancer.server.preservepath=true"
- "traefik.http.services.service02.loadbalancer.server.scheme=foobar"

View file

@ -54,6 +54,7 @@
[http.services.Service01.failover.healthCheck]
[http.services.Service02]
[http.services.Service02.loadBalancer]
strategy = "foobar"
passHostHeader = true
serversTransport = "foobar"
[http.services.Service02.loadBalancer.sticky]

View file

@ -80,6 +80,7 @@ http:
- url: foobar
weight: 42
preservePath: true
strategy: foobar
healthCheck:
scheme: foobar
mode: foobar

View file

@ -290,10 +290,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -1217,10 +1221,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -2924,10 +2932,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -3048,10 +3060,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -3250,10 +3266,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:

View file

@ -297,6 +297,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/path` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/sameSite` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/sticky/cookie/secure` | `true` |
| `traefik/http/services/Service02/loadBalancer/strategy` | `foobar` |
| `traefik/http/services/Service03/mirroring/healthCheck` | `` |
| `traefik/http/services/Service03/mirroring/maxBodySize` | `42` |
| `traefik/http/services/Service03/mirroring/mirrorBody` | `true` |

View file

@ -290,10 +290,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:

View file

@ -454,10 +454,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:

View file

@ -314,10 +314,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -438,10 +442,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:
@ -640,10 +648,14 @@ spec:
type: object
type: object
strategy:
default: wrr
description: |-
Strategy defines the load balancing strategy between the servers.
RoundRobin is the only supported value at the moment.
Supported values are: wrr (Weighed round-robin) and p2c (Power of two choices).
RoundRobin value is deprecated and supported for backward compatibility.
enum:
- wrr
- p2c
- RoundRobin
type: string
weight:

View file

@ -346,6 +346,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -461,6 +461,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.strategy=p2c"
```
### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,

View file

@ -350,6 +350,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -358,19 +358,19 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
maxAge: 42
path: /foo
domain: foo.com
strategy: RoundRobin
strategy: wrr # [16]
weight: 10
nativeLB: true # [16]
nodePortLB: true # [17]
tls: # [18]
secretName: supersecret # [19]
options: # [20]
name: opt # [21]
namespace: default # [22]
certResolver: foo # [23]
domains: # [24]
- main: example.net # [25]
sans: # [26]
nativeLB: true # [17]
nodePortLB: true # [18]
tls: # [19]
secretName: supersecret # [20]
options: # [21]
name: opt # [22]
namespace: default # [23]
certResolver: foo # [24]
domains: # [25]
- main: example.net # [26]
sans: # [27]
- a.example.net
- b.example.net
```
@ -392,17 +392,18 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
| [13] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. |
| [14] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). |
| [15] | `services[n].healthCheck` | Defines the HealthCheck when service references a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName. |
| [16] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. |
| [17] | `services[n].nodePortLB` | Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. |
| [18] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration |
| [19] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
| [20] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
| [21] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
| [22] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
| [23] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
| [24] | `tls.domains` | List of [domains](../routers/index.md#domains) |
| [25] | `domains[n].main` | Defines the main domain name |
| [26] | `domains[n].sans` | List of SANs (alternative domains) |
| [16] | `services[n].strategy` | Defines the load-balancing strategy for the load-balancer. Supported values are `wrr` and `p2c`, please refer to the [Load Balancing documentation](../routing/services/#load-balancing-strategy) for more information. |
| [17] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. |
| [18] | `services[n].nodePortLB` | Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. |
| [19] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration |
| [20] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) |
| [21] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
| [22] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
| [23] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
| [24] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
| [25] | `tls.domains` | List of [domains](../routers/index.md#domains) |
| [26] | `domains[n].main` | Defines the main domain name |
| [27] | `domains[n].sans` | List of SANs (alternative domains) |
??? example "Declaring an IngressRoute"
@ -605,7 +606,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne
#### Load Balancing
More information in the dedicated server [load balancing](../services/index.md#load-balancing) section.
More information in the dedicated server [load balancing](../services/index.md#load-balancing-strategy) section.
!!! info "Declaring and using Kubernetes Service Load Balancing"

View file

@ -300,6 +300,14 @@ A Story of key & values
|---------------------------------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/responseforwarding/flushinterval` | `10` |
??? info "`traefik/http/services/<service_name>/loadbalancer/strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
| Key (Path) | Value |
|---------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/strategy` | `p2c` |
??? info "`traefik/http/services/<service_name>/mirroring/service`"
| Key (Path) | Value |

View file

@ -338,6 +338,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.strategy=p2c
```
### Middleware
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.

View file

@ -467,6 +467,14 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.strategy`"
See [load balancing strategy](../services/index.md#load-balancing-strategy) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.strategy=p2c"
```
### Middleware
You can declare pieces of middleware using labels starting with `traefik.http.middlewares.<name-of-your-choice>.`,

View file

@ -139,6 +139,47 @@ The `url` option point to a specific instance.
url = "http://private-ip-server-1/"
```
The `preservePath` option allows to preserve the URL path.
!!! info "Health Check"
When a [health check](#health-check) is configured for the server, the path is not preserved.
??? example "A Service with One Server and PreservePath -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://private-ip-server-1/base"
preservePath: true
```
```toml tab="TOML"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/base"
preservePath = true
```
#### Load Balancing Strategy
The `strategy` option allows to choose the load balancing algorithm.
Two load balancing algorithms are supported:
- Weighed round-robin (wrr)
- Power of two choices (p2c)
##### WRR
Weighed round-robin is the default strategy (and does not need to be specified).
The `weight` option allows for weighted load balancing on the servers.
??? example "A Service with Two Servers with Weight -- Using the [File Provider](../../providers/file.md)"
@ -169,39 +210,11 @@ The `weight` option allows for weighted load balancing on the servers.
weight = 1
```
The `preservePath` option allows to preserve the URL path.
##### P2C
!!! info "Health Check"
Power of two choices algorithm is a load balancing strategy that selects two servers at random and chooses the one with the least number of active requests.
When a [health check](#health-check) is configured for the server, the path is not preserved.
??? example "A Service with One Server and PreservePath -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://private-ip-server-1/base"
preservePath: true
```
```toml tab="TOML"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/base"
preservePath = true
```
#### Load-balancing
For now, only round robin load balancing is supported:
??? example "Load Balancing -- Using the [File Provider](../../providers/file.md)"
??? example "P2C Load Balancing -- Using the [File Provider](../../providers/file.md)"
```yaml tab="YAML"
## Dynamic configuration
@ -209,19 +222,24 @@ For now, only round robin load balancing is supported:
services:
my-service:
loadBalancer:
strategy: "p2c"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
```toml tab="TOML"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "p2c"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
#### Sticky sessions