Traefik Crash Course

Master the Cloud-Native Edge Router

Lesson 1: Introduction to Traefik

What is Traefik?

Traefik is a modern HTTP reverse proxy and load balancer designed for microservices. It automatically discovers services and configures itself dynamically.

Key Feature: Traefik automatically discovers the right configuration for your services through providers (Docker, Kubernetes, Consul, etc.) without manual configuration.

Why Traefik?

Feature Traefik Traditional Reverse Proxies
Configuration Automatic service discovery Manual configuration files
SSL/TLS Automatic Let's Encrypt integration Manual certificate management
Microservices Built for cloud-native Requires complex setup
Updates Zero-downtime reloads Often requires restart
Dashboard Built-in web UI Usually requires add-ons

Core Concepts

# Traefik Architecture ┌─────────────┐ │ Client │ └──────┬──────┘ │ ▼ ┌─────────────────────────────────────┐ │ Traefik (Edge Router) │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ Routers │ │ Middlewares │ │ │ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────┐ │ │ │ Services │ │ │ └────────────┬────────────────┘ │ └───────────────┼────────────────────┘ │ ┌───────┴────────┐ ▼ ▼ ┌─────────┐ ┌─────────┐ │ Backend │ │ Backend │ │ Service │ │ Service │ └─────────┘ └─────────┘

Key Components

  • EntryPoints: Network entry points (ports) where Traefik listens
  • Routers: Connect incoming requests to services based on rules
  • Services: Define how to reach actual backend services
  • Middlewares: Modify requests/responses (auth, rate limiting, etc.)
  • Providers: Infrastructure components that configure Traefik (Docker, K8s, etc.)

Basic Configuration Example

# traefik.yml - Static Configuration entryPoints: web: address: ":80" websecure: address: ":443" providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false api: dashboard: true insecure: true # Only for development!

Installation Methods

# Using Docker docker run -d \ -p 80:80 \ -p 8080:8080 \ -v /var/run/docker.sock:/var/run/docker.sock \ traefik:v3.0 # Using Docker Compose version: '3' services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock # Using Binary (Linux) 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 ./traefik --help # Using Helm (Kubernetes) helm repo add traefik https://traefik.github.io/charts helm install traefik traefik/traefik

First Service with Traefik

# docker-compose.yml version: '3' services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock whoami: image: traefik/whoami labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)" - "traefik.http.routers.whoami.entrypoints=web" # Start: docker-compose up -d # Access: http://whoami.localhost # Dashboard: http://localhost:8080
Quick Start Summary:
1. Install Traefik (Docker, Binary, or Helm)
2. Configure EntryPoints (ports)
3. Enable providers (Docker, Kubernetes)
4. Add labels to services
5. Access via domain names!

Test Your Knowledge - Lesson 1

1. What is the main advantage of Traefik over traditional reverse proxies?

2. What is an EntryPoint in Traefik?

3. Which component connects incoming requests to backend services?

Lesson 2: Routers & Services

Understanding Routers

Routers analyze incoming requests and determine which service should handle them based on rules.

Router Flow: Request → EntryPoint → Router (checks rules) → Middleware (optional) → Service → Backend

Routing Rules

# Common Routing Rules # Host-based routing Host(`example.com`) Host(`api.example.com`, `www.example.com`) # Multiple hosts # Path-based routing Path(`/api`) PathPrefix(`/admin`) # Header-based routing Headers(`Content-Type`, `application/json`) # Method-based routing Method(`GET`, `POST`) # Query parameter routing Query(`debug`, `true`) # Combining rules with operators Host(`example.com`) && Path(`/api`) Host(`example.com`) || Host(`www.example.com`) PathPrefix(`/api`) && Method(`POST`) # Complex example Host(`api.example.com`) && (PathPrefix(`/v1`) || PathPrefix(`/v2`))

Router Configuration Examples

# Docker Labels labels: # Basic router - "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)" - "traefik.http.routers.myapp.entrypoints=web" # Multiple path prefixes - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)" # Priority (higher = evaluated first) - "traefik.http.routers.specific.rule=Host(`example.com`) && Path(`/special`)" - "traefik.http.routers.specific.priority=100" - "traefik.http.routers.general.rule=Host(`example.com`)" - "traefik.http.routers.general.priority=1" # File Configuration (traefik.yml) http: routers: my-router: rule: "Host(`example.com`)" service: my-service entryPoints: - web api-router: rule: "Host(`api.example.com`) && PathPrefix(`/v1`)" service: api-service priority: 10

Services Configuration

Services define how to reach the actual backend servers and include load balancing configuration.

# Docker - Automatic Service Discovery services: myapp: image: myapp:latest labels: - "traefik.enable=true" - "traefik.http.routers.myapp.rule=Host(`myapp.localhost`)" # Service is auto-created, but can customize: - "traefik.http.services.myapp.loadbalancer.server.port=8080" # Multiple instances (automatic load balancing) api: image: api:latest deploy: replicas: 3 labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`api.localhost`)" # File Configuration - Manual Service Definition http: services: my-service: loadBalancer: servers: - url: "http://192.168.1.10:8080" - url: "http://192.168.1.11:8080" - url: "http://192.168.1.12:8080" weighted-service: weighted: services: - name: service-v1 weight: 3 - name: service-v2 weight: 1

Load Balancing

# Load Balancing Algorithms # Round Robin (default) labels: - "traefik.http.services.myapp.loadbalancer.server.port=8080" # Weighted Round Robin http: services: myservice: weighted: services: - name: app-v1 weight: 80 - name: app-v2 weight: 20 # Canary deployment # Sticky Sessions (Session Affinity) labels: - "traefik.http.services.myapp.loadbalancer.sticky.cookie=true" - "traefik.http.services.myapp.loadbalancer.sticky.cookie.name=lb_cookie" - "traefik.http.services.myapp.loadbalancer.sticky.cookie.secure=true" # Health Checks labels: - "traefik.http.services.myapp.loadbalancer.healthcheck.path=/health" - "traefik.http.services.myapp.loadbalancer.healthcheck.interval=10s" - "traefik.http.services.myapp.loadbalancer.healthcheck.timeout=3s"

Multi-Service Example

# docker-compose.yml - Complete Example version: '3' services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock frontend: image: nginx:alpine labels: - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`example.localhost`)" - "traefik.http.routers.frontend.entrypoints=web" - "traefik.http.services.frontend.loadbalancer.server.port=80" api: image: node:alpine command: node server.js labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`example.localhost`) && PathPrefix(`/api`)" - "traefik.http.routers.api.entrypoints=web" - "traefik.http.services.api.loadbalancer.server.port=3000" # Strip /api prefix before forwarding - "traefik.http.middlewares.api-strip.stripprefix.prefixes=/api" - "traefik.http.routers.api.middlewares=api-strip" admin: image: adminer:latest labels: - "traefik.enable=true" - "traefik.http.routers.admin.rule=Host(`admin.localhost`)" - "traefik.http.routers.admin.entrypoints=web" # Access: # Frontend: http://example.localhost # API: http://example.localhost/api # Admin: http://admin.localhost # Dashboard: http://localhost:8080

TCP & UDP Routing

Traefik also supports TCP and UDP routing for non-HTTP services.

# TCP Routing Example (Database) labels: - "traefik.tcp.routers.postgres.rule=HostSNI(`*`)" - "traefik.tcp.routers.postgres.entrypoints=postgres" - "traefik.tcp.services.postgres.loadbalancer.server.port=5432" # EntryPoint configuration entryPoints: postgres: address: ":5432" # UDP Routing Example (DNS) labels: - "traefik.udp.routers.dns.entrypoints=dns" - "traefik.udp.services.dns.loadbalancer.server.port=53" entryPoints: dns: address: ":53/udp"
Router Best Practices:
• Use specific rules to avoid conflicts
• Set priorities for overlapping rules
• Enable health checks for reliability
• Use sticky sessions when needed
• Test routing rules in development first

Test Your Knowledge - Lesson 2

1. What operator combines multiple routing rules with AND logic?

2. What is the default load balancing algorithm in Traefik?

3. Which rule matches requests based on the URL path?

Lesson 3: Middlewares

What are Middlewares?

Middlewares sit between the router and service, modifying requests and responses. They can add authentication, rate limiting, headers, redirects, and more.

Middleware Chain: Request → Router → Middleware 1 → Middleware 2 → Service → Response

Common Middlewares

1. BasicAuth - Authentication

# Generate password: htpasswd -nb user password # Result: user:$apr1$hash... labels: # Define middleware - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$hash..." # Apply to router - "traefik.http.routers.admin.middlewares=auth" - "traefik.http.routers.admin.rule=Host(`admin.localhost`)" # File configuration http: middlewares: my-auth: basicAuth: users: - "user:$apr1$hash..." # Or from file usersFile: "/path/to/.htpasswd"

2. StripPrefix - URL Manipulation

# Strip /api from path before forwarding labels: - "traefik.http.middlewares.api-strip.stripprefix.prefixes=/api,/v1" - "traefik.http.routers.api.middlewares=api-strip" # Request: /api/users → Backend receives: /users # Add Prefix http: middlewares: add-api-prefix: addPrefix: prefix: "/api"

3. RateLimit - Traffic Control

# Limit requests per IP labels: - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.ratelimit.ratelimit.burst=50" - "traefik.http.routers.api.middlewares=ratelimit" # File configuration http: middlewares: rate-limit: rateLimit: average: 100 # requests per second burst: 50 # burst size period: 1s

4. Headers - Security & CORS

# Security Headers labels: - "traefik.http.middlewares.security-headers.headers.frameDeny=true" - "traefik.http.middlewares.security-headers.headers.browserXssFilter=true" - "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true" - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000" # CORS Headers http: middlewares: cors: headers: accessControlAllowMethods: - GET - POST - PUT accessControlAllowOriginList: - "https://example.com" accessControlMaxAge: 100 addVaryHeader: true # Custom Headers http: middlewares: custom-headers: headers: customRequestHeaders: X-Custom: "value" customResponseHeaders: X-Powered-By: "Traefik"

5. RedirectScheme - HTTP to HTTPS

# Redirect HTTP to HTTPS labels: - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true" - "traefik.http.routers.web.middlewares=redirect-to-https" # Configuration http: middlewares: https-redirect: redirectScheme: scheme: https permanent: true port: 443 # optional

6. Compress - Response Compression

# Enable gzip compression labels: - "traefik.http.middlewares.compress.compress=true" - "traefik.http.routers.myapp.middlewares=compress" # Configuration http: middlewares: compression: compress: excludedContentTypes: - text/event-stream

7. Retry - Automatic Retries

# Retry failed requests labels: - "traefik.http.middlewares.retry.retry.attempts=3" - "traefik.http.middlewares.retry.retry.initialInterval=100ms" http: middlewares: retry: retry: attempts: 4 initialInterval: 100ms

8. CircuitBreaker - Fault Tolerance

# Stop sending requests if service is failing labels: - "traefik.http.middlewares.cb.circuitbreaker.expression=NetworkErrorRatio() > 0.30" http: middlewares: circuit-breaker: circuitBreaker: expression: "LatencyAtQuantileMS(50.0) > 100" # or expression: "NetworkErrorRatio() > 0.30" # or expression: "ResponseCodeRatio(500, 600, 0, 600) > 0.25"

Chaining Middlewares

# Apply multiple middlewares in order labels: # Define middlewares - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$..." - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.compress.compress=true" # Chain them (executed in order) - "traefik.http.routers.api.middlewares=auth,ratelimit,compress" # File configuration - Using chain http: middlewares: my-chain: chain: middlewares: - auth - rate-limit - compression - security-headers routers: api: rule: "Host(`api.example.com`)" middlewares: - my-chain

Complete Example with Multiple Middlewares

# docker-compose.yml version: '3' services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock api: image: my-api:latest labels: - "traefik.enable=true" # Router - "traefik.http.routers.api.rule=Host(`api.localhost`)" - "traefik.http.routers.api.entrypoints=web" # Strip /api prefix - "traefik.http.middlewares.api-strip.stripprefix.prefixes=/api" # Rate limiting - "traefik.http.middlewares.api-ratelimit.ratelimit.average=100" - "traefik.http.middlewares.api-ratelimit.ratelimit.burst=50" # Security headers - "traefik.http.middlewares.api-headers.headers.frameDeny=true" - "traefik.http.middlewares.api-headers.headers.browserXssFilter=true" # Compression - "traefik.http.middlewares.api-compress.compress=true" # Apply all middlewares - "traefik.http.routers.api.middlewares=api-strip,api-ratelimit,api-headers,api-compress" admin: image: admin-panel:latest labels: - "traefik.enable=true" - "traefik.http.routers.admin.rule=Host(`admin.localhost`)" # Basic auth (password: admin123) - "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$8fEqVVxP$$Yq7Qb6kP5H5x8c1Z2Y0xB1" # IP whitelist - "traefik.http.middlewares.admin-ip.ipwhitelist.sourcerange=192.168.1.0/24,127.0.0.1/32" # Chain middlewares - "traefik.http.routers.admin.middlewares=admin-auth,admin-ip"
Middleware Order Matters!
Middlewares are executed in the order they are listed. For example:
• Put authentication before rate limiting
• Put compression last (after modifications)
• Put redirects before other middlewares
Common Middleware Patterns:
• Auth + Rate Limit: Protect APIs
• StripPrefix + AddPrefix: URL rewriting
• Headers + Compress: Optimize responses
• Retry + CircuitBreaker: Improve reliability
• RedirectScheme: Force HTTPS

Test Your Knowledge - Lesson 3

1. What is the purpose of the StripPrefix middleware?

2. Which middleware redirects HTTP to HTTPS?

3. How do you apply multiple middlewares to a router?

Lesson 4: SSL/TLS & Let's Encrypt

HTTPS with Traefik

Traefik makes SSL/TLS setup incredibly simple with automatic certificate management through Let's Encrypt.

Automatic HTTPS: Traefik can automatically obtain, renew, and manage SSL certificates from Let's Encrypt with minimal configuration.

Basic HTTPS Setup

# traefik.yml - Static Configuration entryPoints: web: address: ":80" websecure: address: ":443" certificatesResolvers: letsencrypt: acme: email: your-email@example.com storage: /letsencrypt/acme.json httpChallenge: entryPoint: web # 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" - "--certificatesresolvers.letsencrypt.acme.email=your@email.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 - ./letsencrypt:/letsencrypt

Enabling HTTPS for Services

# Docker service with automatic HTTPS services: myapp: image: myapp:latest labels: - "traefik.enable=true" # HTTP router (redirect to HTTPS) - "traefik.http.routers.myapp.rule=Host(`example.com`)" - "traefik.http.routers.myapp.entrypoints=web" - "traefik.http.routers.myapp.middlewares=redirect-to-https" # HTTPS router - "traefik.http.routers.myapp-secure.rule=Host(`example.com`)" - "traefik.http.routers.myapp-secure.entrypoints=websecure" - "traefik.http.routers.myapp-secure.tls=true" - "traefik.http.routers.myapp-secure.tls.certresolver=letsencrypt" # Redirect middleware - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"

Let's Encrypt Challenge Types

1. HTTP Challenge (Most Common)

# HTTP Challenge - Port 80 must be accessible certificatesResolvers: letsencrypt: acme: email: admin@example.com storage: /letsencrypt/acme.json httpChallenge: entryPoint: web # Pros: Simple, works for most cases # Cons: Requires port 80 open

2. TLS Challenge

# TLS Challenge - Uses port 443 certificatesResolvers: letsencrypt: acme: email: admin@example.com storage: /letsencrypt/acme.json tlsChallenge: {} # Pros: Only needs port 443 # Cons: Doesn't work with wildcards

3. DNS Challenge (Wildcard Certificates)

# DNS Challenge - For wildcard certificates certificatesResolvers: letsencrypt: acme: email: admin@example.com storage: /letsencrypt/acme.json dnsChallenge: provider: cloudflare delayBeforeCheck: 0 resolvers: - "1.1.1.1:53" - "8.8.8.8:53" # Environment variables for DNS provider environment: - CF_API_EMAIL=your@email.com - CF_API_KEY=your-api-key # Wildcard certificate example labels: - "traefik.http.routers.myapp-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.myapp-secure.tls.domains[0].main=example.com" - "traefik.http.routers.myapp-secure.tls.domains[0].sans=*.example.com" # Pros: Works behind firewall, supports wildcards # Cons: Requires DNS provider API access

Self-Signed Certificates (Development)

# Generate self-signed certificate openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout cert.key -out cert.crt \ -subj "/CN=localhost" # traefik.yml tls: certificates: - certFile: /certs/cert.crt keyFile: /certs/cert.key # Docker Compose services: traefik: image: traefik:v3.0 volumes: - ./certs:/certs - ./traefik.yml:/etc/traefik/traefik.yml

Advanced TLS Configuration

# Minimum TLS Version & Cipher Suites http: routers: myapp: rule: "Host(`example.com`)" tls: options: modern tls: options: modern: minVersion: VersionTLS13 default: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # Client certificate authentication mtls: clientAuth: caFiles: - /path/to/ca.crt clientAuthType: RequireAndVerifyClientCert

HSTS (HTTP Strict Transport Security)

# Enable HSTS labels: - "traefik.http.middlewares.hsts.headers.stsSeconds=31536000" - "traefik.http.middlewares.hsts.headers.stsIncludeSubdomains=true" - "traefik.http.middlewares.hsts.headers.stsPreload=true" - "traefik.http.routers.myapp-secure.middlewares=hsts"

Complete Production Example

# docker-compose.yml - Production HTTPS Setup version: '3' services: traefik: image: traefik:v3.0 restart: unless-stopped command: # API - "--api.dashboard=true" # Providers - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" # EntryPoints - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" # Let's Encrypt - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" # Logging - "--log.level=INFO" - "--accesslog=true" ports: - "80:80" - "443:443" 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.entrypoints=websecure" - "traefik.http.routers.dashboard.tls=true" - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..." # Global HTTP to HTTPS redirect - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" - "traefik.http.routers.http-catchall.entrypoints=web" - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" app: image: myapp:latest labels: - "traefik.enable=true" - "traefik.http.routers.app.rule=Host(`app.example.com`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.tls=true" - "traefik.http.routers.app.tls.certresolver=letsencrypt" # Security headers - "traefik.http.middlewares.security.headers.frameDeny=true" - "traefik.http.middlewares.security.headers.sslRedirect=true" - "traefik.http.middlewares.security.headers.stsSeconds=31536000" - "traefik.http.middlewares.security.headers.stsIncludeSubdomains=true" - "traefik.http.routers.app.middlewares=security"
Let's Encrypt Rate Limits:
• 50 certificates per domain per week
• 5 failed validations per hour
• Use staging environment for testing!
--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
HTTPS Best Practices:
• Always redirect HTTP to HTTPS
• Enable HSTS headers
• Use TLS 1.2+ minimum
• Test with Let's Encrypt staging first
• Monitor certificate expiration
• Backup acme.json file

Test Your Knowledge - Lesson 4

1. Which Let's Encrypt challenge type supports wildcard certificates?

2. What file stores Let's Encrypt certificates in Traefik?

3. What does HSTS stand for?

Lesson 5: Docker & Kubernetes Integration

Docker Provider

Traefik automatically discovers Docker containers and configures routing based on labels.

Auto-Discovery: Traefik watches Docker events and updates configuration in real-time when containers start or stop.

Docker Provider Configuration

# Static configuration providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: web # Default network to use watch: true # Watch for Docker events # Constraints (filter containers) constraints: "Label(`traefik.enable`,`true`)" # Or via command line command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=web"

Docker Swarm Mode

# Enable Swarm provider providers: swarm: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: traefik-public # Deploy Traefik in Swarm version: '3.8' services: traefik: image: traefik:v3.0 command: - "--providers.swarm=true" - "--providers.swarm.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" ports: - target: 80 published: 80 mode: host - target: 443 published: 443 mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro deploy: mode: global placement: constraints: - node.role == manager whoami: image: traefik/whoami deploy: replicas: 3 labels: - "traefik.enable=true" - "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)" - "traefik.http.services.whoami.loadbalancer.server.port=80"

Kubernetes Integration

Traefik integrates seamlessly with Kubernetes using Ingress and IngressRoute CRDs.

Installation with Helm

# Add Traefik 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 ports.web.redirectTo.port=websecure \ --set ingressRoute.dashboard.enabled=true # Custom values.yaml # values.yaml ports: web: port: 80 redirectTo: port: websecure websecure: port: 443 tls: enabled: true ingressRoute: dashboard: enabled: true entryPoints: - websecure providers: kubernetesIngress: enabled: true kubernetesCRD: enabled: true # Install with custom values helm install traefik traefik/traefik -f values.yaml

Kubernetes Ingress (Standard)

# Standard Kubernetes 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" spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: myapp-service port: number: 80 tls: - hosts: - myapp.example.com secretName: myapp-tls

IngressRoute (Traefik CRD)

# IngressRoute - More powerful than standard Ingress apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myapp-ingress namespace: default spec: entryPoints: - websecure routes: - match: Host(`myapp.example.com`) kind: Rule services: - name: myapp-service port: 80 middlewares: - name: auth tls: certResolver: letsencrypt --- # Middleware apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: auth spec: basicAuth: secret: auth-secret --- # TLS Option apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: modern spec: minVersion: VersionTLS13

Advanced Kubernetes Example

# Complete Kubernetes deployment with Traefik # 1. Deployment apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 8080 --- # 2. Service apiVersion: v1 kind: Service metadata: name: myapp-service spec: selector: app: myapp ports: - port: 80 targetPort: 8080 --- # 3. Middleware - Rate Limiting apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: rate-limit spec: rateLimit: average: 100 burst: 50 --- # 4. Middleware - Headers apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: security-headers spec: headers: frameDeny: true browserXssFilter: true contentTypeNosniff: true stsSeconds: 31536000 --- # 5. IngressRoute apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myapp-route spec: entryPoints: - websecure routes: - match: Host(`myapp.example.com`) kind: Rule services: - name: myapp-service port: 80 middlewares: - name: rate-limit - name: security-headers tls: certResolver: letsencrypt domains: - main: myapp.example.com

Multi-Namespace Routing

# Access services across namespaces apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: cross-namespace namespace: frontend spec: entryPoints: - websecure routes: # Service in same namespace - match: Host(`app.example.com`) && PathPrefix(`/frontend`) kind: Rule services: - name: frontend-service port: 80 # Service in different namespace - match: Host(`app.example.com`) && PathPrefix(`/api`) kind: Rule services: - name: api-service namespace: backend port: 80 middlewares: - name: strip-api namespace: backend

Canary Deployments

# Weighted routing for canary deployments apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: app-weighted spec: weighted: services: - name: app-v1 port: 80 weight: 80 # 80% traffic to v1 - name: app-v2 port: 80 weight: 20 # 20% traffic to v2 (canary) --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: app-canary spec: entryPoints: - websecure routes: - match: Host(`app.example.com`) kind: Rule services: - name: app-weighted kind: TraefikService

Monitoring in Kubernetes

# Enable Prometheus metrics # values.yaml metrics: prometheus: entryPoint: metrics addEntryPointsLabels: true addServicesLabels: 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
Best Practices:
• Use IngressRoute CRDs for advanced features
• Define middlewares as separate resources
• Enable RBAC for security
• Use namespaces for organization
• Monitor with Prometheus
• Test deployments with weighted routing

Test Your Knowledge - Lesson 5

1. What does Traefik use to discover Docker containers?

2. What is the advantage of IngressRoute over standard Kubernetes Ingress?

3. How do you implement canary deployments in Traefik?

Lesson 6: Advanced Features & Best Practices

Observability & Monitoring

Traefik provides comprehensive observability through access logs, metrics, and tracing.

Access Logs

# Enable access logs accessLog: filePath: "/var/log/traefik/access.log" format: json bufferingSize: 100 filters: statusCodes: - "400-499" - "500-599" retryAttempts: true minDuration: "10ms" # Command line command: - "--accesslog=true" - "--accesslog.filepath=/var/log/access.log" - "--accesslog.format=json"

Prometheus Metrics

# Enable Prometheus metrics metrics: prometheus: entryPoint: metrics addEntryPointsLabels: true addRoutersLabels: true addServicesLabels: true buckets: - 0.1 - 0.3 - 1.2 - 5.0 entryPoints: metrics: address: ":8082" # Scrape configuration # prometheus.yml scrape_configs: - job_name: 'traefik' static_configs: - targets: ['traefik:8082']

Distributed Tracing

# Jaeger integration tracing: jaeger: samplingServerURL: "http://jaeger:5778/sampling" localAgentHostPort: "jaeger:6831" gen128Bit: true propagation: jaeger traceContextHeaderName: uber-trace-id # Zipkin integration tracing: zipkin: httpEndpoint: "http://zipkin:9411/api/v2/spans" sameSpan: true id128Bit: true

High Availability Setup

# HA with Redis for shared storage providers: redis: endpoints: - "redis-1:6379" - "redis-2:6379" - "redis-3:6379" rootKey: "traefik" username: "traefik" password: "secret" # Docker Swarm HA version: '3.8' services: traefik: image: traefik:v3.0 deploy: mode: global # One instance per node update_config: parallelism: 1 delay: 10s restart_policy: condition: on-failure ports: - target: 80 published: 80 mode: host - target: 443 published: 443 mode: host

Performance Optimization

# Connection limits entryPoints: web: address: ":80" transport: lifeCycle: requestAcceptGraceTimeout: 10s graceTimeOut: 10s respondingTimeouts: readTimeout: 60s writeTimeout: 60s idleTimeout: 180s # Connection pooling serversTransport: insecureSkipVerify: false maxIdleConnsPerHost: 200 forwardingTimeouts: dialTimeout: 30s responseHeaderTimeout: 0s idleConnTimeout: 90s # Enable HTTP/2 entryPoints: websecure: http2: maxConcurrentStreams: 250

Security Best Practices

# 1. IP Whitelisting http: middlewares: admin-whitelist: ipWhiteList: sourceRange: - "192.168.1.0/24" - "10.0.0.0/8" ipStrategy: depth: 2 # Check X-Forwarded-For headers # 2. Rate Limiting per IP http: middlewares: api-ratelimit: rateLimit: average: 100 period: 1s burst: 50 sourceCriterion: ipStrategy: depth: 1 # 3. Security Headers http: middlewares: security: headers: frameDeny: true browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true stsSeconds: 31536000 stsIncludeSubdomains: true stsPreload: true customFrameOptionsValue: "SAMEORIGIN" contentSecurityPolicy: "default-src 'self'" referrerPolicy: "strict-origin-when-cross-origin" # 4. API Key Authentication http: middlewares: apikey: plugin: apikey: header: "X-API-Key" keys: - "secret-key-1" - "secret-key-2"

Plugin System

# Install plugin (Traefik Pilot - deprecated in v3) # Use local plugins or build custom ones # Example: Custom plugin structure # plugins-local/ # myPlugin/ # myPlugin.go # myPlugin_test.go # .traefik.yml # .traefik.yml displayName: My Custom Plugin type: middleware import: github.com/user/myPlugin summary: Custom authentication plugin # Use plugin experimental: localPlugins: myPlugin: moduleName: github.com/user/myPlugin http: middlewares: my-middleware: plugin: myPlugin: option1: value1

Debugging & Troubleshooting

# Enable debug logging log: level: DEBUG filePath: "/var/log/traefik/traefik.log" format: json # Command line command: - "--log.level=DEBUG" # Common debugging commands # 1. Check Traefik API curl http://localhost:8080/api/overview # 2. Check all routers curl http://localhost:8080/api/http/routers # 3. Check services curl http://localhost:8080/api/http/services # 4. Check middlewares curl http://localhost:8080/api/http/middlewares # 5. Docker logs docker logs traefik --tail 100 -f # 6. Test routing rules curl -H "Host: example.com" http://localhost/ # 7. Validate configuration traefik healthcheck

Production Checklist

# Production Deployment Checklist ✓ Security □ HTTPS enabled with valid certificates □ HTTP to HTTPS redirect configured □ Security headers middleware applied □ API dashboard protected with authentication □ Minimum TLS version set to 1.2+ □ Strong cipher suites configured □ Rate limiting on public endpoints □ IP whitelisting for admin interfaces ✓ High Availability □ Multiple Traefik instances deployed □ Shared certificate storage configured □ Health checks enabled on all services □ Graceful shutdown configured □ Load balancing between instances ✓ Monitoring □ Access logs enabled and shipped to SIEM □ Metrics exported to Prometheus □ Alerting configured for errors □ Dashboard monitoring enabled □ Distributed tracing set up ✓ Performance □ Connection timeouts configured □ Compression enabled □ HTTP/2 enabled □ Connection pooling optimized □ Resource limits set ✓ Backup & Recovery □ Configuration backed up □ acme.json backed up regularly □ Disaster recovery plan documented □ Rollback procedure tested ✓ Documentation □ Routing rules documented □ Service discovery mechanism documented □ Runbook for common issues created □ Architecture diagram maintained

Common Patterns

# Pattern 1: Multi-tenant routing # Route based on subdomain traefik.http.routers.tenant1.rule=Host(`tenant1.example.com`) traefik.http.routers.tenant2.rule=Host(`tenant2.example.com`) # Pattern 2: API versioning traefik.http.routers.api-v1.rule=PathPrefix(`/v1`) traefik.http.routers.api-v2.rule=PathPrefix(`/v2`) # Pattern 3: Blue-Green deployment # Blue (current) traefik.http.routers.app-blue.rule=Host(`app.example.com`) traefik.http.routers.app-blue.priority=10 # Green (new version - preview) traefik.http.routers.app-green.rule=Host(`app.example.com`) && Headers(`X-Preview`, `true`) traefik.http.routers.app-green.priority=100 # Pattern 4: Geographic routing traefik.http.routers.us.rule=Host(`example.com`) && ClientIP(`1.2.3.0/24`) traefik.http.routers.eu.rule=Host(`example.com`) && ClientIP(`5.6.7.0/24`) # Pattern 5: Authentication gateway # All requests through auth service first traefik.http.routers.auth.rule=PathPrefix(`/auth`) traefik.http.routers.app.middlewares=forwardauth traefik.http.middlewares.forwardauth.forwardauth.address=http://auth-service/verify
Traefik Mastery Checklist:
✓ Understand EntryPoints, Routers, Services, Middlewares
✓ Master Docker and Kubernetes providers
✓ Configure automatic HTTPS with Let's Encrypt
✓ Apply security best practices
✓ Set up monitoring and observability
✓ Deploy in high availability mode
✓ Optimize for production workloads

Test Your Knowledge - Lesson 6

1. Which metrics system does Traefik natively support?

2. What is the recommended minimum TLS version for production?

3. Which deployment pattern routes a small percentage of traffic to a new version?