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 b9dfbdade..04bb76c26 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -2963,6 +2963,526 @@ spec: spec: description: TraefikServiceSpec defines the desired state of a TraefikService. properties: + failover: + description: Failover defines the Failover service configuration. + properties: + errors: + description: Errors defines which errors should trigger the use + of the fallback service. + properties: + maxRequestBodyBytes: + description: |- + MaxRequestBodyBytes defines the maximum size allowed for the body of the request. + Default value is -1, which means unlimited size. + format: int64 + type: integer + status: + description: Status defines the list of status code ranges + for which the fallback service should be used. + items: + type: string + type: array + type: object + fallback: + description: Fallback defines the fallback service to use when + the main service returns an error. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + service: + description: Service defines the main service to use. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + required: + - errors + - fallback + - service + type: object highestRandomWeight: description: HighestRandomWeight defines the highest random weight service configuration. diff --git a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml index 11f302e71..09d2a96d2 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml @@ -44,6 +44,526 @@ spec: spec: description: TraefikServiceSpec defines the desired state of a TraefikService. properties: + failover: + description: Failover defines the Failover service configuration. + properties: + errors: + description: Errors defines which errors should trigger the use + of the fallback service. + properties: + maxRequestBodyBytes: + description: |- + MaxRequestBodyBytes defines the maximum size allowed for the body of the request. + Default value is -1, which means unlimited size. + format: int64 + type: integer + status: + description: Status defines the list of status code ranges + for which the fallback service should be used. + items: + type: string + type: array + type: object + fallback: + description: Fallback defines the fallback service to use when + the main service returns an error. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + service: + description: Service defines the main service to use. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + required: + - errors + - fallback + - service + type: object highestRandomWeight: description: HighestRandomWeight defines the highest random weight service configuration. 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 2512b98a3..c1d9715fd 100644 --- a/docs/content/reference/routing-configuration/http/load-balancing/service.md +++ b/docs/content/reference/routing-configuration/http/load-balancing/service.md @@ -898,8 +898,8 @@ Failover can be triggered in two ways: !!! info "Relation to HealthCheck" The failover service relies on the HealthCheck system to get notified when its main service becomes unreachable, which means HealthCheck needs to be enabled and functional on the main service. However, HealthCheck does not need to be enabled on the failover service itself for it to be functional. It is only required in order to propagate upwards the information when the failover itself becomes down (i.e. both its main and its fallback are down too). -!!! info "Supported Provider" - This service type can currently only be defined with the [File](../../../install-configuration/providers/others/file.md) provider. +!!! info "Supported Providers" + This service type can be defined with the [File](../../../install-configuration/providers/others/file.md) and [Kubernetes CRD](../../../install-configuration/providers/kubernetes/kubernetes-crd.md) providers. #### HealthCheck @@ -909,7 +909,7 @@ HealthCheck enables automatic self-healthcheck for this service, i.e. if the mai If HealthCheck is enabled for a given service and any of its descendants does not have it enabled, the creation of the service will fail. - HealthCheck on a Failover service can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md). + HealthCheck on a Failover service can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md). ```yaml tab="Structured (YAML)" ## Routing configuration 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 1d569aa54..379148386 100644 --- a/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md +++ b/docs/content/reference/routing-configuration/kubernetes/crd/http/traefikservice.md @@ -3,13 +3,14 @@ title: "Traefik Kubernetes Services Documentation" description: "Learn how to configure routing and load balancing in Traefik Proxy to reach Services, which handle incoming requests. Read the technical documentation." --- -A `TraefikService` is a custom resource that sits on top of the Kubernetes Services. It enables advanced load-balancing features such as a [Weighted Round Robin](#weighted-round-robin) load balancing, a [Highest Random Weight](#highest-random-weight) load balancing, or a [Mirroring](#mirroring) between your Kubernetes Services. +A `TraefikService` is a custom resource that sits on top of the Kubernetes Services. It enables advanced load-balancing features such as a [Weighted Round Robin](#weighted-round-robin) load balancing, a [Highest Random Weight](#highest-random-weight) load balancing, a [Mirroring](#mirroring), or a [Failover](#failover) between your Kubernetes Services. Services configure how to reach the actual endpoints that will eventually handle incoming requests. In Traefik, the target service can be either a standard [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/)—which exposes a pod—or a TraefikService. The latter allows you to combine advanced load-balancing options like: - [Weighted Round Robin load balancing](#weighted-round-robin). - [Highest Random Weight load balancing](#highest-random-weight). -- [Mirroring](#mirroring). +- [Mirroring](#mirroring). +- [Failover](#failover). ## Weighted Round Robin @@ -507,3 +508,143 @@ The mirrorerd service dedicated option are described below. | Field | Description | Default | Required | |:--------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------| | `mirrors[m].percent` | Traffic percentage to route to the service. | 0 | No | + +## Failover + +The failover service forwards all requests to a fallback service when the main service responds with specific HTTP status codes defined in the `errors` configuration. + +!!! Failover on Heathcheck Status + + HealthCheck on a Failover service can be defined currently only with the [File provider](../../../../install-configuration/providers/others/file.md). + +### Configuration Examples + +```yaml tab="IngressRoute" +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test-name + namespace: apps + +spec: + entryPoints: + - websecure + routes: + - match: Host(`example.com`) && PathPrefix(`/foo`) + kind: Rule + services: + # Set a Failover TraefikService + - name: failover1 + namespace: apps + kind: TraefikService +``` + +```yaml tab="Failover from Kubernetes Services" +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: apps + +spec: + failover: + service: + name: svc1 + port: 80 + fallback: + name: svc2 + port: 80 + errors: + status: + - "500-503" + - "429" +``` + +```yaml tab="Failover from TraefikService (WRR)" +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: apps + +spec: + failover: + service: + name: wrr1 + kind: TraefikService + fallback: + name: wrr2 + kind: TraefikService + errors: + status: + - "500-503" +``` + +```yaml tab="Failover with maxRequestBodyBytes" +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: apps + +spec: + failover: + service: + name: svc1 + port: 80 + fallback: + name: svc2 + port: 80 + errors: + status: + - "500-503" + - "429" + maxRequestBodyBytes: 1048576 +``` + +```yaml tab="Kubernetes Services" +apiVersion: v1 +kind: Service +metadata: + name: svc1 + namespace: apps + +spec: + ports: + - name: http + port: 80 + selector: + app: traefiklabs + task: app1 +--- +apiVersion: v1 +kind: Service +metadata: + name: svc2 + namespace: apps + +spec: + ports: + - name: http + port: 80 + selector: + app: traefiklabs + task: app2 +``` + +### Configuration Options + +#### Main Service and Fallback Options + +The `service` and `fallback` fields each define a target service using the same options as a [`Service`](./service.md). + +The exhaustive list of the service options is described in the [`Service`](./service.md#configuration-options) documentation. + +#### Failover Dedicated Options + +| Field | Description | Default | Required | +|:---------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|:---------| +| `service` | Main service to forward requests to. Provides the same options as a [`Service`](./service.md). | | Yes | +| `fallback` | Fallback service to use when the main service returns matching error status codes. Provides the same options as a [`Service`](./service.md). | | Yes | +| `errors.status` | List of HTTP status code ranges for which the fallback service should be used.
Each entry can be a single code (e.g. `"429"`) or a range (e.g. `"500-503"`). | | No | +| `errors.`
`maxRequestBodyBytes`
| Maximum size allowed for the body of the request.
If the body is larger, the request is not replayed to the fallback service.
-1 means unlimited size. | -1 | No | diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index db363bd63..d31b9a2c6 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -1704,7 +1704,7 @@ A failover service job is to forward all requests to a fallback service when the !!! info "Supported Providers" - This strategy can currently only be defined with the [File](../../providers/file.md) provider. + This strategy can be defined with the [File](../../providers/file.md) and [Kubernetes CRD](../../providers/kubernetes-crd.md) providers. ```yaml tab="YAML" ## Dynamic configuration diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 1ff183ffe..651ce8e76 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -2964,6 +2964,526 @@ spec: spec: description: TraefikServiceSpec defines the desired state of a TraefikService. properties: + failover: + description: Failover defines the Failover service configuration. + properties: + errors: + description: Errors defines which errors should trigger the use + of the fallback service. + properties: + maxRequestBodyBytes: + description: |- + MaxRequestBodyBytes defines the maximum size allowed for the body of the request. + Default value is -1, which means unlimited size. + format: int64 + type: integer + status: + description: Status defines the list of status code ranges + for which the fallback service should be used. + items: + type: string + type: array + type: object + fallback: + description: Fallback defines the fallback service to use when + the main service returns an error. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + service: + description: Service defines the main service to use. + properties: + healthCheck: + description: Healthcheck defines health checks for ExternalName + services. + properties: + followRedirects: + description: |- + FollowRedirects defines whether redirects should be followed during the health check calls. + Default: true + type: boolean + headers: + additionalProperties: + type: string + description: Headers defines custom headers to be sent + to the health check endpoint. + type: object + hostname: + description: Hostname defines the value of hostname in + the Host header of the health check request. + type: string + interval: + anyOf: + - type: integer + - type: string + description: |- + Interval defines the frequency of the health check calls for healthy targets. + Default: 30s + x-kubernetes-int-or-string: true + method: + description: Method defines the healthcheck method. + type: string + mode: + description: |- + Mode defines the health check mode. + If defined to grpc, will use the gRPC health check protocol to probe the server. + Default: http + type: string + path: + description: Path defines the server URL path for the + health check endpoint. + type: string + port: + description: Port defines the server URL port for the + health check endpoint. + type: integer + scheme: + description: Scheme replaces the server URL scheme for + the health check endpoint. + type: string + status: + description: Status defines the expected HTTP status code + of the response to the health check request. + type: integer + timeout: + anyOf: + - type: integer + - type: string + description: |- + 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. + enum: + - Service + - TraefikService + type: string + middlewares: + description: Middlewares defines the list of references to + Middleware resources to apply to the service. + items: + description: MiddlewareRef is a reference to a Middleware + resource. + properties: + name: + description: Name defines the name of the referenced + Middleware resource. + type: string + namespace: + description: Namespace defines the namespace of the + referenced Middleware resource. + type: string + required: + - name + type: object + type: array + name: + description: |- + Name defines the name of the referenced Kubernetes Service or TraefikService. + The differentiation between the two is specified in the Kind field. + type: string + namespace: + description: Namespace defines the namespace of the referenced + Kubernetes Service or TraefikService. + type: string + nativeLB: + description: |- + NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean + nodePortLB: + description: |- + NodePortLB controls, when creating the load-balancer, + whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. + It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. + By default, NodePortLB is false. + type: boolean + passHostHeader: + description: |- + PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. + By default, passHostHeader is true. + type: boolean + passiveHealthCheck: + description: PassiveHealthCheck defines passive health checks + for ExternalName services. + properties: + failureWindow: + anyOf: + - type: integer + - type: string + description: 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. + x-kubernetes-int-or-string: true + maxFailedAttempts: + description: MaxFailedAttempts is the number of consecutive + failed attempts allowed within the failure window before + marking the server as unhealthy. + type: integer + type: object + port: + anyOf: + - type: integer + - type: string + description: |- + Port defines the port of a Kubernetes Service. + This can be a reference to a named port. + x-kubernetes-int-or-string: true + responseForwarding: + description: ResponseForwarding defines how Traefik forwards + the response from the upstream Kubernetes Service to the + client. + properties: + flushInterval: + description: |- + FlushInterval defines the 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 ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + Default: 100ms + type: string + type: object + scheme: + description: |- + Scheme defines the scheme to use for the request to the upstream Kubernetes Service. + It defaults to https when Kubernetes Service port is 443, http otherwise. + type: string + serversTransport: + description: |- + ServersTransport defines the name of ServersTransport resource to use. + It allows to configure the transport between Traefik and your servers. + Can only be used on a Kubernetes Service. + type: string + sticky: + description: |- + Sticky defines the sticky sessions configuration. + More info: https://doc.traefik.io/traefik/v3.6/reference/routing-configuration/http/load-balancing/service/#sticky-sessions + properties: + cookie: + description: Cookie defines the sticky cookie configuration. + properties: + domain: + description: |- + Domain defines the host to which the cookie will be sent. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + type: string + httpOnly: + description: HTTPOnly defines whether the cookie can + be accessed by client-side APIs, such as JavaScript. + type: boolean + maxAge: + description: |- + MaxAge defines the number of seconds until the cookie expires. + When set to a negative number, the cookie expires immediately. + When set to zero, the cookie never expires. + type: integer + name: + description: Name defines the Cookie name. + type: string + path: + description: |- + Path defines the path that must exist in the requested URL for the browser to send the Cookie header. + When not provided the cookie will be sent on every request to the domain. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value + type: string + sameSite: + description: |- + SameSite defines the same site policy. + More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite + enum: + - none + - lax + - strict + type: string + secure: + description: Secure defines whether the cookie can + only be transmitted over an encrypted connection + (i.e. HTTPS). + type: boolean + type: object + type: object + strategy: + description: |- + 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). + RoundRobin value is deprecated and supported for backward compatibility. + enum: + - wrr + - p2c + - hrw + - leasttime + - RoundRobin + type: string + weight: + description: |- + Weight defines the weight and should only be specified when Name references a TraefikService object + (and to be precise, one that embeds a Weighted Round Robin). + minimum: 0 + type: integer + required: + - name + type: object + required: + - errors + - fallback + - service + type: object highestRandomWeight: description: HighestRandomWeight defines the highest random weight service configuration. diff --git a/pkg/provider/kubernetes/crd/fixtures/with_failover.yml b/pkg/provider/kubernetes/crd/fixtures/with_failover.yml new file mode 100644 index 000000000..572ea9925 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_failover.yml @@ -0,0 +1,106 @@ +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami4-abc + namespace: default + labels: + kubernetes.io/service-name: whoami4 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami4 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami4 + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami5-abc + namespace: default + labels: + kubernetes.io/service-name: whoami5 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami5 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami5 + +--- +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: default + +spec: + failover: + service: + name: whoami5 + kind: Service + port: 8080 + fallback: + name: whoami4 + kind: Service + port: 8080 + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: Host(`foo.com`) && PathPrefix(`/foo`) + kind: Rule + priority: 12 + services: + - name: failover1 + kind: TraefikService diff --git a/pkg/provider/kubernetes/crd/fixtures/with_failover2.yml b/pkg/provider/kubernetes/crd/fixtures/with_failover2.yml new file mode 100644 index 000000000..1b97d5f84 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_failover2.yml @@ -0,0 +1,132 @@ +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami4-abc + namespace: default + labels: + kubernetes.io/service-name: whoami4 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami4 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami4 + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami5-abc + namespace: default + labels: + kubernetes.io/service-name: whoami5 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami5 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami5 + +--- +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: wrr1 + namespace: default + +spec: + weighted: + services: + - name: whoami4 + weight: 1 + port: 8080 + +--- +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: wrr2 + namespace: default + +spec: + weighted: + services: + - name: whoami5 + weight: 1 + port: 8080 + +--- +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: default + +spec: + failover: + service: + name: wrr1 + kind: TraefikService + fallback: + name: wrr2 + kind: TraefikService + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: Host(`foo.com`) && PathPrefix(`/foo`) + kind: Rule + priority: 12 + services: + - name: failover1 + kind: TraefikService diff --git a/pkg/provider/kubernetes/crd/fixtures/with_failover_errors.yml b/pkg/provider/kubernetes/crd/fixtures/with_failover_errors.yml new file mode 100644 index 000000000..1ee7196c9 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_failover_errors.yml @@ -0,0 +1,111 @@ +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami4-abc + namespace: default + labels: + kubernetes.io/service-name: whoami4 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.1 + - 10.10.0.2 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami4 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami4 + +--- +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: whoami5-abc + namespace: default + labels: + kubernetes.io/service-name: whoami5 + +addressType: IPv4 +ports: + - name: web + port: 8080 +endpoints: + - addresses: + - 10.10.0.3 + - 10.10.0.4 + conditions: + ready: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami5 + namespace: default + +spec: + ports: + - name: web + port: 8080 + selector: + app: traefiklabs + task: whoami5 + +--- +apiVersion: traefik.io/v1alpha1 +kind: TraefikService +metadata: + name: failover1 + namespace: default + +spec: + failover: + service: + name: whoami5 + kind: Service + port: 8080 + fallback: + name: whoami4 + kind: Service + port: 8080 + errors: + status: + - "500-504" + - "404" + maxRequestBodyBytes: 1048576 + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - web + + routes: + - match: Host(`foo.com`) && PathPrefix(`/foo`) + kind: Rule + priority: 12 + services: + - name: failover1 + kind: TraefikService diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failover.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failover.go new file mode 100644 index 000000000..1e2b5288a --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failover.go @@ -0,0 +1,65 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// FailoverApplyConfiguration represents a declarative configuration of the Failover type for use +// with apply. +type FailoverApplyConfiguration struct { + Service *LoadBalancerSpecApplyConfiguration `json:"service,omitempty"` + Fallback *LoadBalancerSpecApplyConfiguration `json:"fallback,omitempty"` + Errors *FailoverErrorApplyConfiguration `json:"errors,omitempty"` +} + +// FailoverApplyConfiguration constructs a declarative configuration of the Failover type for use with +// apply. +func Failover() *FailoverApplyConfiguration { + return &FailoverApplyConfiguration{} +} + +// WithService sets the Service field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Service field is set to the value of the last call. +func (b *FailoverApplyConfiguration) WithService(value *LoadBalancerSpecApplyConfiguration) *FailoverApplyConfiguration { + b.Service = value + return b +} + +// WithFallback sets the Fallback field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Fallback field is set to the value of the last call. +func (b *FailoverApplyConfiguration) WithFallback(value *LoadBalancerSpecApplyConfiguration) *FailoverApplyConfiguration { + b.Fallback = value + return b +} + +// WithErrors sets the Errors field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Errors field is set to the value of the last call. +func (b *FailoverApplyConfiguration) WithErrors(value *FailoverErrorApplyConfiguration) *FailoverApplyConfiguration { + b.Errors = value + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failovererror.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failovererror.go new file mode 100644 index 000000000..0d3380f55 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/failovererror.go @@ -0,0 +1,58 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2026 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// FailoverErrorApplyConfiguration represents a declarative configuration of the FailoverError type for use +// with apply. +type FailoverErrorApplyConfiguration struct { + Status []string `json:"status,omitempty"` + MaxRequestBodyBytes *int64 `json:"maxRequestBodyBytes,omitempty"` +} + +// FailoverErrorApplyConfiguration constructs a declarative configuration of the FailoverError type for use with +// apply. +func FailoverError() *FailoverErrorApplyConfiguration { + return &FailoverErrorApplyConfiguration{} +} + +// WithStatus adds the given value to the Status field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Status field. +func (b *FailoverErrorApplyConfiguration) WithStatus(values ...string) *FailoverErrorApplyConfiguration { + for i := range values { + b.Status = append(b.Status, values[i]) + } + return b +} + +// WithMaxRequestBodyBytes sets the MaxRequestBodyBytes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MaxRequestBodyBytes field is set to the value of the last call. +func (b *FailoverErrorApplyConfiguration) WithMaxRequestBodyBytes(value int64) *FailoverErrorApplyConfiguration { + b.MaxRequestBodyBytes = &value + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicespec.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicespec.go index 7ddaac9e6..038e8a073 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicespec.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/traefikservicespec.go @@ -32,6 +32,7 @@ type TraefikServiceSpecApplyConfiguration struct { Weighted *WeightedRoundRobinApplyConfiguration `json:"weighted,omitempty"` Mirroring *MirroringApplyConfiguration `json:"mirroring,omitempty"` HighestRandomWeight *HighestRandomWeightApplyConfiguration `json:"highestRandomWeight,omitempty"` + Failover *FailoverApplyConfiguration `json:"failover,omitempty"` } // TraefikServiceSpecApplyConfiguration constructs a declarative configuration of the TraefikServiceSpec type for use with @@ -63,3 +64,11 @@ func (b *TraefikServiceSpecApplyConfiguration) WithHighestRandomWeight(value *Hi b.HighestRandomWeight = value return b } + +// WithFailover sets the Failover field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Failover field is set to the value of the last call. +func (b *TraefikServiceSpecApplyConfiguration) WithFailover(value *FailoverApplyConfiguration) *TraefikServiceSpecApplyConfiguration { + b.Failover = value + return b +} diff --git a/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go b/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go index 62333ea43..082e745a8 100644 --- a/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go +++ b/pkg/provider/kubernetes/crd/generated/applyconfiguration/utils.go @@ -62,6 +62,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &traefikiov1alpha1.DigestAuthApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ErrorPage"): return &traefikiov1alpha1.ErrorPageApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("Failover"): + return &traefikiov1alpha1.FailoverApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("FailoverError"): + return &traefikiov1alpha1.FailoverErrorApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ForwardAuth"): return &traefikiov1alpha1.ForwardAuthApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ForwardingTimeouts"): diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index d9b3845b4..536957a8a 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -276,6 +276,8 @@ func (c configBuilder) buildTraefikService(ctx context.Context, tService *traefi return c.buildMirroring(ctx, tService, id, conf) case tService.Spec.HighestRandomWeight != nil: return c.buildHRW(ctx, tService, id, conf) + case tService.Spec.Failover != nil: + return c.buildFailover(ctx, tService, id, conf) default: return errors.New("unspecified service type") @@ -746,6 +748,33 @@ func (c configBuilder) buildHRW(ctx context.Context, tService *traefikv1alpha1.T return nil } +func (c configBuilder) buildFailover(ctx context.Context, tService *traefikv1alpha1.TraefikService, id string, conf map[string]*dynamic.Service) error { + serviceName, service, err := c.nameAndService(ctx, tService.Namespace, tService.Spec.Failover.Service) + if err != nil { + return fmt.Errorf("getting service: %w", err) + } + + fallbackName, fallback, err := c.nameAndService(ctx, tService.Namespace, tService.Spec.Failover.Fallback) + if err != nil { + return fmt.Errorf("getting fallback service: %w", err) + } + + failover := &dynamic.Failover{ + Service: serviceName, + Fallback: fallbackName, + Errors: &dynamic.FailoverError{ + Status: tService.Spec.Failover.Errors.Status, + MaxRequestBodyBytes: tService.Spec.Failover.Errors.MaxRequestBodyBytes, + }, + } + + conf[id] = &dynamic.Service{Failover: failover} + conf[serviceName] = service + conf[fallbackName] = fallback + + return nil +} + func splitSvcNameProvider(name string) (string, string) { parts := strings.Split(name, providerNamespaceSeparator) diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 64b922509..c62671106 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -3417,6 +3417,245 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, }, + { + desc: "one kube service in a failover", + paths: []string{"with_failover.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TLS: &dynamic.TLSConfiguration{}, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-77c62dfe9517144aeeaa": { + EntryPoints: []string{"web"}, + Service: "default-failover1", + Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-failover1": { + Failover: &dynamic.Failover{ + Service: "default-whoami5-8080", + Fallback: "default-whoami4-8080", + Errors: &dynamic.FailoverError{}, + }, + }, + "default-whoami4-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + { + URL: "http://10.10.0.2:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + "default-whoami5-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.3:8080", + }, + { + URL: "http://10.10.0.4:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + }, + }, + { + desc: "weighted services in a failover", + paths: []string{"with_failover2.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TLS: &dynamic.TLSConfiguration{}, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-77c62dfe9517144aeeaa": { + EntryPoints: []string{"web"}, + Service: "default-failover1", + Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-failover1": { + Failover: &dynamic.Failover{ + Service: "default-wrr1", + Fallback: "default-wrr2", + Errors: &dynamic.FailoverError{}, + }, + }, + "default-wrr1": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami4-8080", + Weight: pointer(1), + }, + }, + }, + }, + "default-wrr2": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami5-8080", + Weight: pointer(1), + }, + }, + }, + }, + "default-whoami4-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + { + URL: "http://10.10.0.2:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + "default-whoami5-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.3:8080", + }, + { + URL: "http://10.10.0.4:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + }, + }, + { + desc: "failover with errors configuration", + paths: []string{"with_failover_errors.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TLS: &dynamic.TLSConfiguration{}, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-test-route-77c62dfe9517144aeeaa": { + EntryPoints: []string{"web"}, + Service: "default-failover1", + Rule: "Host(`foo.com`) && PathPrefix(`/foo`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-failover1": { + Failover: &dynamic.Failover{ + Service: "default-whoami5-8080", + Fallback: "default-whoami4-8080", + Errors: &dynamic.FailoverError{ + Status: []string{"500-504", "404"}, + MaxRequestBodyBytes: pointer[int64](1048576), + }, + }, + }, + "default-whoami4-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + { + URL: "http://10.10.0.2:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + "default-whoami5-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Strategy: dynamic.BalancerStrategyWRR, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.3:8080", + }, + { + URL: "http://10.10.0.4:8080", + }, + }, + PassHostHeader: pointer(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + }, + }, { desc: "One ingress Route with two different services, with weights", paths: []string{"services.yml", "with_two_services_weight.yml"}, diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go index 35d45bcfc..cb96c5825 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go @@ -46,6 +46,8 @@ type TraefikServiceSpec struct { Mirroring *Mirroring `json:"mirroring,omitempty"` // HighestRandomWeight defines the highest random weight service configuration. HighestRandomWeight *HighestRandomWeight `json:"highestRandomWeight,omitempty"` + // Failover defines the Failover service configuration. + Failover *Failover `json:"failover,omitempty"` } // +k8s:deepcopy-gen=true @@ -97,3 +99,26 @@ type HighestRandomWeight struct { // Services defines the list of Kubernetes Service and/or TraefikService to load-balance, with weight. Services []Service `json:"services,omitempty"` } + +// +k8s:deepcopy-gen=true + +// Failover holds the Failover configuration. +type Failover struct { + // Service defines the main service to use. + Service LoadBalancerSpec `json:"service"` + // Fallback defines the fallback service to use when the main service returns an error. + Fallback LoadBalancerSpec `json:"fallback"` + // Errors defines which errors should trigger the use of the fallback service. + Errors FailoverError `json:"errors"` +} + +// +k8s:deepcopy-gen=true + +// FailoverError holds errors configuration for a Failover service. +type FailoverError struct { + // Status defines the list of status code ranges for which the fallback service should be used. + Status []string `json:"status,omitempty"` + // MaxRequestBodyBytes defines the maximum size allowed for the body of the request. + // Default value is -1, which means unlimited size. + MaxRequestBodyBytes *int64 `json:"maxRequestBodyBytes,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 10bd48dbe..feb3dedfa 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go @@ -283,6 +283,51 @@ func (in *ErrorPage) DeepCopy() *ErrorPage { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Failover) DeepCopyInto(out *Failover) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + in.Fallback.DeepCopyInto(&out.Fallback) + in.Errors.DeepCopyInto(&out.Errors) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Failover. +func (in *Failover) DeepCopy() *Failover { + if in == nil { + return nil + } + out := new(Failover) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FailoverError) DeepCopyInto(out *FailoverError) { + *out = *in + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.MaxRequestBodyBytes != nil { + in, out := &in.MaxRequestBodyBytes, &out.MaxRequestBodyBytes + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverError. +func (in *FailoverError) DeepCopy() *FailoverError { + if in == nil { + return nil + } + out := new(FailoverError) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ForwardAuth) DeepCopyInto(out *ForwardAuth) { *out = *in @@ -2139,6 +2184,11 @@ func (in *TraefikServiceSpec) DeepCopyInto(out *TraefikServiceSpec) { *out = new(HighestRandomWeight) (*in).DeepCopyInto(*out) } + if in.Failover != nil { + in, out := &in.Failover, &out.Failover + *out = new(Failover) + (*in).DeepCopyInto(*out) + } return }