Overview

What’s Happening to the Requests?

Let’s zoom in on Traefik’s architecture and talk about the components that enable the routes to be created.

First, when you start Traefik, you define entrypoints (in their most basic forms, they are port numbers). Then, connected to these entrypoints, routers analyze the incoming requests to see if they match a set of rules. If they do, the router might transform the request using pieces of middleware before forwarding them to your services.

Architecture

Clear Responsibilities

  • Providers discover the services that live on your infrastructure (their IP, health, …)
  • Entrypoints listen for incoming traffic (ports, …)
  • Routers analyse the requests (host, path, headers, SSL, …)
  • Services forward the request to your services (load balancing, …)
  • Middlewares may update the request or make decisions based on the request (authentication, rate limiting, headers, …)

Example with a File Provider

Below is an example of a full configuration file for the file provider that forwards http://example.com/whoami/ requests to a service reachable on http://private/whoami-service/. In the process, Traefik will make sure that the user is authenticated (using the BasicAuth middleware).

Static configuration:

File (YAML)

  1. entryPoints:
  2. web:
  3. # Listen on port 8081 for incoming requests
  4. address: :8081
  5. providers:
  6. # Enable the file provider to define routers / middlewares / services in file
  7. file:
  8. directory: /path/to/dynamic/conf

File (TOML)

  1. [entryPoints]
  2. [entryPoints.web]
  3. # Listen on port 8081 for incoming requests
  4. address = ":8081"
  5. [providers]
  6. # Enable the file provider to define routers / middlewares / services in file
  7. [providers.file]
  8. directory = "/path/to/dynamic/conf"

CLI

  1. # Listen on port 8081 for incoming requests
  2. --entryPoints.web.address=:8081
  3. # Enable the file provider to define routers / middlewares / services in file
  4. --providers.file.directory=/path/to/dynamic/conf

Dynamic configuration:

YAML

  1. # http routing section
  2. http:
  3. routers:
  4. # Define a connection between requests and services
  5. to-whoami:
  6. rule: "Host(`example.com`) && PathPrefix(`/whoami/`)"
  7. # If the rule matches, applies the middleware
  8. middlewares:
  9. - test-user
  10. # If the rule matches, forward to the whoami service (declared below)
  11. service: whoami
  12. middlewares:
  13. # Define an authentication mechanism
  14. test-user:
  15. basicAuth:
  16. users:
  17. - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
  18. services:
  19. # Define how to reach an existing service on our infrastructure
  20. whoami:
  21. loadBalancer:
  22. servers:
  23. - url: http://private/whoami-service

TOML

  1. # http routing section
  2. [http]
  3. [http.routers]
  4. # Define a connection between requests and services
  5. [http.routers.to-whoami]
  6. rule = "Host(`example.com`) && PathPrefix(`/whoami/`)"
  7. # If the rule matches, applies the middleware
  8. middlewares = ["test-user"]
  9. # If the rule matches, forward to the whoami service (declared below)
  10. service = "whoami"
  11. [http.middlewares]
  12. # Define an authentication mechanism
  13. [http.middlewares.test-user.basicAuth]
  14. users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
  15. [http.services]
  16. # Define how to reach an existing service on our infrastructure
  17. [http.services.whoami.loadBalancer]
  18. [[http.services.whoami.loadBalancer.servers]]
  19. url = "http://private/whoami-service"

In this example, we use the file provider. Even if it is one of the least magical way of configuring Traefik, it explicitly describes every available notion.

HTTP / TCP

In this example, we’ve defined routing rules for http requests only. Traefik also supports TCP requests. To add TCP routers and TCP services, declare them in a TCP section like in the following.

Adding a TCP route for TLS requests on whoami-tcp.example.com

Static Configuration

File (YAML)

  1. entryPoints:
  2. web:
  3. # Listen on port 8081 for incoming requests
  4. address: :8081
  5. providers:
  6. # Enable the file provider to define routers / middlewares / services in file
  7. file:
  8. directory: /path/to/dynamic/conf

File (TOML)

  1. [entryPoints]
  2. [entryPoints.web]
  3. # Listen on port 8081 for incoming requests
  4. address = ":8081"
  5. [providers]
  6. # Enable the file provider to define routers / middlewares / services in file
  7. [providers.file]
  8. directory = "/path/to/dynamic/conf"

CLI

  1. # Listen on port 8081 for incoming requests
  2. --entryPoints.web.address=:8081
  3. # Enable the file provider to define routers / middlewares / services in file
  4. --providers.file.directory=/path/to/dynamic/conf

Dynamic Configuration

YAML

  1. # http routing section
  2. http:
  3. routers:
  4. # Define a connection between requests and services
  5. to-whoami:
  6. rule: Host(`example.com`) && PathPrefix(`/whoami/`)
  7. # If the rule matches, applies the middleware
  8. middlewares:
  9. - test-user
  10. # If the rule matches, forward to the whoami service (declared below)
  11. service: whoami
  12. middlewares:
  13. # Define an authentication mechanism
  14. test-user:
  15. basicAuth:
  16. users:
  17. - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
  18. services:
  19. # Define how to reach an existing service on our infrastructure
  20. whoami:
  21. loadBalancer:
  22. servers:
  23. - url: http://private/whoami-service
  24. tcp:
  25. routers:
  26. to-whoami-tcp:
  27. service: whoami-tcp
  28. rule: HostSNI(`whoami-tcp.example.com`)
  29. tls: {}
  30. services:
  31. whoami-tcp:
  32. loadBalancer:
  33. servers:
  34. - address: xx.xx.xx.xx:xx

TOML

  1. # http routing section
  2. [http]
  3. [http.routers]
  4. # Define a connection between requests and services
  5. [http.routers.to-whoami]
  6. rule = "Host(`example.com`) && PathPrefix(`/whoami/`)"
  7. # If the rule matches, applies the middleware
  8. middlewares = ["test-user"]
  9. # If the rule matches, forward to the whoami service (declared below)
  10. service = "whoami"
  11. [http.middlewares]
  12. # Define an authentication mechanism
  13. [http.middlewares.test-user.basicAuth]
  14. users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
  15. [http.services]
  16. # Define how to reach an existing service on our infrastructure
  17. [http.services.whoami.loadBalancer]
  18. [[http.services.whoami.loadBalancer.servers]]
  19. url = "http://private/whoami-service"
  20. [tcp]
  21. [tcp.routers]
  22. [tcp.routers.to-whoami-tcp]
  23. rule = "HostSNI(`whoami-tcp.example.com`)"
  24. service = "whoami-tcp"
  25. [tcp.routers.to-whoami-tcp.tls]
  26. [tcp.services]
  27. [tcp.services.whoami-tcp.loadBalancer]
  28. [[tcp.services.whoami-tcp.loadBalancer.servers]]
  29. address = "xx.xx.xx.xx:xx"

Transport configuration

Most of what happens to the connection between the clients and Traefik, and then between Traefik and the backend servers, is configured through the entrypoints and the routers.

In addition, a few parameters are dedicated to configuring globally what happens with the connections between Traefik and the backends. This is done through the serversTransport and tcpServersTransport sections of the configuration, which features these options:

HTTP Servers Transports

insecureSkipVerify

Optional, Default=false

insecureSkipVerify disables SSL certificate verification.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. insecureSkipVerify: true

File (TOML)

  1. ## Static configuration
  2. [serversTransport]
  3. insecureSkipVerify = true

CLI

  1. ## Static configuration
  2. --serversTransport.insecureSkipVerify=true

rootCAs

Optional

rootCAs is the list of certificates (as file paths, or data bytes) that will be set as Root Certificate Authorities when using a self-signed TLS certificate.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. rootCAs:
  4. - foo.crt
  5. - bar.crt

File (TOML)

  1. ## Static configuration
  2. [serversTransport]
  3. rootCAs = ["foo.crt", "bar.crt"]

CLI

  1. ## Static configuration
  2. --serversTransport.rootCAs=foo.crt,bar.crt

maxIdleConnsPerHost

Optional, Default=2

If non-zero, maxIdleConnsPerHost controls the maximum idle (keep-alive) connections to keep per-host.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. maxIdleConnsPerHost: 7

File (TOML)

  1. ## Static configuration
  2. [serversTransport]
  3. maxIdleConnsPerHost = 7

CLI

  1. ## Static configuration
  2. --serversTransport.maxIdleConnsPerHost=7

spiffe

Please note that SPIFFE must be enabled in the static configuration before using it to secure the connection between Traefik and the backends.

spiffe.ids

Optional

ids defines the allowed SPIFFE IDs. This takes precedence over the SPIFFE TrustDomain.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. spiffe:
  4. ids:
  5. - spiffe://trust-domain/id1
  6. - spiffe://trust-domain/id2

File (TOML)

  1. ## Static configuration
  2. [serversTransport.spiffe]
  3. ids = ["spiffe://trust-domain/id1", "spiffe://trust-domain/id2"]

CLI

  1. ## Static configuration
  2. --serversTransport.spiffe.ids=spiffe://trust-domain/id1,spiffe://trust-domain/id2

spiffe.trustDomain

Optional

trustDomain defines the allowed SPIFFE trust domain.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. trustDomain: spiffe://trust-domain

File (TOML)

  1. ## Static configuration
  2. [serversTransport.spiffe]
  3. trustDomain = "spiffe://trust-domain"

CLI

  1. ## Static configuration
  2. --serversTransport.spiffe.trustDomain=spiffe://trust-domain

forwardingTimeouts

forwardingTimeouts is about a number of timeouts relevant to when forwarding requests to the backend servers.

forwardingTimeouts.dialTimeout

Optional, Default=30s

dialTimeout is the maximum duration allowed for a connection to a backend server to be established. Zero means no timeout.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. forwardingTimeouts:
  4. dialTimeout: 1s

File (TOML)

  1. ## Static configuration
  2. [serversTransport.forwardingTimeouts]
  3. dialTimeout = "1s"

CLI

  1. ## Static configuration
  2. --serversTransport.forwardingTimeouts.dialTimeout=1s

forwardingTimeouts.responseHeaderTimeout

Optional, Default=0s

responseHeaderTimeout, if non-zero, specifies the amount of time to wait for a server’s response headers after fully writing the request (including its body, if any). This time does not include the time to read the response body. Zero means no timeout.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. forwardingTimeouts:
  4. responseHeaderTimeout: 1s

File (TOML)

  1. ## Static configuration
  2. [serversTransport.forwardingTimeouts]
  3. responseHeaderTimeout = "1s"

CLI

  1. ## Static configuration
  2. --serversTransport.forwardingTimeouts.responseHeaderTimeout=1s

forwardingTimeouts.idleConnTimeout

Optional, Default=90s

idleConnTimeout, is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit.

File (YAML)

  1. ## Static configuration
  2. serversTransport:
  3. forwardingTimeouts:
  4. idleConnTimeout: 1s

File (TOML)

  1. ## Static configuration
  2. [serversTransport.forwardingTimeouts]
  3. idleConnTimeout = "1s"

CLI

  1. ## Static configuration
  2. --serversTransport.forwardingTimeouts.idleConnTimeout=1s

TCP Servers Transports

dialTimeout

Optional, Default=”30s”

dialTimeout is the maximum duration allowed for a connection to a backend server to be established. Zero means no timeout.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. dialTimeout: 30s

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport]
  3. dialTimeout = "30s"

CLI

  1. ## Static configuration
  2. --tcpServersTransport.dialTimeout=30s

dialKeepAlive

Optional, Default=”15s”

dialKeepAlive defines the interval between keep-alive probes sent on an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. dialKeepAlive: 30s

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport]
  3. dialKeepAlive = "30s"

CLI

  1. ## Static configuration
  2. --tcpServersTransport.dialKeepAlive=30s

tls

tls defines the TLS configuration to connect with TCP backends.

Optional

An empty tls section enables TLS.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. tls: {}

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport.tls]

CLI

  1. ## Static configuration
  2. --tcpServersTransport.tls=true

tls.insecureSkipVerify

Optional

insecureSkipVerify disables the server’s certificate chain and host name verification.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. tls:
  4. insecureSkipVerify: true

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport.tls]
  3. insecureSkipVerify = true

CLI

  1. ## Static configuration
  2. --tcpServersTransport.tls.insecureSkipVerify=true

tls.rootCAs

Optional

rootCAs defines the set of Root Certificate Authorities (as file paths, or data bytes) to use when verifying self-signed TLS server certificates.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. tls:
  4. rootCAs:
  5. - foo.crt
  6. - bar.crt

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport.tls]
  3. rootCAs = ["foo.crt", "bar.crt"]

CLI

  1. ## Static configuration
  2. --tcpServersTransport.tls.rootCAs=foo.crt,bar.crt

spiffe

Please note that SPIFFE must be enabled in the static configuration before using it to secure the connection between Traefik and the backends.

spiffe.ids

Optional

ids defines the allowed SPIFFE IDs. This takes precedence over the SPIFFE TrustDomain.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. spiffe:
  4. ids:
  5. - spiffe://trust-domain/id1
  6. - spiffe://trust-domain/id2

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport.spiffe]
  3. ids = ["spiffe://trust-domain/id1", "spiffe://trust-domain/id2"]

CLI

  1. ## Static configuration
  2. --tcpServersTransport.spiffe.ids=spiffe://trust-domain/id1,spiffe://trust-domain/id2

spiffe.trustDomain

Optional

trustDomain defines the allowed SPIFFE trust domain.

File (YAML)

  1. ## Static configuration
  2. tcpServersTransport:
  3. trustDomain: spiffe://trust-domain

File (TOML)

  1. ## Static configuration
  2. [tcpServersTransport.spiffe]
  3. trustDomain = "spiffe://trust-domain"

CLI

  1. ## Static configuration
  2. --tcpServersTransport.spiffe.trustDomain=spiffe://trust-domain

Using Traefik OSS in Production?

If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS.

Adding API Gateway capabilities to Traefik OSS is fast and seamless. There’s no rip and replace and all configurations remain intact. See it in action via this short video.