Skip to main content

Kubernetes Service

In Kubernetes, a Service is the implementation of a Traefik HTTP service.

There is no dedicated CRD, a Service is part of:


Configuration Example

You can declare a Service either as part of an IngressRoute or a TraefikService as detailed below:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-name
namespace: apps
spec:
entryPoints:
- web
routes:
- kind: Rule
# Rule on the Host
match: Host(`test.example.com`)
services:
# Target a Kubernetes Service
- kind: Service
name: foo
namespace: apps
# Customize the connection between Traefik Hub and the backend
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: wrr

Configuration Options

FieldDescriptionDefaultRequired
kindKind of the service targeted.
Two values allowed:
- Service: Kubernetes Service
- TraefikService: Traefik Service.
"Service"No
nameService name.
The character @ is not authorized.
""Yes
namespaceService namespace.
Can be empty if the service belongs to the same namespace as the IngressRoute.
""No
portService 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.
100msNo
schemeScheme 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
serversTransportName of ServersTransport resource to use to configure the transport between Traefik Hub and your servers.
Evaluated only if the kind is Service.
""No
passHostHeaderForward client Host header to server.
Evaluated only if the kind is Service.
trueNo
healthCheck.schemeServer URL scheme for the health check endpoint.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
""No
healthCheck.modeHealth 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 of type ExternalName.
"http"No
healthCheck.pathServer URL path for the health check endpoint.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
""No
healthCheck.intervalFrequency of the health check calls for healthy targets.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
"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 of type ExternalName.
"100ms"No
healthCheck.methodHTTP method for the health check endpoint.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
"GET"No
healthCheck.statusExpected HTTP status code of the response to the health check request.
Only for Kubernetes service of type ExternalName.
If not set, expect a status between 200 and 399.
Evaluated only if the kind is Service.
No
healthCheck.portURL port for the health check endpoint.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
No
healthCheck.timeoutMaximum duration to wait before considering the server unhealthy.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
"5s"No
healthCheck.hostnameValue in the Host header of the health check request.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
""No
healthCheck.
followRedirect
Follow the redirections during the healthcheck.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
trueNo
healthCheck.headersMap of header to send to the health check endpoint.
Evaluated only if the kind is Service.
Only for Kubernetes service of type ExternalName.
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 specified 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.
Abbreviation of a sha1
(ex: _1d52e).
No
sticky.
cookie.httpOnly
Allow the cookie can be accessed by client-side APIs, such as JavaScript.
Evaluated only if the kind is Service.
falseNo
sticky.
cookie.secure
Allow the cookie can only be transmitted over an encrypted connection (that is, HTTPS).
Evaluated only if the kind is Service.
falseNo
sticky.
cookie.sameSite
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.
0No
strategyLoad balancing strategy between the servers.
Allowed values:
- wrr: Weighted Round Robin (default)
- p2c: Power of Two Choices algorithm for better load distribution
- hrw: Highest Random Weight for consistent hashing
- RoundRobin: Deprecated, use wrr instead
Evaluated only if the kind is Service.
"wrr"No
nativeLBAllow using the Kubernetes Service load balancing between the pods instead of the one provided by Traefik Hub.
Evaluated only if the kind is Service.
falseNo
nodePortLBUse the nodePort IP address when the service type is NodePort.
It allows services to be reachable when Traefik Hub runs externally from the Kubernetes cluster but within the same network of the nodes.
Evaluated only if the kind is Service.
falseNo

ExternalName Service

Traefik Hub backends creation needs a port to be set, however Kubernetes ExternalName Service could be defined without any port. Accordingly, Traefik Hub supports defining a port in two ways:

  • only on IngressRoute service
  • on both sides, you'll be warned if the ports don't match, and the IngressRoute service port is used

Thus, in case of two sides port definition, Traefik Hub expects a match between port.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName

Load Balancing

You can declare and use Kubernetes Service load balancing as detailed below:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`example.com`) && PathPrefix(`/foo`)
kind: Rule
services:
- name: svc1
namespace: default
- name: svc2
namespace: default

Load Balancing Algorithms

Traefik Hub supports multiple load balancing algorithms for distributing traffic among the pods of a Kubernetes Service. The algorithm is configured using the strategy field on the service configuration.

The available algorithms are:

  • wrr (Weighted Round Robin): Distributes requests evenly across all servers in rotation. This is the default strategy.

  • p2c (Power of Two Choices): Selects two random servers and routes the request to the one with fewer active connections. This algorithm provides better load distribution when servers have varying response times.

  • hrw (Highest Random Weight): Uses consistent hashing to ensure requests from the same client IP are consistently routed to the same server, providing session affinity based on the client's remote address.

RoundRobin Deprecation

The RoundRobin strategy value has been deprecated and replaced by wrr. While still supported for backwards compatibility, please use wrr instead.

Understanding Pod-Level vs Service-Level Load Balancing

Traefik Hub offers load balancing at two different levels:

Pod-level load balancing (configured on a Kubernetes Service reference):

  • Distributes traffic between individual pod IPs within a single Kubernetes Service
  • Supports: wrr, p2c, and hrw algorithms
  • Traefik Hub discovers pod IPs via Kubernetes EndpointSlices and connects directly to them
  • Bypasses Kubernetes Service's internal load balancing for more control

Service-level load balancing (configured in TraefikService):

  • Distributes traffic between multiple Kubernetes Services or TraefikServices
  • Supports: Weighted Round Robin, Highest Random Weight, and Mirroring
  • Used when you need to balance between different services, implement A/B testing, canary deployments, or traffic mirroring

When you configure a strategy on a Kubernetes Service reference, Traefik Hub:

  1. Queries Kubernetes to discover all pod IPs associated with that service via EndpointSlices
  2. Creates direct connections to each pod IP (bypassing the Kubernetes Service's ClusterIP)
  3. Applies your chosen load balancing algorithm to distribute requests across those pods
  4. Maintains persistent connections to backends for performance

This approach gives you algorithmic control over pod-level load balancing while leveraging Kubernetes for dynamic service discovery. Use nativeLB if you prefer to delegate load balancing to Kubernetes instead.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`example.com`) && PathPrefix(`/foo`)
kind: Rule
services:
- name: svc1
namespace: default
strategy: wrr

For advanced load balancing between multiple services (not only between pods within a service), use a TraefikService which supports WRR, HRW, and mirroring for service-to-service load balancing.

NativeLB

To avoid creating the server load-balancer with the pod IPs and use Kubernetes Service clusterIP directly, one should set the service nativeLB option to true.

By default, Traefik Hub reuses the established connections to the backends for performance purposes. This can prevent the requests load balancing between the replicas from behaving as one would expect when the option is set.

By default, nativeLB is false.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: svc
port: 80
# Here, nativeLB instructs to build the server load-balancer with the Kubernetes Service clusterIP only.
nativeLB: true

Configuring Backend Protocol

There are 3 ways to configure the backend protocol for communication between Traefik Hub and your pods:

  • Setting the scheme explicitly (http/https/h2c)
  • Configuring the name of the kubernetes service port to start with https (https)
  • Setting the kubernetes service port to use port 443 (https)

If you do not configure the above, Traefik Hub will assume an http connection.