Skip to content

Traefik - Cloud Native Edge Router

A comprehensive guide to Traefik - a modern HTTP reverse proxy and load balancer for microservices.

Table of Contents

Introduction

What is Traefik?

Traefik is a modern HTTP reverse proxy and load balancer designed for deploying microservices. It integrates seamlessly with existing infrastructure components and configures itself automatically and dynamically.

Key Features

  • Automatic Service Discovery: Auto-configuration from service registries
  • Let's Encrypt Integration: Automatic SSL certificate provisioning
  • Multiple Protocols: HTTP, HTTPS, TCP, UDP
  • Middleware System: Modular request/response transformations
  • Load Balancing: Multiple algorithms and health checks
  • Metrics & Tracing: Prometheus, Datadog, Jaeger integration
  • High Availability: Clustering support
  • WebSocket Support: Native WebSocket proxying

Installation

Docker

# Run Traefik in Docker
docker run -d \
  -p 80:80 \
  -p 443:443 \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $PWD/traefik.yml:/etc/traefik/traefik.yml \
  --name traefik \
  traefik:v3.0

# Docker Compose
version: '3'

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

Kubernetes (Helm)

# Add Helm repository
helm repo add traefik https://traefik.github.io/charts
helm repo update

# Install Traefik
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --set dashboard.enabled=true \
  --set rbac.enabled=true

# Custom values
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --values traefik-values.yaml

Traefik Helm Values

# traefik-values.yaml
# Deployment
deployment:
  replicas: 3

# Enable dashboard
dashboard:
  enabled: true
  domain: traefik.example.com

# Entry points
ports:
  web:
    port: 80
    exposedPort: 80
    protocol: TCP
  websecure:
    port: 443
    exposedPort: 443
    protocol: TCP
    tls:
      enabled: true
  metrics:
    port: 9100
    expose: true
    protocol: TCP

# Providers
providers:
  kubernetesCRD:
    enabled: true
  kubernetesIngress:
    enabled: true
    publishedService:
      enabled: true

# Let's Encrypt
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /data/acme.json
      httpChallenge:
        entryPoint: web

# Metrics
metrics:
  prometheus:
    enabled: true
    addEntryPointsLabels: true
    addServicesLabels: true

# Logs
logs:
  general:
    level: INFO
  access:
    enabled: true

Binary Installation

# Download Traefik binary
wget https://github.com/traefik/traefik/releases/download/v3.0.0/traefik_v3.0.0_linux_amd64.tar.gz
tar -xzf traefik_v3.0.0_linux_amd64.tar.gz
sudo mv traefik /usr/local/bin/

# Make executable
sudo chmod +x /usr/local/bin/traefik

# Verify
traefik version

Core Concepts

Architecture

Client Request
Entry Points (Ports: 80, 443, etc.)
Routers (Match requests based on rules)
Middlewares (Transform request/response)
Services (Load balance to backends)
Backend Servers

Providers

Traefik discovers services from providers:

  • Docker: Labels on containers
  • Kubernetes: Ingress, IngressRoute CRDs
  • File: Static configuration files
  • Consul: Service discovery
  • Etcd: Distributed configuration
  • HTTP: API-based configuration

Routers

Match requests and forward to services:

# HTTP Router
http:
  routers:
    my-router:
      rule: "Host(`example.com`) && Path(`/api`)"
      service: my-service
      middlewares:
        - auth
        - compress
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

Services

Define how to reach backends:

http:
  services:
    my-service:
      loadBalancer:
        servers:
          - url: "http://backend1:8080"
          - url: "http://backend2:8080"
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s

Configuration

Static Configuration

# traefik.yml (Static Configuration)
global:
  checkNewVersion: true
  sendAnonymousUsage: false

# API and Dashboard
api:
  dashboard: true
  insecure: false

# Entry Points
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

# Providers
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: web

  file:
    directory: /etc/traefik/dynamic
    watch: true

# Certificate Resolvers
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

# Logging
log:
  level: INFO
  filePath: /var/log/traefik/traefik.log

accessLog:
  filePath: /var/log/traefik/access.log
  format: json

# Metrics
metrics:
  prometheus:
    buckets:
      - 0.1
      - 0.3
      - 1.2
      - 5.0

Dynamic Configuration

# dynamic.yml
http:
  routers:
    api-router:
      rule: "Host(`api.example.com`)"
      service: api-service
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt
      middlewares:
        - rate-limit
        - auth

  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:8080"
          - url: "http://192.168.1.101:8080"
        healthCheck:
          path: /health
          interval: "10s"

  middlewares:
    rate-limit:
      rateLimit:
        average: 100
        burst: 50

    auth:
      basicAuth:
        users:
          - "user:$apr1$xxx"  # Use htpasswd

Kubernetes Ingress

Standard Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: traefik
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls

IngressRoute CRD

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: myapp-ingressroute
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`myapp.example.com`) && PathPrefix(`/api`)
    kind: Rule
    services:
    - name: myapp-api
      port: 8080
    middlewares:
    - name: api-auth
    - name: rate-limit

  - match: Host(`myapp.example.com`)
    kind: Rule
    services:
    - name: myapp-web
      port: 80

  tls:
    certResolver: letsencrypt
    domains:
    - main: myapp.example.com
      sans:
      - www.myapp.example.com

TCP IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: postgres-ingressroute
spec:
  entryPoints:
    - postgres
  routes:
  - match: HostSNI(`*`)
    services:
    - name: postgres
      port: 5432

Middlewares

Authentication

# Basic Auth
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth
spec:
  basicAuth:
    secret: auth-secret  # Contains user:password (htpasswd format)

---
# Forward Auth (OAuth2, SSO)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth2-proxy
spec:
  forwardAuth:
    address: http://oauth2-proxy.auth.svc:4180
    authResponseHeaders:
      - X-Auth-User
      - X-Auth-Email

Rate Limiting

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
spec:
  rateLimit:
    average: 100  # Requests per second
    burst: 50     # Burst size
    period: 1s

Headers

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-headers
spec:
  headers:
    customResponseHeaders:
      X-Frame-Options: "SAMEORIGIN"
      X-Content-Type-Options: "nosniff"
      X-XSS-Protection: "1; mode=block"
      Referrer-Policy: "strict-origin-when-cross-origin"
    stsSeconds: 31536000
    stsIncludeSubdomains: true
    stsPreload: true

Compression

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: compress
spec:
  compress: {}

Redirect

# HTTPS Redirect
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-https
spec:
  redirectScheme:
    scheme: https
    permanent: true

---
# WWW Redirect
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-www
spec:
  redirectRegex:
    regex: "^https://example.com/(.*)"
    replacement: "https://www.example.com/${1}"
    permanent: true

Strip Prefix

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: strip-api-prefix
spec:
  stripPrefix:
    prefixes:
      - /api

IP Whitelist

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: ip-whitelist
spec:
  ipWhiteList:
    sourceRange:
      - "192.168.1.0/24"
      - "172.16.0.1"

Circuit Breaker

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: circuit-breaker
spec:
  circuitBreaker:
    expression: "NetworkErrorRatio() > 0.30"

Retry

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: retry
spec:
  retry:
    attempts: 4
    initialInterval: 100ms

TLS & Certificates

Let's Encrypt

# traefik.yml
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      # HTTP Challenge
      httpChallenge:
        entryPoint: web
      # DNS Challenge (for wildcards)
      # dnsChallenge:
      #   provider: cloudflare
      #   delayBeforeCheck: 0

Custom TLS Certificate

# Create TLS secret
kubectl create secret tls myapp-tls \
  --cert=cert.pem \
  --key=key.pem

# Use in IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`myapp.example.com`)
    kind: Rule
    services:
    - name: myapp
      port: 80
  tls:
    secretName: myapp-tls

TLS Options

apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
  name: modern-tls
spec:
  minVersion: VersionTLS12
  cipherSuites:
    - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  curvePreferences:
    - CurveP521
    - CurveP384
  sniStrict: true

Load Balancing

Algorithms

http:
  services:
    my-service:
      loadBalancer:
        # Round Robin (default)
        servers:
          - url: "http://backend1:8080"
          - url: "http://backend2:8080"

        # Weighted Round Robin
        # servers:
        #   - url: "http://backend1:8080"
        #     weight: 3
        #   - url: "http://backend2:8080"
        #     weight: 1

        # Sticky Sessions
        sticky:
          cookie:
            name: traefik_session
            secure: true
            httpOnly: true

        # Health Check
        healthCheck:
          path: /health
          interval: "10s"
          timeout: "3s"
          scheme: http

Mirroring (Traffic Shadowing)

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror-service
spec:
  mirroring:
    name: production
    port: 80
    mirrors:
    - name: canary
      port: 80
      percent: 10

Weighted Round Robin

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: weighted-service
spec:
  weighted:
    services:
    - name: app-v1
      weight: 90
      port: 80
    - name: app-v2
      weight: 10
      port: 80

Observability

Prometheus Metrics

# Enable metrics in traefik.yml
metrics:
  prometheus:
    buckets:
      - 0.1
      - 0.3
      - 1.2
      - 5.0
    addEntryPointsLabels: true
    addServicesLabels: true
    addRoutersLabels: true

# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: traefik
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: traefik
  endpoints:
  - port: metrics
    interval: 30s

Access Logs

accessLog:
  filePath: /var/log/traefik/access.log
  format: json
  filters:
    statusCodes:
      - "400-499"
      - "500-599"
    retryAttempts: true
    minDuration: "10ms"
  fields:
    defaultMode: keep
    headers:
      defaultMode: drop
      names:
        User-Agent: keep
        Authorization: drop

Tracing

# Jaeger tracing
tracing:
  jaeger:
    samplingServerURL: http://jaeger:5778/sampling
    localAgentHostPort: jaeger:6831

# Zipkin tracing
tracing:
  zipkin:
    httpEndpoint: http://zipkin:9411/api/v2/spans
    sameSpan: true
    id128Bit: true

Advanced Configuration Examples

Multi-Domain Routing with Path Matching

# Complex routing with multiple domains and path conditions
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: complex-routing
spec:
  entryPoints:
    - websecure
  routes:
  # API v1 on api.example.com
  - match: Host(`api.example.com`) && PathPrefix(`/v1/users`)
    kind: Rule
    priority: 100
    services:
    - name: user-service-v1
      port: 8080
    middlewares:
    - name: api-v1-auth
    - name: rate-limit-api

  # API v2 on api.example.com
  - match: Host(`api.example.com`) && PathPrefix(`/v2/users`)
    kind: Rule
    priority: 100
    services:
    - name: user-service-v2
      port: 8080
    middlewares:
    - name: api-v2-auth
    - name: rate-limit-api

  # Admin panel with IP restriction
  - match: Host(`admin.example.com`)
    kind: Rule
    priority: 90
    services:
    - name: admin-panel
      port: 80
    middlewares:
    - name: admin-ip-whitelist
    - name: admin-basic-auth

  # Static assets with caching
  - match: Host(`static.example.com`) && PathPrefix(`/assets`)
    kind: Rule
    priority: 80
    services:
    - name: static-server
      port: 80
    middlewares:
    - name: cache-headers
    - name: compress

  # Default route
  - match: Host(`example.com`) || Host(`www.example.com`)
    kind: Rule
    priority: 50
    services:
    - name: main-website
      port: 80
    middlewares:
    - name: www-redirect

  tls:
    certResolver: letsencrypt
    domains:
    - main: example.com
      sans:
      - "*.example.com"

Canary Deployment with Traffic Splitting

# Weighted service for canary releases
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: canary-deployment
  namespace: production
spec:
  weighted:
    services:
    - name: app-stable
      weight: 95
      port: 8080
      kind: Service
    - name: app-canary
      weight: 5
      port: 8080
      kind: Service

---
# IngressRoute using the weighted service
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: app-canary-route
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`app.example.com`)
    kind: Rule
    services:
    - name: canary-deployment
      kind: TraefikService
    middlewares:
    - name: canary-headers
  tls:
    certResolver: letsencrypt

---
# Middleware to add canary tracking headers
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: canary-headers
spec:
  headers:
    customResponseHeaders:
      X-Canary-Version: "v2.0.0-canary"

Blue-Green Deployment

# Blue environment (current production)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: app-blue
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`app.example.com`)
    kind: Rule
    services:
    - name: app-blue
      port: 8080
  tls:
    certResolver: letsencrypt

---
# Green environment (new version - testing via header)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: app-green-testing
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`app.example.com`) && HeadersRegexp(`X-Environment`, `green`)
    kind: Rule
    priority: 100
    services:
    - name: app-green
      port: 8080
  tls:
    certResolver: letsencrypt

---
# Switch to green (update the main route)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: app-production
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`app.example.com`)
    kind: Rule
    services:
    - name: app-green  # Changed from app-blue
      port: 8080
  tls:
    certResolver: letsencrypt

Advanced Middleware Chaining

# Complete middleware chain for production API
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-production
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`api.example.com`)
    kind: Rule
    services:
    - name: api-backend
      port: 8080
    middlewares:
    - name: security-headers        # 1. Add security headers
    - name: ip-whitelist           # 2. Check IP whitelist
    - name: rate-limit-global      # 3. Global rate limit
    - name: rate-limit-per-ip      # 4. Per-IP rate limit
    - name: oauth2-auth            # 5. OAuth2 authentication
    - name: strip-prefix           # 6. Strip /api prefix
    - name: add-correlation-id     # 7. Add correlation ID
    - name: compress               # 8. Compress response
    - name: circuit-breaker        # 9. Circuit breaker
    - name: retry                  # 10. Retry on failure
  tls:
    certResolver: letsencrypt

---
# Add correlation ID for tracing
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-correlation-id
spec:
  headers:
    customRequestHeaders:
      X-Correlation-ID: "{{uuid}}"

Custom Error Pages

# Custom error page middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: custom-errors
spec:
  errors:
    status:
      - "400-599"
    service:
      name: error-pages
      port: 80
    query: "/{status}.html"

---
# Error pages service deployment
apiVersion: v1
kind: ConfigMap
metadata:
  name: error-pages-html
data:
  404.html: |
    <!DOCTYPE html>
    <html>
    <head><title>404 Not Found</title></head>
    <body>
      <h1>404 - Page Not Found</h1>
      <p>The resource you requested could not be found.</p>
    </body>
    </html>

  500.html: |
    <!DOCTYPE html>
    <html>
    <head><title>500 Internal Server Error</title></head>
    <body>
      <h1>500 - Internal Server Error</h1>
      <p>Something went wrong. Please try again later.</p>
    </body>
    </html>

  503.html: |
    <!DOCTYPE html>
    <html>
    <head><title>503 Service Unavailable</title></head>
    <body>
      <h1>503 - Service Unavailable</h1>
      <p>The service is temporarily unavailable. Please try again soon.</p>
    </body>
    </html>

Request/Response Modification

# Add custom headers based on conditions
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: custom-headers
spec:
  headers:
    # Custom request headers
    customRequestHeaders:
      X-Forwarded-Proto: "https"
      X-Custom-Header: "CustomValue"
      X-Real-IP: "{{.RemoteAddr}}"

    # Custom response headers
    customResponseHeaders:
      X-Custom-Response: "API-Gateway"
      X-Frame-Options: "SAMEORIGIN"
      X-Content-Type-Options: "nosniff"
      X-XSS-Protection: "1; mode=block"
      Content-Security-Policy: "default-src 'self'"
      Referrer-Policy: "strict-origin-when-cross-origin"
      Permissions-Policy: "geolocation=(), microphone=(), camera=()"

    # SSL Headers
    stsSeconds: 63072000
    stsIncludeSubdomains: true
    stsPreload: true
    forceSTSHeader: true

    # CORS headers
    accessControlAllowMethods:
      - "GET"
      - "POST"
      - "PUT"
      - "DELETE"
      - "OPTIONS"
    accessControlAllowOriginList:
      - "https://app.example.com"
      - "https://dashboard.example.com"
    accessControlAllowCredentials: true
    accessControlMaxAge: 100

    # Remove headers
    customRequestHeadersRemove:
      - "X-Powered-By"
      - "Server"

---
# URL rewriting middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: url-rewrite
spec:
  replacePathRegex:
    regex: "^/old-api/(.*)"
    replacement: "/new-api/$1"

---
# Add prefix middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-prefix
spec:
  addPrefix:
    prefix: "/api/v1"

gRPC Routing

# gRPC service routing
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: grpc-service
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`grpc.example.com`) && Headers(`Content-Type`, `application/grpc`)
    kind: Rule
    services:
    - name: grpc-backend
      port: 50051
      scheme: h2c  # HTTP/2 cleartext
    middlewares:
    - name: grpc-headers
  tls:
    certResolver: letsencrypt

---
# gRPC specific middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: grpc-headers
spec:
  headers:
    customRequestHeaders:
      X-Request-ID: "{{uuid}}"
    customResponseHeaders:
      X-gRPC-Version: "1.0"

---
# gRPC with TLS (h2)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: grpc-service-tls
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`grpc-secure.example.com`)
    kind: Rule
    services:
    - name: grpc-backend-tls
      port: 50051
      scheme: h2  # HTTP/2 with TLS
  tls:
    certResolver: letsencrypt

WebSocket Configuration

# WebSocket routing
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: websocket-app
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`ws.example.com`)
    kind: Rule
    services:
    - name: websocket-backend
      port: 8080
    middlewares:
    - name: websocket-headers
  tls:
    certResolver: letsencrypt

---
# WebSocket headers middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: websocket-headers
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Proto: "wss"
      Connection: "upgrade"
      Upgrade: "websocket"

---
# File provider config for WebSocket
# dynamic.yml
http:
  routers:
    websocket:
      rule: "Host(`ws.example.com`) && PathPrefix(`/ws`)"
      service: websocket-service
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

  services:
    websocket-service:
      loadBalancer:
        servers:
          - url: "http://websocket-backend:8080"
        # Important: Disable buffering for WebSocket
        passHostHeader: true
        responseForwarding:
          flushInterval: "1ms"

TCP/UDP Routing

# TCP routing for databases
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: postgres-tcp
spec:
  entryPoints:
    - postgres-entry
  routes:
  - match: HostSNI(`db.example.com`)
    services:
    - name: postgres
      port: 5432
  tls:
    passthrough: true

---
# TCP routing for Redis
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis-tcp
spec:
  entryPoints:
    - redis-entry
  routes:
  - match: HostSNI(`*`)
    services:
    - name: redis
      port: 6379

---
# UDP routing for DNS
apiVersion: traefik.io/v1alpha1
kind: IngressRouteUDP
metadata:
  name: dns-udp
spec:
  entryPoints:
    - dns-udp
  routes:
  - services:
    - name: coredns
      port: 53

---
# Static config for TCP/UDP entry points
# traefik.yml
entryPoints:
  postgres-entry:
    address: ":5432"

  redis-entry:
    address: ":6379"

  dns-udp:
    address: ":53/udp"

  mysql-entry:
    address: ":3306"

Advanced Rate Limiting Strategies

# Global rate limiting
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit-global
spec:
  rateLimit:
    average: 1000
    burst: 2000
    period: 1s

---
# Per-IP rate limiting
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit-per-ip
spec:
  rateLimit:
    average: 100
    burst: 200
    period: 1s
    sourceCriterion:
      ipStrategy:
        depth: 1  # Use first IP in X-Forwarded-For

---
# API endpoint specific rate limits
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit-api-strict
spec:
  rateLimit:
    average: 10
    burst: 20
    period: 1m

---
# Rate limit with IP exclusions (use chain)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit-with-exclusions
spec:
  chain:
    middlewares:
    - name: trusted-ip-whitelist
    - name: rate-limit-general

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: trusted-ip-whitelist
spec:
  ipWhiteList:
    sourceRange:
      - "10.0.0.0/8"      # Internal network
      - "172.16.0.0/12"   # Private network
      - "192.168.0.0/16"  # Local network

Advanced Authentication Patterns

# OAuth2 Proxy for SSO
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth2-proxy
spec:
  forwardAuth:
    address: "http://oauth2-proxy.auth.svc.cluster.local:4180"
    trustForwardHeader: true
    authResponseHeaders:
      - "X-Auth-Request-User"
      - "X-Auth-Request-Email"
      - "X-Auth-Request-Access-Token"
      - "Authorization"

---
# OIDC Authentication (Keycloak)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: keycloak-auth
spec:
  forwardAuth:
    address: "http://keycloak-gatekeeper.auth.svc:3000"
    trustForwardHeader: true
    authResponseHeaders:
      - "X-Auth-Username"
      - "X-Auth-Userid"
      - "X-Auth-Email"
      - "X-Auth-Groups"

---
# Basic Auth with multiple users
apiVersion: v1
kind: Secret
metadata:
  name: auth-secret
type: Opaque
stringData:
  users: |
    admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
    user1:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
    user2:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj0

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth-multi
spec:
  basicAuth:
    secret: auth-secret
    realm: "Protected Area"
    removeHeader: true

---
# Digest authentication
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: digest-auth
spec:
  digestAuth:
    secret: digest-secret
    realm: "Secure API"
    removeHeader: false

---
# IP-based authentication bypass
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: smart-auth
spec:
  chain:
    middlewares:
    - name: internal-ip-check
    - name: oauth2-proxy

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: internal-ip-check
spec:
  ipWhiteList:
    sourceRange:
      - "10.0.0.0/8"
    # If IP is in whitelist, skip subsequent auth

Traffic Mirroring (Shadowing)

# Mirror production traffic to test environment
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror-to-test
spec:
  mirroring:
    name: production-api
    port: 8080
    mirrors:
    - name: test-api
      port: 8080
      percent: 100  # Mirror 100% of traffic
    - name: analytics-api
      port: 8080
      percent: 10   # Send 10% to analytics

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-with-mirroring
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`api.example.com`)
    kind: Rule
    services:
    - name: mirror-to-test
      kind: TraefikService
  tls:
    certResolver: letsencrypt

Multi-Cluster Setup

# Primary cluster routing
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: multi-cluster-route
  namespace: traefik
spec:
  entryPoints:
    - websecure
  routes:
  # Route to primary cluster by default
  - match: Host(`app.example.com`)
    kind: Rule
    priority: 50
    services:
    - name: app-primary
      namespace: production
      port: 8080

  # Route to secondary cluster via header
  - match: Host(`app.example.com`) && Header(`X-Cluster`, `secondary`)
    kind: Rule
    priority: 100
    services:
    - name: app-secondary
      namespace: production
      port: 8080

  # Route to DR cluster via subdomain
  - match: Host(`dr.app.example.com`)
    kind: Rule
    services:
    - name: app-dr
      namespace: production
      port: 8080

  tls:
    certResolver: letsencrypt

---
# Cross-cluster service (using external name)
apiVersion: v1
kind: Service
metadata:
  name: app-secondary
  namespace: production
spec:
  type: ExternalName
  externalName: app.cluster2.example.com
  ports:
  - port: 8080

Advanced Health Checks

# File provider: advanced health check configuration
# dynamic.yml
http:
  services:
    api-service-with-health:
      loadBalancer:
        servers:
          - url: "http://api1.example.com:8080"
          - url: "http://api2.example.com:8080"
          - url: "http://api3.example.com:8080"

        healthCheck:
          path: "/health"
          interval: "10s"
          timeout: "3s"
          scheme: "http"
          hostname: "api.example.com"
          port: 8080
          followRedirects: true
          headers:
            X-Health-Check: "true"

        # Sticky sessions
        sticky:
          cookie:
            name: "traefik_backend"
            secure: true
            httpOnly: true
            sameSite: "lax"

        # Server weights
        servers:
          - url: "http://api1.example.com:8080"
            weight: 3
          - url: "http://api2.example.com:8080"
            weight: 2
          - url: "http://api3.example.com:8080"
            weight: 1

Circuit Breaker Patterns

# Network error circuit breaker
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: circuit-breaker-network
spec:
  circuitBreaker:
    expression: "NetworkErrorRatio() > 0.30"
    checkPeriod: "10s"
    fallbackDuration: "30s"
    recoveryDuration: "10s"

---
# Response code circuit breaker
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: circuit-breaker-5xx
spec:
  circuitBreaker:
    expression: "ResponseCodeRatio(500, 600, 0, 600) > 0.25"
    checkPeriod: "10s"
    fallbackDuration: "60s"

---
# Combined circuit breaker
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: circuit-breaker-combined
spec:
  circuitBreaker:
    expression: "NetworkErrorRatio() > 0.20 || ResponseCodeRatio(500, 600, 0, 600) > 0.20"
    checkPeriod: "15s"
    fallbackDuration: "120s"

Content-Based Routing

# Route based on content type
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: content-based-routing
spec:
  entryPoints:
    - websecure
  routes:
  # JSON API requests
  - match: Host(`api.example.com`) && HeadersRegexp(`Content-Type`, `application/json`)
    kind: Rule
    priority: 100
    services:
    - name: json-api-service
      port: 8080

  # GraphQL requests
  - match: Host(`api.example.com`) && PathPrefix(`/graphql`)
    kind: Rule
    priority: 90
    services:
    - name: graphql-service
      port: 4000

  # gRPC requests
  - match: Host(`api.example.com`) && HeadersRegexp(`Content-Type`, `application/grpc`)
    kind: Rule
    priority: 85
    services:
    - name: grpc-service
      port: 50051
      scheme: h2c

  # XML/SOAP requests
  - match: Host(`api.example.com`) && HeadersRegexp(`Content-Type`, `text/xml`)
    kind: Rule
    priority: 80
    services:
    - name: soap-service
      port: 8080

  # Default REST API
  - match: Host(`api.example.com`)
    kind: Rule
    priority: 50
    services:
    - name: rest-api-service
      port: 8080

  tls:
    certResolver: letsencrypt

Retry Strategies

# Basic retry
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: retry-basic
spec:
  retry:
    attempts: 3
    initialInterval: "100ms"

---
# Aggressive retry for critical services
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: retry-aggressive
spec:
  retry:
    attempts: 5
    initialInterval: "50ms"

---
# Conservative retry for expensive operations
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: retry-conservative
spec:
  retry:
    attempts: 2
    initialInterval: "500ms"

Plugin Configuration

# Install plugin (via static config)
# traefik.yml
experimental:
  plugins:
    block-path:
      moduleName: github.com/traefik/plugin-blockpath
      version: v0.2.1

    rewrite-body:
      moduleName: github.com/traefik/plugin-rewritebody
      version: v0.3.1

    geoblock:
      moduleName: github.com/PascalMinder/geoblock
      version: v0.2.5

---
# Use block-path plugin
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: block-private-paths
spec:
  plugin:
    block-path:
      regex:
        - "^\\/\\..*$"        # Block hidden files
        - ".*\\.env$"         # Block .env files
        - ".*\\.git.*$"       # Block git files
        - ".*wp-admin.*$"     # Block WordPress admin

---
# Use rewrite-body plugin
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rewrite-api-urls
spec:
  plugin:
    rewrite-body:
      rewrites:
        - regex: "http://old-api.example.com"
          replacement: "https://new-api.example.com"
        - regex: "v1/users"
          replacement: "v2/users"

---
# Use geoblock plugin
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: geoblock-countries
spec:
  plugin:
    geoblock:
      allowedCountries:
        - US
        - CA
        - GB
        - DE
      api: "https://get.geojs.io/v1/ip/country/{ip}"
      cacheSize: 25
      forceMonthlyUpdate: true
      allowLocalRequests: true
      logLocalRequests: false

Monitoring and Observability

# Prometheus metrics with custom labels
# traefik.yml
metrics:
  prometheus:
    buckets:
      - 0.005
      - 0.01
      - 0.025
      - 0.05
      - 0.1
      - 0.25
      - 0.5
      - 1.0
      - 2.5
      - 5.0
      - 10.0
    addEntryPointsLabels: true
    addRoutersLabels: true
    addServicesLabels: true
    entryPoint: metrics
    manualRouting: true

---
# Access log with custom format
accessLog:
  filePath: "/var/log/traefik/access.log"
  format: json
  bufferingSize: 100
  filters:
    statusCodes:
      - "200"
      - "300-302"
      - "400-499"
      - "500-599"
    retryAttempts: true
    minDuration: "10ms"
  fields:
    defaultMode: keep
    names:
      ClientUsername: drop
    headers:
      defaultMode: drop
      names:
        User-Agent: keep
        Authorization: redact
        Content-Type: keep
        X-Forwarded-For: keep
        X-Real-IP: keep
        X-Request-ID: keep

---
# Jaeger tracing configuration
tracing:
  jaeger:
    samplingServerURL: "http://jaeger-agent.monitoring:5778/sampling"
    samplingType: "const"
    samplingParam: 1.0
    localAgentHostPort: "jaeger-agent.monitoring:6831"
    gen128Bit: true
    propagation: "jaeger"
    traceContextHeaderName: "uber-trace-id"
    collector:
      endpoint: "http://jaeger-collector.monitoring:14268/api/traces?format=jaeger.thrift"
      user: "traefik"
      password: "secret"

---
# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: traefik
  namespace: traefik
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: traefik
  endpoints:
  - port: metrics
    interval: 15s
    path: /metrics
    scheme: http

---
# PrometheusRule for alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: traefik-alerts
  namespace: traefik
spec:
  groups:
  - name: traefik
    interval: 30s
    rules:
    - alert: TraefikHighErrorRate
      expr: |
        sum(rate(traefik_service_requests_total{code=~"5.."}[5m])) by (service)
        /
        sum(rate(traefik_service_requests_total[5m])) by (service)
        > 0.05
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Traefik high error rate on {{ $labels.service }}"
        description: "Service {{ $labels.service }} has error rate above 5% (current: {{ $value | humanizePercentage }})"

    - alert: TraefikServiceDown
      expr: |
        up{job="traefik"} == 0
      for: 2m
      labels:
        severity: critical
      annotations:
        summary: "Traefik instance is down"
        description: "Traefik instance {{ $labels.instance }} has been down for more than 2 minutes"

    - alert: TraefikHighResponseTime
      expr: |
        histogram_quantile(0.99,
          sum(rate(traefik_service_request_duration_seconds_bucket[5m])) by (service, le)
        ) > 1
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Traefik high response time on {{ $labels.service }}"
        description: "Service {{ $labels.service }} 99th percentile response time is above 1s"

Docker Labels Configuration

# Docker Compose with Traefik labels
version: '3.8'

services:
  # Traefik itself
  traefik:
    image: traefik:v3.0
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    labels:
      # Dashboard
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"

  # Application with multiple routes
  webapp:
    image: myapp:latest
    labels:
      - "traefik.enable=true"

      # Main website
      - "traefik.http.routers.webapp.rule=Host(`example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      - "traefik.http.routers.webapp.service=webapp-svc"
      - "traefik.http.services.webapp-svc.loadbalancer.server.port=80"

      # API routes
      - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.routers.api.service=api-svc"
      - "traefik.http.routers.api.middlewares=api-ratelimit,strip-api"
      - "traefik.http.services.api-svc.loadbalancer.server.port=8080"

      # Middlewares
      - "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"
      - "traefik.http.middlewares.api-ratelimit.ratelimit.burst=50"
      - "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api"

      # HTTP to HTTPS redirect
      - "traefik.http.routers.webapp-http.rule=Host(`example.com`)"
      - "traefik.http.routers.webapp-http.entrypoints=web"
      - "traefik.http.routers.webapp-http.middlewares=redirect-https"
      - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"

  # Database with TCP routing
  postgres:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secretpass
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.postgres.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.postgres.entrypoints=postgres"
      - "traefik.tcp.routers.postgres.service=postgres-svc"
      - "traefik.tcp.services.postgres-svc.loadbalancer.server.port=5432"

Best Practices

High Availability

# Multiple replicas
deployment:
  replicas: 3

# Pod Disruption Budget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: traefik-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: traefik

Security

1. Use TLS everywhere:
   - Redirect HTTP to HTTPS
   - Use TLS 1.2+ only
   - Strong cipher suites

2. Enable security headers:
   - HSTS
   - X-Frame-Options
   - CSP headers

3. Rate limiting:
   - Protect against DDoS
   - Per-IP rate limits

4. IP whitelisting:
   - Restrict admin endpoints
   - Block known bad IPs

5. Keep Traefik updated:
   - Regular security patches
   - Monitor CVEs

Performance

1. Enable compression:
   - Reduce bandwidth
   - Faster response times

2. Use caching:
   - HTTP caching headers
   - CDN integration

3. Connection pooling:
   - Reuse backend connections
   - Reduce latency

4. Health checks:
   - Remove unhealthy backends
   - Automatic recovery

5. Optimize middleware order:
   - Most restrictive first
   - Caching before auth

Monitoring

1. Collect metrics:
   - Request rate
   - Error rate
   - Response time
   - Backend health

2. Set up alerts:
   - High error rate
   - Slow responses
   - Certificate expiration
   - Backend failures

3. Use distributed tracing:
   - Track requests across services
   - Identify bottlenecks

4. Log analysis:
   - Access patterns
   - Error trends
   - Security events

Additional Resources


Last updated: 2025-11-16