diff --git a/docs/content/expose/docker/advanced.md b/docs/content/expose/docker/advanced.md index 088daa10ff..81645e9e25 100644 --- a/docs/content/expose/docker/advanced.md +++ b/docs/content/expose/docker/advanced.md @@ -8,6 +8,7 @@ In this advanced guide, you'll learn how to enhance your Traefik deployment with - **Let's Encrypt** for automated certificate management - **Sticky sessions** for stateful applications - **Multi-layer routing** for hierarchical routing with a complex authentication based routing example +- **Service middlewares** for applying middleware at the service level ## Prerequisites @@ -382,6 +383,71 @@ You should see the response from the admin-backend service when authenticating a For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md). +## Service Middlewares + +Service middlewares allow you to apply middleware to a service rather than to individual routers. This means the middleware takes effect for all requests handled by the service, regardless of which router forwards the request. + +This is useful when you want to apply the same middleware (like headers, rate limiting, or authentication) to all traffic reaching a service without having to configure it on each router. + +### When to Use Service Middlewares + +Use service middlewares when: + +- Multiple routers forward traffic to the same service, and all should have the same middleware applied +- You want to ensure a middleware is always applied to a service regardless of how traffic reaches it +- You're centralizing middleware configuration at the service level for easier management + +### Add Service Middleware Labels + +Add the following labels to your whoami service in `docker-compose.yml`: + +```yaml +services: + whoami: + image: traefik/whoami + networks: + - proxy + labels: + - "traefik.enable=true" + - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" + - "traefik.http.routers.whoami.entrypoints=websecure" + - "traefik.http.routers.whoami.tls=true" + # Define the middleware + - "traefik.http.middlewares.service-headers.headers.customRequestHeaders.X-Service-Middleware=applied" + # Attach middleware at the SERVICE level (not the router level) + - "traefik.http.services.whoami.middlewares=service-headers" + - "traefik.http.services.whoami.loadbalancer.server.port=80" +``` + +!!! info "Service-Level vs Router-Level Middlewares" + + - **Router-level middleware** (`traefik.http.routers..middlewares`): Applied only when traffic matches that specific router's rule + - **Service-level middleware** (`traefik.http.services..middlewares`): Applied to all traffic reaching the service, regardless of which router forwarded it + + When both are configured, router middlewares execute first, followed by service middlewares. + +Apply the changes: + +```bash +docker compose up -d +``` + +### Test Service Middleware + +Verify the service middleware is working: + +```bash +curl -k -H "Host: whoami.docker.localhost" https://localhost/ +``` + +In the response from whoami, you should see the custom header that was added by the service middleware: + +```text +X-Service-Middleware: applied +``` + +For more details on service middlewares, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md#middlewares). + ## Conclusion In this advanced guide, you've learned how to: @@ -390,6 +456,7 @@ In this advanced guide, you've learned how to: - Automate certificate management with Let's Encrypt - Implement sticky sessions for stateful applications - Setup multi-layer routing for authentication-based routing +- Apply middlewares at the service level for centralized middleware management These advanced capabilities allow you to build production-ready Traefik deployments with Docker. Each of these can be further customized to meet your specific requirements. diff --git a/docs/content/expose/kubernetes/advanced.md b/docs/content/expose/kubernetes/advanced.md index 64f5e78b71..1a5e263cfc 100644 --- a/docs/content/expose/kubernetes/advanced.md +++ b/docs/content/expose/kubernetes/advanced.md @@ -9,6 +9,7 @@ In this advanced guide, you'll learn how to enhance your Traefik deployment with - **cert-manager** for automated certificate management (Gateway API) - **Sticky sessions** for stateful applications - **Multi-layer routing** for hierarchical routing with complex authentication scenarios (IngressRoute only) +- **Service middlewares** for applying middleware at the service level ## Prerequisites @@ -806,6 +807,182 @@ spec: For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md). +## Service Middlewares + +Service middlewares allow you to apply middleware to a service rather than to individual routers. This means the middleware takes effect for all requests handled by the service, regardless of which router forwards the request. + +This is useful when you want to apply the same middleware (like headers, rate limiting, or authentication) to all traffic reaching a service without having to configure it on each router. + +### When to Use Service Middlewares + +Use service middlewares when: + +- Multiple routers forward traffic to the same service, and all should have the same middleware applied +- You want to ensure a middleware is always applied to a service regardless of how traffic reaches it +- You're centralizing middleware configuration at the service level for easier management + +!!! info "Service-Level vs Router-Level Middlewares" + + - **Router-level middleware**: Applied only when traffic matches that specific router's rule + - **Service-level middleware**: Applied to all traffic reaching the service, regardless of which router forwarded it + + When both are configured, router middlewares execute first, followed by service middlewares. + +### Using IngressRoute with Service Middlewares + +With IngressRoute, you can attach middlewares directly to a service reference within a route: + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: service-headers + namespace: default +spec: + headers: + customRequestHeaders: + X-Service-Middleware: "applied" +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: whoami + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`whoami.docker.localhost`) + kind: Rule + services: + - name: whoami + port: 80 + middlewares: + - name: service-headers + tls: {} +``` + +Save this as `service-middleware-ingressroute.yaml` and apply it: + +```bash +kubectl apply -f service-middleware-ingressroute.yaml +``` + +### Using Gateway API with Backend Filters + +Gateway API supports applying filters directly to individual backends through the `backendRefs[].filters` field. This enables backend-level request modifications. + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: service-headers + namespace: default +spec: + headers: + customRequestHeaders: + X-Service-Middleware: "applied" +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: whoami + namespace: default +spec: + parentRefs: + - name: traefik-gateway + sectionName: websecure + hostnames: + - "whoami.docker.localhost" + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: whoami + port: 80 + filters: + - type: ExtensionRef + extensionRef: + group: traefik.io + kind: Middleware + name: service-headers +``` + +Gateway API also supports the native `RequestHeaderModifier` filter type for simpler header modifications: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: whoami + namespace: default +spec: + parentRefs: + - name: traefik-gateway + sectionName: websecure + hostnames: + - "whoami.docker.localhost" + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: whoami + port: 80 + filters: + - type: RequestHeaderModifier + requestHeaderModifier: + add: + - name: X-Backend-Header + value: "gateway-api-filter" +``` + +Save and apply: + +```bash +kubectl apply -f service-middleware-gateway.yaml +``` + +### Using Kubernetes Ingress with Service Annotation + +For standard Kubernetes Ingress, you can apply middlewares to a service using annotations: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: whoami + namespace: default + annotations: + traefik.ingress.kubernetes.io/service.middlewares: default-service-headers@kubernetescrd +spec: + selector: + app: whoami + ports: + - port: 80 +``` + +The annotation value follows the format `-@kubernetescrd`. + +### Test Service Middleware + +Verify the service middleware is working: + +```bash +curl -k -H "Host: whoami.docker.localhost" https://localhost/ +``` + +In the response from whoami, you should see the custom header that was added by the service middleware: + +```text +X-Service-Middleware: applied +``` + +For more details on service middlewares, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md#middlewares). + ## Conclusion In this advanced guide, you've learned how to: @@ -814,6 +991,7 @@ In this advanced guide, you've learned how to: - Automate certificate management with Let's Encrypt (IngressRoute) and cert-manager (Gateway API) - Implement sticky sessions for stateful applications - Setup multi-layer routing for authentication-based routing (IngressRoute only) +- Apply middlewares at the service level for centralized middleware management These advanced capabilities allow you to build production-ready Traefik deployments with Kubernetes. Each of these can be further customized to meet your specific requirements. diff --git a/docs/content/expose/swarm/advanced.md b/docs/content/expose/swarm/advanced.md index b2fdee7255..d39f2b85ff 100644 --- a/docs/content/expose/swarm/advanced.md +++ b/docs/content/expose/swarm/advanced.md @@ -8,6 +8,7 @@ In this advanced guide, you'll learn how to enhance your Traefik deployment with - **Let's Encrypt** for automated certificate management - **Sticky sessions** for stateful applications - **Multi-layer routing** for complex authentication scenarios +- **Service middlewares** for applying middleware at the service level ## Prerequisites @@ -382,6 +383,73 @@ You should see the response from the admin-backend service when authenticating a For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md). +## Service Middlewares + +Service middlewares allow you to apply middleware to a service rather than to individual routers. This means the middleware takes effect for all requests handled by the service, regardless of which router forwards the request. + +This is useful when you want to apply the same middleware (like headers, rate limiting, or authentication) to all traffic reaching a service without having to configure it on each router. + +### When to Use Service Middlewares + +Use service middlewares when: + +- Multiple routers forward traffic to the same service, and all should have the same middleware applied +- You want to ensure a middleware is always applied to a service regardless of how traffic reaches it +- You're centralizing middleware configuration at the service level for easier management + +### Add Service Middleware Labels + +Add the following labels to your whoami service deployment section in `docker-compose.yml`: + +```yaml +services: + whoami: + image: traefik/whoami + networks: + - traefik_proxy + deploy: + replicas: 2 + labels: + - "traefik.enable=true" + - "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)" + - "traefik.http.routers.whoami.entrypoints=websecure" + - "traefik.http.routers.whoami.tls=true" + # Define the middleware + - "traefik.http.middlewares.service-headers.headers.customRequestHeaders.X-Service-Middleware=applied" + # Attach middleware at the SERVICE level (not the router level) + - "traefik.http.services.whoami.middlewares=service-headers" + - "traefik.http.services.whoami.loadbalancer.server.port=80" +``` + +!!! info "Service-Level vs Router-Level Middlewares" + + - **Router-level middleware** (`traefik.http.routers..middlewares`): Applied only when traffic matches that specific router's rule + - **Service-level middleware** (`traefik.http.services..middlewares`): Applied to all traffic reaching the service, regardless of which router forwarded it + + When both are configured, router middlewares execute first, followed by service middlewares. + +Deploy the stack: + +```bash +docker stack deploy -c docker-compose.yml traefik +``` + +### Test Service Middleware + +Verify the service middleware is working: + +```bash +curl -k -H "Host: whoami.swarm.localhost" https://localhost/ +``` + +In the response from whoami, you should see the custom header that was added by the service middleware: + +```text +X-Service-Middleware: applied +``` + +For more details on service middlewares, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md#middlewares). + ## Conclusion In this advanced guide, you've learned how to: @@ -390,6 +458,7 @@ In this advanced guide, you've learned how to: - Automate certificate management with Let's Encrypt - Implement sticky sessions for stateful applications - Setup multi-layer routing for authentication-based routing +- Apply middlewares at the service level for centralized middleware management These advanced capabilities allow you to build production-ready Traefik deployments with Docker Swarm. Each of these can be further customized to meet your specific requirements. 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 5685c3198e..f4a99f423e 100644 --- a/docs/content/reference/routing-configuration/http/load-balancing/service.md +++ b/docs/content/reference/routing-configuration/http/load-balancing/service.md @@ -483,6 +483,67 @@ Below are the available options for the passive health check mechanism: | `failureWindow` | Defines the time window during which the failed attempts must occur for the server to be marked as unhealthy. It also defines for how long the server will be considered unhealthy. | 10s | No | | `maxFailedAttempts` | Defines the number of consecutive failed attempts allowed within the failure window before marking the server as unhealthy. | 1 | No | +### Middlewares + +You can attach a list of [middlewares](../middlewares/overview.md) to each HTTP service. +The middlewares will take effect for all requests handled by the service, regardless of which router forwards the request. + +!!! info "Middlewares Execution Order" + + When both a router and a service have middlewares configured, the router middlewares are applied first, followed by the service middlewares. + This means the request passes through router middlewares before reaching service middlewares. + +!!! info "Supported Providers" + + Service-level middlewares can be configured with the [File](../../../install-configuration/providers/others/file.md), [Docker](../../other-providers/docker.md), [Swarm](../../other-providers/docker.md), [Kubernetes IngressRoute](../../kubernetes/crd/http/ingressroute.md), [Kubernetes Ingress](../../kubernetes/ingress.md), and [Kubernetes Gateway API](../../kubernetes/gateway-api.md) providers. + +??? example "Attaching Middlewares to a Service -- Using the [File Provider](../../../install-configuration/providers/others/file.md)" + + ```yaml tab="Structured (YAML)" + ## Dynamic configuration + http: + services: + my-service: + middlewares: + - add-header + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" + + middlewares: + add-header: + headers: + customRequestHeaders: + X-Custom-Header: "service-middleware" + ``` + + ```toml tab="Structured (TOML)" + ## Dynamic configuration + [http.services] + [http.services.my-service] + middlewares = ["add-header"] + [http.services.my-service.loadBalancer] + [[http.services.my-service.loadBalancer.servers]] + url = "http://127.0.0.1:8080" + + [http.middlewares] + [http.middlewares.add-header.headers] + [http.middlewares.add-header.headers.customRequestHeaders] + X-Custom-Header = "service-middleware" + ``` + +??? example "Attaching Middlewares to a Service -- Using [Docker Labels](../../other-providers/docker.md)" + + ```yaml + labels: + # Define the middleware + - "traefik.http.middlewares.add-header.headers.customRequestHeaders.X-Custom-Header=service-middleware" + # Attach middleware to the service (at service level, not loadBalancer level) + - "traefik.http.services.my-service.middlewares=add-header" + # Configure the service + - "traefik.http.services.my-service.loadbalancer.server.port=8080" + ``` + ## Advanced Service Types Advanced service types allow you to compose multiple services together for weighted distribution, consistent hashing, mirroring, or failover scenarios. diff --git a/docs/content/reference/routing-configuration/http/middlewares/overview.md b/docs/content/reference/routing-configuration/http/middlewares/overview.md index 1c8ac86b71..cc9af6d135 100644 --- a/docs/content/reference/routing-configuration/http/middlewares/overview.md +++ b/docs/content/reference/routing-configuration/http/middlewares/overview.md @@ -5,7 +5,14 @@ description: "There are several available middleware in Traefik Proxy used to mo # HTTP Middleware Overview -Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service (or before the answer from the services are sent to the clients). +Attached to [routers](../routing/router.md) or [services](../load-balancing/service.md), pieces of middleware are a means of tweaking the requests before they are sent to your backend servers (or before the answer is sent to the clients). + +Middlewares can be attached at two levels: + +- **Router-level:** Applied to all requests matching the router's rule, before forwarding to the service. +- **Service-level:** Applied to all requests handled by the service, regardless of which router forwards the request. See [service middlewares](../load-balancing/service.md#middlewares). + +When both are configured, router middlewares execute first, followed by service middlewares. There are several available middlewares in Traefik, some can modify the request, the headers, some are in charge of redirections, some add authentication, and so on. diff --git a/docs/content/reference/routing-configuration/kubernetes/crd/http/service.md b/docs/content/reference/routing-configuration/kubernetes/crd/http/service.md index 0d701d9a3d..6b292151de 100644 --- a/docs/content/reference/routing-configuration/kubernetes/crd/http/service.md +++ b/docs/content/reference/routing-configuration/kubernetes/crd/http/service.md @@ -48,6 +48,10 @@ spec: name: cookie secure: true strategy: wrr + # Attach middlewares to this service + middlewares: + - name: my-middleware + namespace: apps ``` ```yaml tab="TraefikService" @@ -80,36 +84,39 @@ spec: ## Configuration Options -| Field | Description | Default | Required | -|:---------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------| -| `kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
**TraefikService**: Traefik Service.
More information [here](#externalname-service). | "Service" | No | -| `name` | Service name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes | -| `namespace` | Service namespace.
Can be empty if the service belongs to the same namespace as the IngressRoute.
More information [here](#externalname-service). | | No | -| `port` | Service port (number or port name).
Evaluated only if the kind 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 is **Service**. | 100ms | No | -| `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 | -| `serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No | -| `passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No | -| `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 | -| `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 | -| `healthCheck.path` | Server URL path for the health check endpoint.
The configured path must be relative URL.
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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `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 | -| `strategy` | Strategy defines the load balancing strategy between the servers.
Supported values are: wrr (Weighed round-robin), p2c (Power of two choices), hrw (Highest Random Weight), and leasttime (Least-Time).
Evaluated only if the kind is **Service**. | "RoundRobin" | No | -| `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 | -| `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 | +| Field | Description | Default | Required | +|:---------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------| +| `kind` | Kind of the service targeted.
Two values allowed:
- **Service**: Kubernetes Service
**TraefikService**: Traefik Service.
More information [here](#externalname-service). | "Service" | No | +| `name` | Service name.
The character `@` is not authorized.
More information [here](#middleware). | | Yes | +| `namespace` | Service namespace.
Can be empty if the service belongs to the same namespace as the IngressRoute.
More information [here](#externalname-service). | | No | +| `port` | Service port (number or port name).
Evaluated only if the kind 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 is **Service**. | 100ms | No | +| `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 | +| `serversTransport` | Name of ServersTransport resource to use to configure the transport between Traefik and your servers.
Evaluated only if the kind is **Service**. | "" | No | +| `passHostHeader` | Forward client Host header to server.
Evaluated only if the kind is **Service**. | true | No | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `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 | +| `strategy` | Strategy defines the load balancing strategy between the servers.
Supported values are: wrr (Weighed round-robin), p2c (Power of two choices), hrw (Highest Random Weight), and leasttime (Least-Time).
Evaluated only if the kind is **Service**. | "RoundRobin" | No | +| `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 | +| `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 | +| `middlewares` | List of references to [Middleware](./middleware.md) resources to apply to the service.
The middlewares will take effect for all requests handled by the service, regardless of which router forwards the request.
Evaluated only if the kind is **Service**.
More information [here](#middlewares). | | No | +| `middlewares[n].name` | Middleware name.
The character `@` is not authorized. | | Yes | +| `middlewares[n].namespace` | Middleware namespace.
Can be empty if the middleware belongs to the same namespace as the IngressRoute. | | No | ### ExternalName Service @@ -419,6 +426,61 @@ spec: ... ``` +### Middlewares + +You can attach a list of [middlewares](./middleware.md) to each service. +The middlewares will take effect for all requests handled by the service, regardless of which router forwards the request. + +For more information on service-level middlewares, see [service middlewares](../../../http/load-balancing/service.md#middlewares). + +??? example "Attaching Middlewares to a Service" + + ```yaml tab="IngressRoute" + apiVersion: traefik.io/v1alpha1 + kind: IngressRoute + metadata: + name: test-name + namespace: default + spec: + entryPoints: + - web + routes: + - kind: Rule + match: Host(`example.com`) + services: + - kind: Service + name: whoami + port: 80 + middlewares: + - name: add-header + namespace: default + ``` + + ```yaml tab="Middleware" + apiVersion: traefik.io/v1alpha1 + kind: Middleware + metadata: + name: add-header + namespace: default + spec: + headers: + customRequestHeaders: + X-Custom-Header: "service-middleware" + ``` + + ```yaml tab="Whoami Service" + apiVersion: v1 + kind: Service + metadata: + name: whoami + namespace: default + spec: + ports: + - port: 80 + selector: + app: whoami + ``` + ### Configuring Backend Protocol There are 3 ways to configure the backend protocol for communication between Traefik and your pods: diff --git a/docs/content/reference/routing-configuration/kubernetes/gateway-api.md b/docs/content/reference/routing-configuration/kubernetes/gateway-api.md index 784a834247..19ab8a10ee 100644 --- a/docs/content/reference/routing-configuration/kubernetes/gateway-api.md +++ b/docs/content/reference/routing-configuration/kubernetes/gateway-api.md @@ -429,6 +429,106 @@ Once everything is deployed, sending a `GET` request should return the following X-Real-Ip: 10.42.2.1 ``` +#### Backend-Level Filters + +In addition to route-level filters, the Gateway API also supports applying filters directly to individual backends through the `backendRefs[].filters` field. +This allows request modifications to be applied to specific backends, enabling the `HTTPRouteBackendRequestHeaderModification` extended feature. + +!!! info "Supported Filter Types" + + Backend-level filters support the same filter types as route-level filters: + + - `RequestHeaderModifier`: Add, set, or remove HTTP request headers before forwarding to the backend. + - `ResponseHeaderModifier`: Add, set, or remove HTTP response headers. + - `RequestRedirect`: Redirect the request to a different URL. + - `URLRewrite`: Rewrite the request URL path and/or hostname. + - `ExtensionRef`: Reference a Traefik [Middleware](../kubernetes/crd/http/middleware.md) resource. + +!!! info "Middlewares Execution Order" + + When both route-level and backend-level filters are configured, route-level filters are applied first, followed by backend-level filters. + +For more information on service-level middlewares, see [service middlewares](../http/load-balancing/service.md#middlewares). + +??? example "Using RequestHeaderModifier on a Backend" + + ```yaml tab="HTTPRoute" + --- + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: whoami-http + namespace: default + spec: + parentRefs: + - name: traefik + sectionName: http + kind: Gateway + + hostnames: + - whoami.localhost + + rules: + - matches: + - path: + type: PathPrefix + value: / + + backendRefs: + - name: whoami + namespace: default + port: 80 + filters: + - type: RequestHeaderModifier + requestHeaderModifier: + set: + - name: X-Backend-Header + value: "backend-filter" + ``` + +??? example "Using ExtensionRef (Traefik Middleware) on a Backend" + + ```yaml tab="HTTPRoute" + --- + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: whoami-http + namespace: default + spec: + parentRefs: + - name: traefik + sectionName: http + kind: Gateway + + hostnames: + - whoami.localhost + + rules: + - backendRefs: + - name: whoami + namespace: default + port: 80 + filters: + - type: ExtensionRef + extensionRef: + group: traefik.io + kind: Middleware + name: add-prefix + ``` + + ```yaml tab="AddPrefix Middleware" + --- + apiVersion: traefik.io/v1alpha1 + kind: Middleware + metadata: + name: add-prefix + namespace: default + spec: + addPrefix: + prefix: /api + ``` + ### GRPC The `GRPCRoute` is an extended resource in the Gateway API specification, designed to define how GRPC traffic should be routed within a Kubernetes cluster. diff --git a/docs/content/reference/routing-configuration/kubernetes/ingress.md b/docs/content/reference/routing-configuration/kubernetes/ingress.md index dd7c4f22c6..001ba03718 100644 --- a/docs/content/reference/routing-configuration/kubernetes/ingress.md +++ b/docs/content/reference/routing-configuration/kubernetes/ingress.md @@ -85,6 +85,14 @@ spec: | `traefik.ingress.kubernetes.io/service.sticky.cookie.maxage` | Sets the Max-Age attribute (in seconds) on the sticky session cookie.
See [sticky sessions](../kubernetes/crd/http/traefikservice.md#stickiness-on-multiple-levels) for more information. | `42` | | `traefik.ingress.kubernetes.io/service.sticky.cookie.path` | Sets the Path attribute on the sticky session cookie, defining the path that must exist in the requested URL.
See [sticky sessions](../kubernetes/crd/http/traefikservice.md#stickiness-on-multiple-levels) for more information. | `/foobar` | +??? info "`traefik.ingress.kubernetes.io/service.middlewares`" + + See [service middlewares](../http/load-balancing/service.md#middlewares) for more information. + + ```yaml + traefik.ingress.kubernetes.io/service.middlewares: auth@file,prefix@kubernetescrd + ``` + ## TLS ### Enabling TLS via HTTP Options on Entrypoint