From d7d00175452f0929b699fca633aa8b077c313f6c Mon Sep 17 00:00:00 2001
From: Swastik Sarkar <40518186+sswastik02@users.noreply.github.com>
Date: Wed, 9 Apr 2025 13:40:05 +0530
Subject: [PATCH] Add unhealthy Interval to the health check configuration
---
.../dynamic-configuration/docker-labels.yml | 1 +
.../reference/dynamic-configuration/file.toml | 1 +
.../reference/dynamic-configuration/file.yaml | 1 +
.../kubernetes-crd-definition-v1.yml | 55 ++++-
.../reference/dynamic-configuration/kv-ref.md | 1 +
.../traefik.io_ingressroutes.yaml | 11 +-
.../traefik.io_middlewares.yaml | 11 +-
.../traefik.io_traefikservices.yaml | 33 ++-
.../http/load-balancing/service.md | 60 +++---
.../kubernetes/crd/http/ingressroute.md | 101 ++++-----
.../kubernetes/crd/http/traefikservice.md | 199 +++++++++---------
.../other-providers/consul-catalog.md | 8 +
.../other-providers/docker.md | 8 +
.../other-providers/ecs.md | 8 +
.../other-providers/kv.md | 8 +
.../other-providers/nomad.md | 8 +
.../other-providers/swarm.md | 8 +
.../routing/providers/consul-catalog.md | 8 +
docs/content/routing/providers/docker.md | 8 +
docs/content/routing/providers/ecs.md | 8 +
docs/content/routing/providers/kv.md | 8 +
docs/content/routing/providers/nomad.md | 8 +
docs/content/routing/providers/swarm.md | 8 +
docs/content/routing/services/index.md | 5 +-
integration/fixtures/k8s/01-traefik-crd.yml | 55 ++++-
pkg/config/dynamic/http_config.go | 23 +-
pkg/config/dynamic/zz_generated.deepcopy.go | 5 +
pkg/config/label/label_test.go | 76 ++++---
pkg/healthcheck/healthcheck.go | 107 +++++++---
pkg/healthcheck/healthcheck_test.go | 62 +++++-
.../kubernetes/crd/kubernetes_http.go | 12 ++
.../kubernetes/crd/kubernetes_test.go | 36 ++--
.../crd/traefikio/v1alpha1/ingressroute.go | 6 +-
.../v1alpha1/zz_generated.deepcopy.go | 5 +
pkg/provider/kv/kv_test.go | 18 +-
.../components/_commons/PanelHealthCheck.vue | 16 +-
36 files changed, 701 insertions(+), 295 deletions(-)
diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml
index d6534790b..b2af3def6 100644
--- a/docs/content/reference/dynamic-configuration/docker-labels.yml
+++ b/docs/content/reference/dynamic-configuration/docker-labels.yml
@@ -209,6 +209,7 @@
- "traefik.http.services.service02.loadbalancer.healthcheck.scheme=foobar"
- "traefik.http.services.service02.loadbalancer.healthcheck.status=42"
- "traefik.http.services.service02.loadbalancer.healthcheck.timeout=42s"
+- "traefik.http.services.service02.loadbalancer.healthcheck.unhealthyinterval=42s"
- "traefik.http.services.service02.loadbalancer.passhostheader=true"
- "traefik.http.services.service02.loadbalancer.responseforwarding.flushinterval=42s"
- "traefik.http.services.service02.loadbalancer.serverstransport=foobar"
diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml
index 9915ff223..202815c39 100644
--- a/docs/content/reference/dynamic-configuration/file.toml
+++ b/docs/content/reference/dynamic-configuration/file.toml
@@ -84,6 +84,7 @@
status = 42
port = 42
interval = "42s"
+ unhealthyInterval = "42s"
timeout = "42s"
hostname = "foobar"
followRedirects = true
diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml
index 30f0afa59..e8210ef85 100644
--- a/docs/content/reference/dynamic-configuration/file.yaml
+++ b/docs/content/reference/dynamic-configuration/file.yaml
@@ -89,6 +89,7 @@ http:
status: 42
port: 42
interval: 42s
+ unhealthyInterval: 42s
timeout: 42s
hostname: foobar
followRedirects: true
diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
index f14cce498..0541d1607 100644
--- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
+++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
@@ -136,7 +136,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -172,6 +172,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -1070,7 +1079,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -1106,6 +1115,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -2743,7 +2761,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -2779,6 +2797,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -2828,7 +2855,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -2864,6 +2891,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -3167,7 +3203,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -3203,6 +3239,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md
index 65f3b8760..c40c0545d 100644
--- a/docs/content/reference/dynamic-configuration/kv-ref.md
+++ b/docs/content/reference/dynamic-configuration/kv-ref.md
@@ -281,6 +281,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| `traefik/http/services/Service02/loadBalancer/healthCheck/scheme` | `foobar` |
| `traefik/http/services/Service02/loadBalancer/healthCheck/status` | `42` |
| `traefik/http/services/Service02/loadBalancer/healthCheck/timeout` | `42s` |
+| `traefik/http/services/Service02/loadBalancer/healthCheck/unhealthyInterval` | `42s` |
| `traefik/http/services/Service02/loadBalancer/passHostHeader` | `true` |
| `traefik/http/services/Service02/loadBalancer/responseForwarding/flushInterval` | `42s` |
| `traefik/http/services/Service02/loadBalancer/servers/0/preservePath` | `true` |
diff --git a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml
index ed13f3d51..c01206e14 100644
--- a/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml
+++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml
@@ -136,7 +136,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -172,6 +172,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
diff --git a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml
index 0f576eb39..798caa505 100644
--- a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml
+++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml
@@ -301,7 +301,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -337,6 +337,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
diff --git a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml
index 340b36f68..3494097bd 100644
--- a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml
+++ b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml
@@ -71,7 +71,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -107,6 +107,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -156,7 +165,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -192,6 +201,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -495,7 +513,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -531,6 +549,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
diff --git a/docs/content/reference/routing-configuration/http/load-balancing/service.md b/docs/content/reference/routing-configuration/http/load-balancing/service.md
index eaa665417..43b94d88d 100644
--- a/docs/content/reference/routing-configuration/http/load-balancing/service.md
+++ b/docs/content/reference/routing-configuration/http/load-balancing/service.md
@@ -1,7 +1,7 @@
---
title: "Traefik HTTP Services Documentation"
description: "A service is in charge of connecting incoming requests to the Servers that can handle them. Read the technical documentation."
----
+---
## Service Load Balancer
@@ -70,7 +70,6 @@ labels:
```json tab="Tags"
{
- // ...
"Tags": [
"traefik.http.services.my-service.loadBalancer.servers[0].url=http://private-ip-server-1/",
"traefik.http.services.my-service.loadBalancer.servers[0].weight=2",
@@ -88,15 +87,15 @@ labels:
### Configuration Options
-| Field | Description | Required |
-|----------|------------------------------------------|----------|
-|`servers`| Represents individual backend instances for your service | Yes |
-|`sticky`| Defines a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response. | No |
-|`healthcheck`| Configures health check to remove unhealthy servers from the load balancing rotation. | No |
-|`passHostHeader`| Allows forwarding of the client Host header to server. By default, `passHostHeader` is true. | No |
-|`serversTransport`| Allows to reference an [HTTP ServersTransport](./serverstransport.md) configuration for the communication between Traefik and your servers. If no `serversTransport` is specified, the `default@internal` will be used. | No |
-| `responseForwarding` | Configures how Traefik forwards the response from the backend server to the client.| No |
-| `responseForwarding.FlushInterval` | Specifies the interval in between flushes to the client while copying the response body. It is a duration in milliseconds, defaulting to 100ms. A negative value means to flush immediately after each write to the client. The `FlushInterval` is ignored when ReverseProxy recognizes a response as a streaming response; for such responses, writes are flushed to the client immediately. | No |
+| Field | Description | Required |
+|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
+| `servers` | Represents individual backend instances for your service | Yes |
+| `sticky` | Defines a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response. | No |
+| `healthcheck` | Configures health check to remove unhealthy servers from the load balancing rotation. | No |
+| `passHostHeader` | Allows forwarding of the client Host header to server. By default, `passHostHeader` is true. | No |
+| `serversTransport` | Allows to reference an [HTTP ServersTransport](./serverstransport.md) configuration for the communication between Traefik and your servers. If no `serversTransport` is specified, the `default@internal` will be used. | No |
+| `responseForwarding` | Configures how Traefik forwards the response from the backend server to the client. | No |
+| `responseForwarding.FlushInterval` | Specifies the interval in between flushes to the client while copying the response body. It is a duration in milliseconds, defaulting to 100ms. A negative value means to flush immediately after each write to the client. The `FlushInterval` is ignored when ReverseProxy recognizes a response as a streaming response; for such responses, writes are flushed to the client immediately. | No |
#### Servers
@@ -104,11 +103,11 @@ Servers represent individual backend instances for your service. The [service lo
##### Configuration Options
-| Field | Description | Required |
-|----------|------------------------------------------|----------|
-|`url`| Points to a specific instance. | Yes for File provider, No for [Docker provider](../../other-providers/docker.md) |
-|`weight`| Allows for weighted load balancing on the servers. | No |
-|`preservePath`| Allows to preserve the URL path. | No |
+| Field | Description | Required |
+|----------------|----------------------------------------------------|----------------------------------------------------------------------------------|
+| `url` | Points to a specific instance. | Yes for File provider, No for [Docker provider](../../other-providers/docker.md) |
+| `weight` | Allows for weighted load balancing on the servers. | No |
+| `preservePath` | Allows to preserve the URL path. | No |
#### Health Check
@@ -118,20 +117,21 @@ To propagate status changes (e.g. all servers of this service are down) upwards,
Below are the available options for the health check mechanism:
-| Field | Description | Default | Required |
-|----------|------------------------------------------|----------|--------|
-|`path`| Defines the server URL path for the health check endpoint. | "" | Yes |
-|`scheme`| Replaces the server URL scheme for the health check endpoint. | | No |
-|`mode`| If defined to `grpc`, will use the gRPC health check protocol to probe the server. | http | No |
-|`hostname`| Defines the value of hostname in the Host header of the health check request. | "" | No |
-|`port`| Replaces the server URL port for the health check endpoint. | | No |
-|`interval`| Defines the frequency of the health check calls. | 30s | No |
-|`timeout`| Defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy. | 5s | No |
-|`headers`| Defines custom headers to be sent to the health check endpoint. | | No |
-|`followRedirects`| Defines whether redirects should be followed during the health check calls. | true | No |
-|`hostname`| Defines the value of hostname in the Host header of the health check request. | "" | No |
-|`method`| Defines the HTTP method that will be used while connecting to the endpoint. | GET | No |
-|`status`| Defines the expected HTTP status code of the response to the health check request. | | No |
+| Field | Description | Default | Required |
+|---------------------|-------------------------------------------------------------------------------------------------------------------------------|---------|----------|
+| `path` | Defines the server URL path for the health check endpoint. | "" | Yes |
+| `scheme` | Replaces the server URL scheme for the health check endpoint. | | No |
+| `mode` | If defined to `grpc`, will use the gRPC health check protocol to probe the server. | http | No |
+| `hostname` | Defines the value of hostname in the Host header of the health check request. | "" | No |
+| `port` | Replaces the server URL port for the health check endpoint. | | No |
+| `interval` | Defines the frequency of the health check calls for healthy targets. | 30s | No |
+| `unhealthyInterval` | Defines the frequency of the health check calls for unhealthy targets. When not defined, it defaults to the `interval` value. | 30s | No |
+| `timeout` | Defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy. | 5s | No |
+| `headers` | Defines custom headers to be sent to the health check endpoint. | | No |
+| `followRedirects` | Defines whether redirects should be followed during the health check calls. | true | No |
+| `hostname` | Defines the value of hostname in the Host header of the health check request. | "" | No |
+| `method` | Defines the HTTP method that will be used while connecting to the endpoint. | GET | No |
+| `status` | Defines the expected HTTP status code of the response to the health check request. | | No |
## Weighted Round Robin (WRR)
diff --git a/docs/content/reference/routing-configuration/kubernetes/crd/http/ingressroute.md b/docs/content/reference/routing-configuration/kubernetes/crd/http/ingressroute.md
index f1ceb293c..255f75212 100644
--- a/docs/content/reference/routing-configuration/kubernetes/crd/http/ingressroute.md
+++ b/docs/content/reference/routing-configuration/kubernetes/crd/http/ingressroute.md
@@ -74,56 +74,57 @@ spec:
## Configuration Options
-| Field | Description | Default | Required |
-|:------|:----------------------------------------------------------|:---------------------|:---------|
-| `entryPoints` | List of [entry points](../../../../install-configuration/entrypoints.md) names.
If not specified, HTTP routers will accept requests from all EntryPoints in the list of default EntryPoints. | | No |
-| `routes` | List of routes. | | Yes |
-| `routes[n].kind` | Kind of router matching, only `Rule` is allowed yet. | "Rule" | No |
-| `routes[n].match` | Defines the [rule](../../../http/router/rules-and-priority.md#rules) corresponding to an underlying router. | | Yes |
-| `routes[n].priority` | Defines the [priority](../../../http/router/rules-and-priority.md#priority-calculation) to disambiguate rules of the same length, for route matching.
If not set, the priority is directly equal to the length of the rule, and so the longest length has the highest priority.
A value of `0` for the priority is ignored, the default rules length sorting is used. | 0 | No |
-| `routes[n].middlewares` | List of middlewares to attach to the IngressRoute.
More information [here](#middleware). | "" | No |
-| `routes[n].`
`middlewares[m].`
`name` | Middleware name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes |
-| `routes[n].`
`middlewares[m].`
`namespace` | Middleware namespace.
Can be empty if the middleware belongs to the same namespace as the IngressRoute.
More information [here](#middleware). | | No |
-| `routes[n].`
`observability.`
`accesslogs` | Defines whether the route will produce [access-logs](../../../../install-configuration/observability/logs-and-accesslogs.md). See [here](../../../http/router/observability.md) for more information. | false | No |
-| `routes[n].`
`observability.`
`metrics` | Defines whether the route will produce [metrics](../../../../install-configuration/observability/metrics.md). See [here](../../../http/router/observability.md) for more information. | false | No |
-| `routes[n].`
`observability.`
`tracing` | Defines whether the route will produce [traces](../../../../install-configuration/observability/tracing.md). See [here](../../../http/router/observability.md) for more information. | false | No |
-| `routes[n].`
`services` | List of any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
More information [here](#externalname-service). | | No |
-| `routes[n].`
`services[m].`
`kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
**TraefikService**: Traefik Service.
More information [here](#externalname-service). | "Service" | No |
-| `routes[n].`
`services[m].`
`name` | Service name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes |
-| `routes[n].`
`services[m].`
`namespace` | Service namespace.
Can be empty if the service belongs to the same namespace as the IngressRoute.
More information [here](#externalname-service). | | No |
-| `routes[n].`
`services[m].`
`port` | Service port (number or port name).
Evaluated only if the kind is **Service**. | | No |
-| `routes[n].`
`services[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind is **Service**. | 100ms | No |
-| `routes[n].`
`services[m].`
`scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
-| `routes[n].`
`services[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No |
-| `routes[n].`
`services[m].`
`passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No |
-| `routes[n].`
`services[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
-| `routes[n].`
`services[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "http" | No |
-| `routes[n].`
`services[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
-| `routes[n].`
`services[m].`
`healthCheck.interval` | Frequency of the health check calls.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "100ms" | No |
-| `routes[n].`
`services[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "GET" | No |
-| `routes[n].`
`services[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind is **Service**. | | No |
-| `routes[n].`
`services[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | | No |
-| `routes[n].`
`services[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "5s" | No |
-| `routes[n].`
`services[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
-| `routes[n].`
`services[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | true | No |
-| `routes[n].`
`services[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service)). | | No |
-| `routes[n].`
`services[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
Evaluated only if the kind is **Service**. | "" | No |
-| `routes[n].`
`services[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind is **Service**. | false | No |
-| `routes[n].`
`services[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind is **Service**. | false | No |
-| `routes[n].`
`services[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind is **Service**. | "" | No |
-| `routes[n].`
`services[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind is **Service**. | 0 | No |
-| `routes[n].`
`services[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind is **Service**. | "RoundRobin" | No |
-| `routes[n].`
`services[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
-| `routes[n].`
`services[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind is **Service**. | false | No |
-| `routes[n].`
`services[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind is **Service**. | false | No |
-| `tls` | TLS configuration.
Can be an empty value(`{}`):
A self signed is generated in such a case
(or the [default certificate](tlsstore.md) is used if it is defined.) | | No |
-| `tls.secretName` | [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the same namesapce as the `IngressRoute`) | "" | No |
-| `tls.`
`options.name` | Name of the [`TLSOption`](tlsoption.md) to use.
More information [here](#tls-options). | "" | No |
-| `tls.`
`options.namespace` | Namespace of the [`TLSOption`](tlsoption.md) to use. | "" | No |
-| `tls.certResolver` | Name of the [Certificate Resolver](../../../../install-configuration/tls/certificate-resolvers/overview.md) to use to generate automatic TLS certificates. | "" | No |
-| `tls.domains` | List of domains to serve using the certificates generates (one `tls.domain`= one certificate).
More information in the [dedicated section](../../../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition). | | No |
-| `tls.`
`domains[n].main` | Main domain name | "" | Yes |
-| `tls.`
`domains[n].sans` | List of alternative domains (SANs) | | No |
+| Field | Description | Default | Required |
+|:---------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------|
+| `entryPoints` | List of [entry points](../../../../install-configuration/entrypoints.md) names.
If not specified, HTTP routers will accept requests from all EntryPoints in the list of default EntryPoints. | | No |
+| `routes` | List of routes. | | Yes |
+| `routes[n].kind` | Kind of router matching, only `Rule` is allowed yet. | "Rule" | No |
+| `routes[n].match` | Defines the [rule](../../../http/router/rules-and-priority.md#rules) corresponding to an underlying router. | | Yes |
+| `routes[n].priority` | Defines the [priority](../../../http/router/rules-and-priority.md#priority-calculation) to disambiguate rules of the same length, for route matching.
If not set, the priority is directly equal to the length of the rule, and so the longest length has the highest priority.
A value of `0` for the priority is ignored, the default rules length sorting is used. | 0 | No |
+| `routes[n].middlewares` | List of middlewares to attach to the IngressRoute.
More information [here](#middleware). | "" | No |
+| `routes[n].`
`middlewares[m].`
`name` | Middleware name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes |
+| `routes[n].`
`middlewares[m].`
`namespace` | Middleware namespace.
Can be empty if the middleware belongs to the same namespace as the IngressRoute.
More information [here](#middleware). | | No |
+| `routes[n].`
`observability.`
`accesslogs` | Defines whether the route will produce [access-logs](../../../../install-configuration/observability/logs-and-accesslogs.md). See [here](../../../http/router/observability.md) for more information. | false | No |
+| `routes[n].`
`observability.`
`metrics` | Defines whether the route will produce [metrics](../../../../install-configuration/observability/metrics.md). See [here](../../../http/router/observability.md) for more information. | false | No |
+| `routes[n].`
`observability.`
`tracing` | Defines whether the route will produce [traces](../../../../install-configuration/observability/tracing.md). See [here](../../../http/router/observability.md) for more information. | false | No |
+| `routes[n].`
`services` | List of any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
More information [here](#externalname-service). | | No |
+| `routes[n].`
`services[m].`
`kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
**TraefikService**: Traefik Service.
More information [here](#externalname-service). | "Service" | No |
+| `routes[n].`
`services[m].`
`name` | Service name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes |
+| `routes[n].`
`services[m].`
`namespace` | Service namespace.
Can be empty if the service belongs to the same namespace as the IngressRoute.
More information [here](#externalname-service). | | No |
+| `routes[n].`
`services[m].`
`port` | Service port (number or port name).
Evaluated only if the kind is **Service**. | | No |
+| `routes[n].`
`services[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind is **Service**. | 100ms | No |
+| `routes[n].`
`services[m].`
`scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
+| `routes[n].`
`services[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No |
+| `routes[n].`
`services[m].`
`passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No |
+| `routes[n].`
`services[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
+| `routes[n].`
`services[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "http" | No |
+| `routes[n].`
`services[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
+| `routes[n].`
`services[m].`
`healthCheck.interval` | Frequency of the health check calls for healthy targets.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "100ms" | No |
+| `routes[n].`
`services[m].`
`healthCheck.unhealthyInterval` | Frequency of the health check calls for unhealthy targets.
When not defined, it defaults to the `interval` value.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "100ms" | No |
+| `routes[n].`
`services[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "GET" | No |
+| `routes[n].`
`services[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind is **Service**. | | No |
+| `routes[n].`
`services[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | | No |
+| `routes[n].`
`services[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "5s" | No |
+| `routes[n].`
`services[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | "" | No |
+| `routes[n].`
`services[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service). | true | No |
+| `routes[n].`
`services[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#externalname-service)). | | No |
+| `routes[n].`
`services[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
Evaluated only if the kind is **Service**. | "" | No |
+| `routes[n].`
`services[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind is **Service**. | false | No |
+| `routes[n].`
`services[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind is **Service**. | false | No |
+| `routes[n].`
`services[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind is **Service**. | "" | No |
+| `routes[n].`
`services[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind is **Service**. | 0 | No |
+| `routes[n].`
`services[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind is **Service**. | "RoundRobin" | No |
+| `routes[n].`
`services[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
+| `routes[n].`
`services[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind is **Service**. | false | No |
+| `routes[n].`
`services[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind is **Service**. | false | No |
+| `tls` | TLS configuration.
Can be an empty value(`{}`):
A self signed is generated in such a case
(or the [default certificate](tlsstore.md) is used if it is defined.) | | No |
+| `tls.secretName` | [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the same namesapce as the `IngressRoute`) | "" | No |
+| `tls.`
`options.name` | Name of the [`TLSOption`](tlsoption.md) to use.
More information [here](#tls-options). | "" | No |
+| `tls.`
`options.namespace` | Namespace of the [`TLSOption`](tlsoption.md) to use. | "" | No |
+| `tls.certResolver` | Name of the [Certificate Resolver](../../../../install-configuration/tls/certificate-resolvers/overview.md) to use to generate automatic TLS certificates. | "" | No |
+| `tls.domains` | List of domains to serve using the certificates generates (one `tls.domain`= one certificate).
More information in the [dedicated section](../../../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition). | | No |
+| `tls.`
`domains[n].main` | Main domain name | "" | Yes |
+| `tls.`
`domains[n].sans` | List of alternative domains (SANs) | | No |
### ExternalName Service
diff --git a/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md b/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md
index acda27c48..71bd5b2f4 100644
--- a/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md
+++ b/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md
@@ -148,42 +148,43 @@ data:
### Configuration Options
-| Field | Description | Default | Required |
-|:------|:----------------------------------------------------------|:---------------------|:---------|
-| `services` | List of any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
. | | No |
-| `services[m].`
`kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service. | "" | No |
-| `services[m].`
`name` | Service name.
The character `@` is not authorized. | "" | Yes |
-| `services[m].`
`namespace` | Service namespace. | "" | No |
-| `services[m].`
`port` | Service port (number or port name).
Evaluated only if the kind is **Service**. | "" | No |
-| `services[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind is **Service**. | 100ms | No |
-| `services[m].`
`scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
-| `services[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No |
-| `services[m].`
`passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No |
-| `services[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
-| `services[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "http" | No |
-| `services[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
-| `services[m].`
`healthCheck.interval` | Frequency of the health check calls.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName]`ExternalName`. | "100ms" | No |
-| `services[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "GET" | No |
-| `services[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind is **Service**. | | No |
-| `services[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | | No |
-| `services[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "5s" | No |
-| `services[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
-| `services[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | true | No |
-| `services[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | | No |
-| `services[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
Evaluated only if the kind is **Service**. | Abbreviation of a sha1
(ex: `_1d52e`). | No |
-| `services[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind is **Service**. | false | No |
-| `services[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind is **Service**. | false | No |
-| `services[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind is **Service**. | "" | No |
-| `services[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind is **Service**. | 0 | No |
-| `services[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind is **Service**. | "RoundRobin" | No |
-| `services[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
-| `services[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind is **Service**. | false | No |
-| `services[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind is **Service**. | false | No |
-| `sticky.`
`cookie.name` | Name of the cookie used for the stickiness at the WRR service level.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | Abbreviation of a sha1
(ex: `_1d52e`). | No |
-| `sticky.`
`cookie.httpOnly` | Allow the cookie used for the stickiness at the WRR service level to be accessed by client-side APIs, such as JavaScript.
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | false | No |
-| `sticky.`
`cookie.secure` | Allow the cookie used for the stickiness at the WRR service level to be only transmitted over an encrypted connection (i.e. HTTPS).
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | false | No |
-| `sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy for the cookie used for the stickiness at the WRR service level.
Allowed values:
-`none`
-`lax`
`strict`
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | "" | No |
-| `sticky.`
`cookie.maxAge` | Number of seconds until the cookie used for the stickiness at the WRR service level expires.
Negative number, the cookie expires immediately.
0, the cookie never expires. | 0 | No |
+| Field | Description | Default | Required |
+|:---------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------|
+| `services` | List of any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
. | | No |
+| `services[m].`
`kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service. | "" | No |
+| `services[m].`
`name` | Service name.
The character `@` is not authorized. | "" | Yes |
+| `services[m].`
`namespace` | Service namespace. | "" | No |
+| `services[m].`
`port` | Service port (number or port name).
Evaluated only if the kind is **Service**. | "" | No |
+| `services[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind is **Service**. | 100ms | No |
+| `services[m].`
`scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
+| `services[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No |
+| `services[m].`
`passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No |
+| `services[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
+| `services[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "http" | No |
+| `services[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
+| `services[m].`
`healthCheck.interval` | Frequency of the health check calls for healthy targets.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName]`ExternalName`. | "100ms" | No |
+| `services[m].`
`healthCheck.unhealthyInterval` | Frequency of the health check calls for unhealthy targets.
When not defined, it defaults to the `interval` value.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName]`ExternalName`. | "100ms" | No |
+| `services[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "GET" | No |
+| `services[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind is **Service**. | | No |
+| `services[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | | No |
+| `services[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "5s" | No |
+| `services[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | "" | No |
+| `services[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | true | No |
+| `services[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type `ExternalName`. | | No |
+| `services[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
Evaluated only if the kind is **Service**. | Abbreviation of a sha1
(ex: `_1d52e`). | No |
+| `services[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind is **Service**. | false | No |
+| `services[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind is **Service**. | false | No |
+| `services[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind is **Service**. | "" | No |
+| `services[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind is **Service**. | 0 | No |
+| `services[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind is **Service**. | "RoundRobin" | No |
+| `services[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
+| `services[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind is **Service**. | false | No |
+| `services[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind is **Service**. | false | No |
+| `sticky.`
`cookie.name` | Name of the cookie used for the stickiness at the WRR service level.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | Abbreviation of a sha1
(ex: `_1d52e`). | No |
+| `sticky.`
`cookie.httpOnly` | Allow the cookie used for the stickiness at the WRR service level to be accessed by client-side APIs, such as JavaScript.
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | false | No |
+| `sticky.`
`cookie.secure` | Allow the cookie used for the stickiness at the WRR service level to be only transmitted over an encrypted connection (i.e. HTTPS).
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | false | No |
+| `sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy for the cookie used for the stickiness at the WRR service level.
Allowed values:
-`none`
-`lax`
`strict`
More information about WRR stickiness [here](#stickiness-on-multiple-levels) | "" | No |
+| `sticky.`
`cookie.maxAge` | Number of seconds until the cookie used for the stickiness at the WRR service level expires.
Negative number, the cookie expires immediately.
0, the cookie never expires. | 0 | No |
#### Stickiness on multiple levels
@@ -372,65 +373,67 @@ spec:
The mirrored services properties are set in the `mirrors` list.
-| Field | Description | Default | Required |
-|:------|:----------------------------------------------------------|:---------------------|:---------|
-| `kind` | Kind of the main service.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service.
More information [here](#services) | "" | No |
-| `name` | Main service name.
The character `@` is not authorized. | "" | Yes |
-| `namespace` | Main service namespace.
More information [here](#services). | "" | No |
-| `port` | Main service port (number or port name).
Evaluated only if the kind of the main service is **Service**. | "" | No |
-| `responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind of the main service is **Service**. | 100ms | No |
-| `scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind of the main service is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
-| `serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and the main service's servers.
Evaluated only if the kind of the main service is **Service**. | "" | No |
-| `passHostHeader` | Forward client Host header to main service's server.
Evaluated only if the kind of the main service is **Service**. | true | No |
-| `healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "http" | No |
-| `healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `healthCheck.interval` | Frequency of the health check calls.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
-| `healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "GET" | No |
-| `healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind of the main service is **Service**. | | No |
-| `healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
-| `healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "5s" | No |
-| `healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | true | No |
-| `healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
-| `sticky.`
`cookie.name` | Name of the cookie used for the stickiness on the main service.
Evaluated only if the kind of the main service is **Service**. | Abbreviation of a sha1
(ex: `_1d52e`). | No |
-| `sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind of the main service is **Service**. | false | No |
-| `sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind of the main service is **Service**. | false | No |
-| `sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind of the main service is **Service**. | "" | No |
-| `sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind of the main service is **Service**. | 0 | No |
-| `strategy` | Load balancing strategy between the main service's servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind of the main service is **Service**. | "RoundRobin" | No |
-| `weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
-| `nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind of the main service is **Service**. | false | No |
-| `nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind of the main service is **Service**. | false | No |
-| `maxBodySize` | Maximum size allowed for the body of the request.
If the body is larger, the request is not mirrored.
-1 means unlimited size. | -1 | No |
-| `mirrors` | List of mirrored services to target.
It can be any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
More information [here](#services). | | No |
-| `mirrors[m].`
`kind` | Kind of the mirrored service targeted.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service.
More information [here](#services) | "" | No |
-| `mirrors[m].`
`name` | Mirrored service name.
The character `@` is not authorized. | "" | Yes |
-| `mirrors[m].`
`namespace` | Mirrored service namespace.
More information [here](#services). | "" | No |
-| `mirrors[m].`
`port` | Mirrored service port (number or port name).
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
-| `mirrors[m].`
`percent` | Part of the traffic to mirror in percent (from 0 to 100) | 0 | No |
-| `mirrors[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind of the mirrored service is **Service**. | 100ms | No |
-| `mirrors[m].`
`scheme` | Scheme to use for the request to the mirrored service.
Evaluated only if the kind of the mirrored service is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
-| `mirrors[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and the mirrored service servers.
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
-| `mirrors[m].`
`passHostHeader` | Forward client Host header to the mirrored service servers.
Evaluated only if the kind of the mirrored service is **Service**. | true | No |
-| `mirrors[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `mirrors[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "http" | No |
-| `mirrors[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `mirrors[m].`
`healthCheck.interval` | Frequency of the health check calls.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
-| `mirrors[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "GET" | No |
-| `mirrors[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind of the mirrored service is **Service**. | | No |
-| `mirrors[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
-| `mirrors[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "5s" | No |
-| `mirrors[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
-| `mirrors[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | true | No |
-| `mirrors[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
-| `mirrors[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
-| `mirrors[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
-| `mirrors[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
-| `mirrors[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
-| `mirrors[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind of the mirrored service is **Service**. | 0 | No |
-| `mirrors[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind of the mirrored service is **Service**. | "RoundRobin" | No |
-| `mirrors[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
-| `mirrors[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
-| `mirrors[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
-| `mirrorBody` | Defines whether the request body should be mirrored. | true | No |
+| Field | Description | Default | Required |
+|:--------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------|
+| `kind` | Kind of the main service.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service.
More information [here](#services) | "" | No |
+| `name` | Main service name.
The character `@` is not authorized. | "" | Yes |
+| `namespace` | Main service namespace.
More information [here](#services). | "" | No |
+| `port` | Main service port (number or port name).
Evaluated only if the kind of the main service is **Service**. | "" | No |
+| `responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind of the main service is **Service**. | 100ms | No |
+| `scheme` | Scheme to use for the request to the upstream Kubernetes Service.
Evaluated only if the kind of the main service is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
+| `serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and the main service's servers.
Evaluated only if the kind of the main service is **Service**. | "" | No |
+| `passHostHeader` | Forward client Host header to main service's server.
Evaluated only if the kind of the main service is **Service**. | true | No |
+| `healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "http" | No |
+| `healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `healthCheck.interval` | Frequency of the health check calls for healthy targets.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
+| `healthCheck.unhealthyInterval` | Frequency of the health check calls for unhealthy targets.
When not defined, it defaults to the `interval` value.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
+| `healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "GET" | No |
+| `healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind of the main service is **Service**. | | No |
+| `healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
+| `healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "5s" | No |
+| `healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | true | No |
+| `healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind of the main service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
+| `sticky.`
`cookie.name` | Name of the cookie used for the stickiness on the main service.
Evaluated only if the kind of the main service is **Service**. | Abbreviation of a sha1
(ex: `_1d52e`). | No |
+| `sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind of the main service is **Service**. | false | No |
+| `sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind of the main service is **Service**. | false | No |
+| `sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind of the main service is **Service**. | "" | No |
+| `sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind of the main service is **Service**. | 0 | No |
+| `strategy` | Load balancing strategy between the main service's servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind of the main service is **Service**. | "RoundRobin" | No |
+| `weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
+| `nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind of the main service is **Service**. | false | No |
+| `nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind of the main service is **Service**. | false | No |
+| `maxBodySize` | Maximum size allowed for the body of the request.
If the body is larger, the request is not mirrored.
-1 means unlimited size. | -1 | No |
+| `mirrors` | List of mirrored services to target.
It can be any combination of TraefikService and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/).
More information [here](#services). | | No |
+| `mirrors[m].`
`kind` | Kind of the mirrored service targeted.
Two values allowed:
- **Service**: Kubernetes Service
- **TraefikService**: Traefik Service.
More information [here](#services) | "" | No |
+| `mirrors[m].`
`name` | Mirrored service name.
The character `@` is not authorized. | "" | Yes |
+| `mirrors[m].`
`namespace` | Mirrored service namespace.
More information [here](#services). | "" | No |
+| `mirrors[m].`
`port` | Mirrored service port (number or port name).
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
+| `mirrors[m].`
`percent` | Part of the traffic to mirror in percent (from 0 to 100) | 0 | No |
+| `mirrors[m].`
`responseForwarding.`
`flushInterval` | Interval, in milliseconds, in between flushes to the client while copying the response body.
A negative value means to flush immediately after each write to the client.
This configuration is ignored when a response is a streaming response; for such responses, writes are flushed to the client immediately.
Evaluated only if the kind of the mirrored service is **Service**. | 100ms | No |
+| `mirrors[m].`
`scheme` | Scheme to use for the request to the mirrored service.
Evaluated only if the kind of the mirrored service is **Service**. | "http"
"https" if `port` is 443 or contains the string *https*. | No |
+| `mirrors[m].`
`serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and the mirrored service servers.
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
+| `mirrors[m].`
`passHostHeader` | Forward client Host header to the mirrored service servers.
Evaluated only if the kind of the mirrored service is **Service**. | true | No |
+| `mirrors[m].`
`healthCheck.scheme` | Server URL scheme for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `mirrors[m].`
`healthCheck.mode` | Health check mode.
If defined to grpc, will use the gRPC health check protocol to probe the server.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "http" | No |
+| `mirrors[m].`
`healthCheck.path` | Server URL path for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `mirrors[m].`
`healthCheck.interval` | Frequency of the health check calls.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
+| `mirrors[m].`
`healthCheck.unhealthyInterval` | Frequency of the health check calls for unhealthy targets.
When not defined, it defaults to the `interval` value.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "100ms" | No |
+| `mirrors[m].`
`healthCheck.method` | HTTP method for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "GET" | No |
+| `mirrors[m].`
`healthCheck.status` | Expected HTTP status code of the response to the health check request.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind of the mirrored service is **Service**. | | No |
+| `mirrors[m].`
`healthCheck.port` | URL port for the health check endpoint.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
+| `mirrors[m].`
`healthCheck.timeout` | Maximum duration to wait before considering the server unhealthy.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "5s" | No |
+| `mirrors[m].`
`healthCheck.hostname` | Value in the Host header of the health check request.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | "" | No |
+| `mirrors[m].`
`healthCheck.`
`followRedirect` | Follow the redirections during the healtchcheck.
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | true | No |
+| `mirrors[m].`
`healthCheck.headers` | Map of header to send to the health check endpoint
Evaluated only if the kind of the mirrored service is **Service**.
Only for [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) of type [ExternalName](#services). | | No |
+| `mirrors[m].`
`sticky.`
`cookie.name` | Name of the cookie used for the stickiness.
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
If the server pecified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
+| `mirrors[m].`
`sticky.`
`cookie.httpOnly` | Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
+| `mirrors[m].`
`sticky.`
`cookie.secure` | Allow the cookie can only be transmitted over an encrypted connection (i.e. HTTPS).
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
+| `mirrors[m].`
`sticky.`
`cookie.sameSite` | [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) policy.
Allowed values:
-`none`
-`lax`
`strict`
Evaluated only if the kind of the mirrored service is **Service**. | "" | No |
+| `mirrors[m].`
`sticky.`
`cookie.maxAge` | Number of seconds until the cookie expires.
Negative number, the cookie expires immediately.
0, the cookie never expires.
Evaluated only if the kind of the mirrored service is **Service**. | 0 | No |
+| `mirrors[m].`
`strategy` | Load balancing strategy between the servers.
RoundRobin is the only supported value yet.
Evaluated only if the kind of the mirrored service is **Service**. | "RoundRobin" | No |
+| `mirrors[m].`
`weight` | Service weight.
To use only to refer to WRR TraefikService | "" | No |
+| `mirrors[m].`
`nativeLB` | Allow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
+| `mirrors[m].`
`nodePortLB` | Use the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind of the mirrored service is **Service**. | false | No |
+| `mirrorBody` | Defines whether the request body should be mirrored. | true | No |
diff --git a/docs/content/reference/routing-configuration/other-providers/consul-catalog.md b/docs/content/reference/routing-configuration/other-providers/consul-catalog.md
index 534891cf3..77f4f3f18 100644
--- a/docs/content/reference/routing-configuration/other-providers/consul-catalog.md
+++ b/docs/content/reference/routing-configuration/other-providers/consul-catalog.md
@@ -222,6 +222,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/reference/routing-configuration/other-providers/docker.md b/docs/content/reference/routing-configuration/other-providers/docker.md
index e17c9fc91..f6e07620c 100644
--- a/docs/content/reference/routing-configuration/other-providers/docker.md
+++ b/docs/content/reference/routing-configuration/other-providers/docker.md
@@ -327,6 +327,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa
"traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ ```yaml
+ "traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/reference/routing-configuration/other-providers/ecs.md b/docs/content/reference/routing-configuration/other-providers/ecs.md
index b17d9330a..128da324b 100644
--- a/docs/content/reference/routing-configuration/other-providers/ecs.md
+++ b/docs/content/reference/routing-configuration/other-providers/ecs.md
@@ -218,6 +218,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/reference/routing-configuration/other-providers/kv.md b/docs/content/reference/routing-configuration/other-providers/kv.md
index 963d83cb0..b6aeb9c7b 100644
--- a/docs/content/reference/routing-configuration/other-providers/kv.md
+++ b/docs/content/reference/routing-configuration/other-providers/kv.md
@@ -203,6 +203,14 @@ description: "Read the technical documentation to learn the Traefik Routing Conf
|---------------------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/healthcheck/interval` | `10` |
+??? info "`traefik/http/services//loadbalancer/healthcheck/unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ | Key (Path) | Value |
+ |------------------------------------------------------------------------------|-------|
+ | `traefik/http/services/myservice/loadbalancer/healthcheck/unhealthyinterval` | `10` |
+
??? info "`traefik/http/services//loadbalancer/healthcheck/path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/reference/routing-configuration/other-providers/nomad.md b/docs/content/reference/routing-configuration/other-providers/nomad.md
index b8cc400c9..37bd6a4b8 100644
--- a/docs/content/reference/routing-configuration/other-providers/nomad.md
+++ b/docs/content/reference/routing-configuration/other-providers/nomad.md
@@ -222,6 +222,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/reference/routing-configuration/other-providers/swarm.md b/docs/content/reference/routing-configuration/other-providers/swarm.md
index 51b2371c0..59f21aed9 100644
--- a/docs/content/reference/routing-configuration/other-providers/swarm.md
+++ b/docs/content/reference/routing-configuration/other-providers/swarm.md
@@ -351,6 +351,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../http/load-balancing/service.md#health-check) for more information.
+
+ ```yaml
+ - "traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md
index 76b326b55..d8d07bc0a 100644
--- a/docs/content/routing/providers/consul-catalog.md
+++ b/docs/content/routing/providers/consul-catalog.md
@@ -218,6 +218,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md
index aedbfe09f..d1fac0b27 100644
--- a/docs/content/routing/providers/docker.md
+++ b/docs/content/routing/providers/docker.md
@@ -333,6 +333,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ ```yaml
+ - "traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/providers/ecs.md b/docs/content/routing/providers/ecs.md
index e85975409..c740a5ff9 100644
--- a/docs/content/routing/providers/ecs.md
+++ b/docs/content/routing/providers/ecs.md
@@ -220,6 +220,14 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md
index 37e6148f5..88ed9bf8a 100644
--- a/docs/content/routing/providers/kv.md
+++ b/docs/content/routing/providers/kv.md
@@ -180,6 +180,14 @@ A Story of key & values
|---------------------------------------------------------------------|-------|
| `traefik/http/services/myservice/loadbalancer/healthcheck/interval` | `10` |
+??? info "`traefik/http/services//loadbalancer/healthcheck/unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ | Key (Path) | Value |
+ |------------------------------------------------------------------------------|-------|
+ | `traefik/http/services/myservice/loadbalancer/healthcheck/unhealthyinterval` | `10` |
+
??? info "`traefik/http/services//loadbalancer/healthcheck/path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/providers/nomad.md b/docs/content/routing/providers/nomad.md
index 613f35a7b..50ac7451b 100644
--- a/docs/content/routing/providers/nomad.md
+++ b/docs/content/routing/providers/nomad.md
@@ -218,6 +218,14 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ ```yaml
+ traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/providers/swarm.md b/docs/content/routing/providers/swarm.md
index bd9685ef6..13ef3ffaa 100644
--- a/docs/content/routing/providers/swarm.md
+++ b/docs/content/routing/providers/swarm.md
@@ -347,6 +347,14 @@ you'd add the label `traefik.http.services..loadbalancer.pa
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
+??? info "`traefik.http.services..loadbalancer.healthcheck.unhealthyinterval`"
+
+ See [health check](../services/index.md#health-check) for more information.
+
+ ```yaml
+ - "traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
+ ```
+
??? info "`traefik.http.services..loadbalancer.healthcheck.path`"
See [health check](../services/index.md#health-check) for more information.
diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md
index 199fb81a3..e2745e4c4 100644
--- a/docs/content/routing/services/index.md
+++ b/docs/content/routing/services/index.md
@@ -415,7 +415,8 @@ Below are the available options for the health check mechanism:
- `mode` (default: http), if defined to `grpc`, will use the gRPC health check protocol to probe the server.
- `hostname` (optional), sets the value of `hostname` in the `Host` header of the health check request.
- `port` (optional), replaces the server URL `port` for the health check endpoint.
-- `interval` (default: 30s), defines the frequency of the health check calls.
+- `interval` (default: 30s), defines the frequency of the health check calls for healthy targets.
+- `unhealthyInterval` (default: 30s), defines the frequency of the health check calls for unhealthy targets. When not defined, it defaults to the `interval` value.
- `timeout` (default: 5s), defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
- `headers` (optional), defines custom headers to be sent to the health check endpoint.
- `followRedirects` (default: true), defines whether redirects should be followed during the health check calls.
@@ -424,7 +425,7 @@ Below are the available options for the health check mechanism:
!!! info "Interval & Timeout Format"
- Interval and timeout are to be given in a format understood by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
+ Interval, UnhealthyInterval and Timeout are to be given in a format understood by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
!!! info "Recovering Servers"
diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml
index f14cce498..0541d1607 100644
--- a/integration/fixtures/k8s/01-traefik-crd.yml
+++ b/integration/fixtures/k8s/01-traefik-crd.yml
@@ -136,7 +136,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -172,6 +172,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -1070,7 +1079,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -1106,6 +1115,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -2743,7 +2761,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -2779,6 +2797,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -2828,7 +2855,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -2864,6 +2891,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
@@ -3167,7 +3203,7 @@ spec:
- type: integer
- type: string
description: |-
- Interval defines the frequency of the health check calls.
+ Interval defines the frequency of the health check calls for healthy targets.
Default: 30s
x-kubernetes-int-or-string: true
method:
@@ -3203,6 +3239,15 @@ spec:
Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
Default: 5s
x-kubernetes-int-or-string: true
+ unhealthyInterval:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ When UnhealthyInterval is not defined, it defaults to the Interval value.
+ Default: 30s
+ x-kubernetes-int-or-string: true
type: object
kind:
description: Kind defines the kind of the Service.
diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go
index d91f60340..a867c882b 100644
--- a/pkg/config/dynamic/http_config.go
+++ b/pkg/config/dynamic/http_config.go
@@ -299,17 +299,18 @@ type Server struct {
// ServerHealthCheck holds the HealthCheck configuration.
type ServerHealthCheck struct {
- Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
- Mode string `json:"mode,omitempty" toml:"mode,omitempty" yaml:"mode,omitempty" export:"true"`
- Path string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
- Method string `json:"method,omitempty" toml:"method,omitempty" yaml:"method,omitempty" export:"true"`
- Status int `json:"status,omitempty" toml:"status,omitempty" yaml:"status,omitempty" export:"true"`
- Port int `json:"port,omitempty" toml:"port,omitempty,omitzero" yaml:"port,omitempty" export:"true"`
- Interval ptypes.Duration `json:"interval,omitempty" toml:"interval,omitempty" yaml:"interval,omitempty" export:"true"`
- Timeout ptypes.Duration `json:"timeout,omitempty" toml:"timeout,omitempty" yaml:"timeout,omitempty" export:"true"`
- Hostname string `json:"hostname,omitempty" toml:"hostname,omitempty" yaml:"hostname,omitempty"`
- FollowRedirects *bool `json:"followRedirects,omitempty" toml:"followRedirects,omitempty" yaml:"followRedirects,omitempty" export:"true"`
- Headers map[string]string `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
+ Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
+ Mode string `json:"mode,omitempty" toml:"mode,omitempty" yaml:"mode,omitempty" export:"true"`
+ Path string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
+ Method string `json:"method,omitempty" toml:"method,omitempty" yaml:"method,omitempty" export:"true"`
+ Status int `json:"status,omitempty" toml:"status,omitempty" yaml:"status,omitempty" export:"true"`
+ Port int `json:"port,omitempty" toml:"port,omitempty,omitzero" yaml:"port,omitempty" export:"true"`
+ Interval ptypes.Duration `json:"interval,omitempty" toml:"interval,omitempty" yaml:"interval,omitempty" export:"true"`
+ UnhealthyInterval *ptypes.Duration `json:"unhealthyInterval,omitempty" toml:"unhealthyInterval,omitempty" yaml:"unhealthyInterval,omitempty" export:"true"`
+ Timeout ptypes.Duration `json:"timeout,omitempty" toml:"timeout,omitempty" yaml:"timeout,omitempty" export:"true"`
+ Hostname string `json:"hostname,omitempty" toml:"hostname,omitempty" yaml:"hostname,omitempty"`
+ FollowRedirects *bool `json:"followRedirects,omitempty" toml:"followRedirects,omitempty" yaml:"followRedirects,omitempty" export:"true"`
+ Headers map[string]string `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
}
// SetDefaults Default values for a HealthCheck.
diff --git a/pkg/config/dynamic/zz_generated.deepcopy.go b/pkg/config/dynamic/zz_generated.deepcopy.go
index 2a680897c..9cf39ba40 100644
--- a/pkg/config/dynamic/zz_generated.deepcopy.go
+++ b/pkg/config/dynamic/zz_generated.deepcopy.go
@@ -1428,6 +1428,11 @@ func (in *Server) DeepCopy() *Server {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServerHealthCheck) DeepCopyInto(out *ServerHealthCheck) {
*out = *in
+ if in.UnhealthyInterval != nil {
+ in, out := &in.UnhealthyInterval, &out.UnhealthyInterval
+ *out = new(paersertypes.Duration)
+ **out = **in
+ }
if in.FollowRedirects != nil {
in, out := &in.FollowRedirects, &out.FollowRedirects
*out = new(bool)
diff --git a/pkg/config/label/label_test.go b/pkg/config/label/label_test.go
index bd763ba08..b17222410 100644
--- a/pkg/config/label/label_test.go
+++ b/pkg/config/label/label_test.go
@@ -162,6 +162,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service0.loadbalancer.healthcheck.headers.name1": "foobar",
"traefik.http.services.Service0.loadbalancer.healthcheck.hostname": "foobar",
"traefik.http.services.Service0.loadbalancer.healthcheck.interval": "1s",
+ "traefik.http.services.Service0.loadbalancer.healthcheck.unhealthyinterval": "1s",
"traefik.http.services.Service0.loadbalancer.healthcheck.path": "foobar",
"traefik.http.services.Service0.loadbalancer.healthcheck.method": "foobar",
"traefik.http.services.Service0.loadbalancer.healthcheck.status": "401",
@@ -186,6 +187,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.hostname": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.interval": "1s",
+ "traefik.http.services.Service1.loadbalancer.healthcheck.unhealthyinterval": "1s",
"traefik.http.services.Service1.loadbalancer.healthcheck.path": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.method": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.status": "401",
@@ -701,15 +703,16 @@ func TestDecodeConfiguration(t *testing.T) {
},
},
HealthCheck: &dynamic.ServerHealthCheck{
- Scheme: "foobar",
- Mode: "foobar",
- Path: "foobar",
- Method: "foobar",
- Status: 401,
- Port: 42,
- Interval: ptypes.Duration(time.Second),
- Timeout: ptypes.Duration(time.Second),
- Hostname: "foobar",
+ Scheme: "foobar",
+ Mode: "foobar",
+ Path: "foobar",
+ Method: "foobar",
+ Status: 401,
+ Port: 42,
+ Interval: ptypes.Duration(time.Second),
+ UnhealthyInterval: pointer(ptypes.Duration(time.Second)),
+ Timeout: ptypes.Duration(time.Second),
+ Hostname: "foobar",
Headers: map[string]string{
"name0": "foobar",
"name1": "foobar",
@@ -735,15 +738,16 @@ func TestDecodeConfiguration(t *testing.T) {
},
},
HealthCheck: &dynamic.ServerHealthCheck{
- Scheme: "foobar",
- Mode: "foobar",
- Path: "foobar",
- Method: "foobar",
- Status: 401,
- Port: 42,
- Interval: ptypes.Duration(time.Second),
- Timeout: ptypes.Duration(time.Second),
- Hostname: "foobar",
+ Scheme: "foobar",
+ Mode: "foobar",
+ Path: "foobar",
+ Method: "foobar",
+ Status: 401,
+ Port: 42,
+ Interval: ptypes.Duration(time.Second),
+ UnhealthyInterval: pointer(ptypes.Duration(time.Second)),
+ Timeout: ptypes.Duration(time.Second),
+ Hostname: "foobar",
Headers: map[string]string{
"name0": "foobar",
"name1": "foobar",
@@ -1244,14 +1248,15 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
HealthCheck: &dynamic.ServerHealthCheck{
- Scheme: "foobar",
- Path: "foobar",
- Method: "foobar",
- Status: 401,
- Port: 42,
- Interval: ptypes.Duration(time.Second),
- Timeout: ptypes.Duration(time.Second),
- Hostname: "foobar",
+ Scheme: "foobar",
+ Path: "foobar",
+ Method: "foobar",
+ Status: 401,
+ Port: 42,
+ Interval: ptypes.Duration(time.Second),
+ UnhealthyInterval: pointer(ptypes.Duration(time.Second)),
+ Timeout: ptypes.Duration(time.Second),
+ Hostname: "foobar",
Headers: map[string]string{
"name0": "foobar",
"name1": "foobar",
@@ -1276,14 +1281,15 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
HealthCheck: &dynamic.ServerHealthCheck{
- Scheme: "foobar",
- Path: "foobar",
- Method: "foobar",
- Status: 401,
- Port: 42,
- Interval: ptypes.Duration(time.Second),
- Timeout: ptypes.Duration(time.Second),
- Hostname: "foobar",
+ Scheme: "foobar",
+ Path: "foobar",
+ Method: "foobar",
+ Status: 401,
+ Port: 42,
+ Interval: ptypes.Duration(time.Second),
+ UnhealthyInterval: pointer(ptypes.Duration(time.Second)),
+ Timeout: ptypes.Duration(time.Second),
+ Hostname: "foobar",
Headers: map[string]string{
"name0": "foobar",
"name1": "foobar",
@@ -1471,6 +1477,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name1": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Hostname": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Interval": "1000000000",
+ "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.UnhealthyInterval": "1000000000",
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Path": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Method": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Status": "401",
@@ -1495,6 +1502,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Hostname": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Interval": "1000000000",
+ "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.UnhealthyInterval": "1000000000",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Path": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Method": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Status": "401",
diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go
index c9d3e7e36..e2679d73c 100644
--- a/pkg/healthcheck/healthcheck.go
+++ b/pkg/healthcheck/healthcheck.go
@@ -40,18 +40,27 @@ type metricsHealthCheck interface {
ServiceServerUpGauge() gokitmetrics.Gauge
}
+type target struct {
+ targetURL *url.URL
+ name string
+}
+
type ServiceHealthChecker struct {
balancer StatusSetter
info *runtime.ServiceInfo
- config *dynamic.ServerHealthCheck
- interval time.Duration
- timeout time.Duration
+ config *dynamic.ServerHealthCheck
+ interval time.Duration
+ unhealthyInterval time.Duration
+ timeout time.Duration
metrics metricsHealthCheck
- client *http.Client
- targets map[string]*url.URL
+ client *http.Client
+
+ healthyTargets chan target
+ unhealthyTargets chan target
+
serviceName string
}
@@ -60,13 +69,26 @@ func NewServiceHealthChecker(ctx context.Context, metrics metricsHealthCheck, co
interval := time.Duration(config.Interval)
if interval <= 0 {
- logger.Error().Msg("Health check interval smaller than zero")
+ logger.Error().Msg("Health check interval smaller than zero, default value will be used instead.")
interval = time.Duration(dynamic.DefaultHealthCheckInterval)
}
+ // If the unhealthyInterval option is not set, we use the interval option value,
+ // to check the unhealthy targets as often as the healthy ones.
+ var unhealthyInterval time.Duration
+ if config.UnhealthyInterval == nil {
+ unhealthyInterval = interval
+ } else {
+ unhealthyInterval = time.Duration(*config.UnhealthyInterval)
+ if unhealthyInterval <= 0 {
+ logger.Error().Msg("Health check unhealthy interval smaller than zero, default value will be used instead.")
+ unhealthyInterval = time.Duration(dynamic.DefaultHealthCheckInterval)
+ }
+ }
+
timeout := time.Duration(config.Timeout)
if timeout <= 0 {
- logger.Error().Msg("Health check timeout smaller than zero")
+ logger.Error().Msg("Health check timeout smaller than zero, default value will be used instead.")
timeout = time.Duration(dynamic.DefaultHealthCheckTimeout)
}
@@ -80,21 +102,38 @@ func NewServiceHealthChecker(ctx context.Context, metrics metricsHealthCheck, co
}
}
+ healthyTargets := make(chan target, len(targets))
+ for name, targetURL := range targets {
+ healthyTargets <- target{
+ targetURL: targetURL,
+ name: name,
+ }
+ }
+ unhealthyTargets := make(chan target, len(targets))
+
return &ServiceHealthChecker{
- balancer: service,
- info: info,
- config: config,
- interval: interval,
- timeout: timeout,
- targets: targets,
- serviceName: serviceName,
- client: client,
- metrics: metrics,
+ balancer: service,
+ info: info,
+ config: config,
+ interval: interval,
+ unhealthyInterval: unhealthyInterval,
+ timeout: timeout,
+ healthyTargets: healthyTargets,
+ unhealthyTargets: unhealthyTargets,
+ serviceName: serviceName,
+ client: client,
+ metrics: metrics,
}
}
func (shc *ServiceHealthChecker) Launch(ctx context.Context) {
- ticker := time.NewTicker(shc.interval)
+ go shc.healthcheck(ctx, shc.unhealthyTargets, shc.unhealthyInterval)
+
+ shc.healthcheck(ctx, shc.healthyTargets, shc.interval)
+}
+
+func (shc *ServiceHealthChecker) healthcheck(ctx context.Context, targets chan target, interval time.Duration) {
+ ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
@@ -103,7 +142,23 @@ func (shc *ServiceHealthChecker) Launch(ctx context.Context) {
return
case <-ticker.C:
- for proxyName, target := range shc.targets {
+ // We collect the targets to check once for all,
+ // to avoid rechecking a target that has been moved during the health check.
+ var targetsToCheck []target
+ hasMoreTargets := true
+ for hasMoreTargets {
+ select {
+ case <-ctx.Done():
+ return
+ case target := <-targets:
+ targetsToCheck = append(targetsToCheck, target)
+ default:
+ hasMoreTargets = false
+ }
+ }
+
+ // Now we can check the targets.
+ for _, target := range targetsToCheck {
select {
case <-ctx.Done():
return
@@ -113,14 +168,14 @@ func (shc *ServiceHealthChecker) Launch(ctx context.Context) {
up := true
serverUpMetricValue := float64(1)
- if err := shc.executeHealthCheck(ctx, shc.config, target); err != nil {
+ if err := shc.executeHealthCheck(ctx, shc.config, target.targetURL); err != nil {
// The context is canceled when the dynamic configuration is refreshed.
if errors.Is(err, context.Canceled) {
return
}
log.Ctx(ctx).Warn().
- Str("targetURL", target.String()).
+ Str("targetURL", target.targetURL.String()).
Err(err).
Msg("Health check failed.")
@@ -128,17 +183,21 @@ func (shc *ServiceHealthChecker) Launch(ctx context.Context) {
serverUpMetricValue = float64(0)
}
- shc.balancer.SetStatus(ctx, proxyName, up)
+ shc.balancer.SetStatus(ctx, target.name, up)
- statusStr := runtime.StatusDown
+ var statusStr string
if up {
statusStr = runtime.StatusUp
+ shc.healthyTargets <- target
+ } else {
+ statusStr = runtime.StatusDown
+ shc.unhealthyTargets <- target
}
- shc.info.UpdateServerStatus(target.String(), statusStr)
+ shc.info.UpdateServerStatus(target.targetURL.String(), statusStr)
shc.metrics.ServiceServerUpGauge().
- With("service", shc.serviceName, "url", target.String()).
+ With("service", shc.serviceName, "url", target.targetURL.String()).
Set(serverUpMetricValue)
}
}
diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go
index a977635d1..a8df9bcdf 100644
--- a/pkg/healthcheck/healthcheck_test.go
+++ b/pkg/healthcheck/healthcheck_test.go
@@ -419,11 +419,12 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
lb := &testLoadBalancer{RWMutex: &sync.RWMutex{}}
config := &dynamic.ServerHealthCheck{
- Mode: test.mode,
- Status: test.status,
- Path: "/path",
- Interval: ptypes.Duration(500 * time.Millisecond),
- Timeout: ptypes.Duration(499 * time.Millisecond),
+ Mode: test.mode,
+ Status: test.status,
+ Path: "/path",
+ Interval: ptypes.Duration(500 * time.Millisecond),
+ UnhealthyInterval: pointer(ptypes.Duration(500 * time.Millisecond)),
+ Timeout: ptypes.Duration(499 * time.Millisecond),
}
gauge := &testhelpers.CollectingGauge{}
@@ -456,3 +457,54 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
})
}
}
+
+func TestDifferentIntervals(t *testing.T) {
+ // The context is passed to the health check and
+ // canonically canceled by the test server once all expected requests have been received.
+ ctx, cancel := context.WithCancel(context.Background())
+ t.Cleanup(cancel)
+
+ healthyServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ }))
+ healthyURL := testhelpers.MustParseURL(healthyServer.URL)
+
+ unhealthyServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ w.WriteHeader(http.StatusServiceUnavailable)
+ }))
+ unhealthyURL := testhelpers.MustParseURL(unhealthyServer.URL)
+
+ lb := &testLoadBalancer{RWMutex: &sync.RWMutex{}}
+
+ config := &dynamic.ServerHealthCheck{
+ Mode: "http",
+ Path: "/path",
+ Interval: ptypes.Duration(500 * time.Millisecond),
+ UnhealthyInterval: pointer(ptypes.Duration(50 * time.Millisecond)),
+ Timeout: ptypes.Duration(499 * time.Millisecond),
+ }
+
+ gauge := &testhelpers.CollectingGauge{}
+ serviceInfo := &runtime.ServiceInfo{}
+ hc := NewServiceHealthChecker(ctx, &MetricsMock{gauge}, config, lb, serviceInfo, http.DefaultTransport, map[string]*url.URL{"healthy": healthyURL, "unhealthy": unhealthyURL}, "foobar")
+
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+
+ go func() {
+ hc.Launch(ctx)
+ wg.Done()
+ }()
+
+ select {
+ case <-time.After(2 * time.Second):
+ break
+ case <-ctx.Done():
+ wg.Wait()
+ }
+
+ lb.Lock()
+ defer lb.Unlock()
+
+ assert.Greater(t, lb.numRemovedServers, lb.numUpsertedServers, "removed servers greater than upserted servers")
+}
diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go
index a2d89dd42..67989818c 100644
--- a/pkg/provider/kubernetes/crd/kubernetes_http.go
+++ b/pkg/provider/kubernetes/crd/kubernetes_http.go
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/rs/zerolog/log"
+ ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/logs"
"github.com/traefik/traefik/v3/pkg/provider"
@@ -373,6 +374,17 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
return nil, err
}
}
+ // If the UnhealthyInterval option is not set, we use the Interval option value,
+ // to check the unhealthy targets as often as the healthy ones.
+ if svc.HealthCheck.UnhealthyInterval == nil {
+ lb.HealthCheck.UnhealthyInterval = &lb.HealthCheck.Interval
+ } else {
+ var unhealthyInterval ptypes.Duration
+ if err := unhealthyInterval.Set(svc.HealthCheck.UnhealthyInterval.String()); err != nil {
+ return nil, err
+ }
+ lb.HealthCheck.UnhealthyInterval = &unhealthyInterval
+ }
if svc.HealthCheck.Timeout != nil {
if err := lb.HealthCheck.Timeout.Set(svc.HealthCheck.Timeout.String()); err != nil {
return nil, err
diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go
index 93b43fdfb..239d3cdae 100644
--- a/pkg/provider/kubernetes/crd/kubernetes_test.go
+++ b/pkg/provider/kubernetes/crd/kubernetes_test.go
@@ -2647,10 +2647,11 @@ func TestLoadIngressRoutes(t *testing.T) {
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
HealthCheck: &dynamic.ServerHealthCheck{
- Path: "/health",
- Timeout: 5000000000,
- Interval: 15000000000,
- FollowRedirects: pointer(true),
+ Path: "/health",
+ Timeout: 5000000000,
+ Interval: 15000000000,
+ UnhealthyInterval: pointer(ptypes.Duration(15000000000)),
+ FollowRedirects: pointer(true),
},
},
},
@@ -2712,10 +2713,11 @@ func TestLoadIngressRoutes(t *testing.T) {
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
HealthCheck: &dynamic.ServerHealthCheck{
- Path: "/health1",
- Timeout: 5000000000,
- Interval: 15000000000,
- FollowRedirects: pointer(true),
+ Path: "/health1",
+ Timeout: 5000000000,
+ Interval: 15000000000,
+ UnhealthyInterval: pointer(ptypes.Duration(15000000000)),
+ FollowRedirects: pointer(true),
},
},
},
@@ -2732,10 +2734,11 @@ func TestLoadIngressRoutes(t *testing.T) {
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
HealthCheck: &dynamic.ServerHealthCheck{
- Path: "/health2",
- Timeout: 5000000000,
- Interval: 20000000000,
- FollowRedirects: pointer(true),
+ Path: "/health2",
+ Timeout: 5000000000,
+ Interval: 20000000000,
+ UnhealthyInterval: pointer(ptypes.Duration(20000000000)),
+ FollowRedirects: pointer(true),
},
},
},
@@ -2776,10 +2779,11 @@ func TestLoadIngressRoutes(t *testing.T) {
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
HealthCheck: &dynamic.ServerHealthCheck{
- Path: "/health1",
- Timeout: 5000000000,
- Interval: 15000000000,
- FollowRedirects: pointer(true),
+ Path: "/health1",
+ Timeout: 5000000000,
+ Interval: 15000000000,
+ UnhealthyInterval: pointer(ptypes.Duration(15000000000)),
+ FollowRedirects: pointer(true),
},
},
},
diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go
index 6186207e2..5a8fa67c0 100644
--- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go
+++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go
@@ -170,9 +170,13 @@ type ServerHealthCheck struct {
Status int `json:"status,omitempty"`
// Port defines the server URL port for the health check endpoint.
Port int `json:"port,omitempty"`
- // Interval defines the frequency of the health check calls.
+ // Interval defines the frequency of the health check calls for healthy targets.
// Default: 30s
Interval *intstr.IntOrString `json:"interval,omitempty"`
+ // UnhealthyInterval defines the frequency of the health check calls for unhealthy targets.
+ // When UnhealthyInterval is not defined, it defaults to the Interval value.
+ // Default: 30s
+ UnhealthyInterval *intstr.IntOrString `json:"unhealthyInterval,omitempty"`
// Timeout defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy.
// Default: 5s
Timeout *intstr.IntOrString `json:"timeout,omitempty"`
diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go
index f975a8bfb..3e53cfae5 100644
--- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go
@@ -1280,6 +1280,11 @@ func (in *ServerHealthCheck) DeepCopyInto(out *ServerHealthCheck) {
*out = new(intstr.IntOrString)
**out = **in
}
+ if in.UnhealthyInterval != nil {
+ in, out := &in.UnhealthyInterval, &out.UnhealthyInterval
+ *out = new(intstr.IntOrString)
+ **out = **in
+ }
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(intstr.IntOrString)
diff --git a/pkg/provider/kv/kv_test.go b/pkg/provider/kv/kv_test.go
index b439f38ae..08ff286ef 100644
--- a/pkg/provider/kv/kv_test.go
+++ b/pkg/provider/kv/kv_test.go
@@ -45,6 +45,7 @@ func Test_buildConfiguration(t *testing.T) {
"traefik/http/services/Service01/loadBalancer/healthCheck/path": "foobar",
"traefik/http/services/Service01/loadBalancer/healthCheck/port": "42",
"traefik/http/services/Service01/loadBalancer/healthCheck/interval": "1s",
+ "traefik/http/services/Service01/loadBalancer/healthCheck/unhealthyinterval": "1s",
"traefik/http/services/Service01/loadBalancer/healthCheck/timeout": "1s",
"traefik/http/services/Service01/loadBalancer/healthCheck/hostname": "foobar",
"traefik/http/services/Service01/loadBalancer/healthCheck/headers/name0": "foobar",
@@ -665,14 +666,15 @@ func Test_buildConfiguration(t *testing.T) {
},
},
HealthCheck: &dynamic.ServerHealthCheck{
- Scheme: "foobar",
- Mode: "foobar",
- Path: "foobar",
- Port: 42,
- Interval: ptypes.Duration(time.Second),
- Timeout: ptypes.Duration(time.Second),
- Hostname: "foobar",
- FollowRedirects: pointer(true),
+ Scheme: "foobar",
+ Mode: "foobar",
+ Path: "foobar",
+ Port: 42,
+ Interval: ptypes.Duration(time.Second),
+ UnhealthyInterval: pointer(ptypes.Duration(time.Second)),
+ Timeout: ptypes.Duration(time.Second),
+ Hostname: "foobar",
+ FollowRedirects: pointer(true),
Headers: map[string]string{
"name0": "foobar",
"name1": "foobar",
diff --git a/webui/src/components/_commons/PanelHealthCheck.vue b/webui/src/components/_commons/PanelHealthCheck.vue
index 7ac03a7bc..918b06302 100644
--- a/webui/src/components/_commons/PanelHealthCheck.vue
+++ b/webui/src/components/_commons/PanelHealthCheck.vue
@@ -8,7 +8,7 @@
:thumb-style="appThumbStyle"
style="height:100%;"
>
-
+
+
+
+ UNHEALTHY INTERVAL
+
+
+ {{ data.unhealthyInterval }}
+
+