Перейти к основному содержимому
Вернуться в категорию

Traefik Reverse Proxy: современный балансировщик нагрузки для Docker и Kubernetes

Установка Traefik, автоматическое обнаружение сервисов с Docker-провайдером, SSL от Let's Encrypt, настройка middleware, dashboard, Kubernetes Ingress Controller и балансировка нагрузки.

Время чтения: 18 мин DevOps и автоматизация
traefikобратный проксибалансировщик нагрузкиdockerkubernetesssldevops

Содержание

Traefik Reverse Proxy: современный балансировщик нагрузки для Docker и Kubernetes

Traefik — современный edge router и обратный прокси, разработанный для микросервисных архитектур. Благодаря глубокой интеграции с Docker и Kubernetes он автоматически обнаруживает и маршрутизирует сервисы.

Что такое Traefik?

Ключевые особенности Traefik:

  • Автоматическое обнаружение сервисов: Автоматическая маршрутизация через метки Docker/Kubernetes
  • Интеграция с Let's Encrypt: Автоматическое управление SSL-сертификатами
  • Система middleware: Auth, ограничение скорости, перенаправление, заголовки
  • Dashboard: Интерфейс мониторинга в реальном времени
  • Несколько провайдеров: Поддержка Docker, Kubernetes, Consul, etcd
  • TCP/UDP-маршрутизация: Поддержка не-HTTP протоколов

Traefik v3 предлагает лучшую производительность и новые функции по сравнению с v2. Это руководство сосредоточено на Traefik v3.

Установка Traefik v3

Установка с Docker Compose

hljs yaml
# docker-compose.yml
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard (закрыть в production)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./config:/etc/traefik/config:ro
      - traefik_certs:/certs
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      # Dashboard
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hash"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"

volumes:
  traefik_certs:

networks:
  traefik-net:
    external: true

Конфигурация traefik.yml

hljs yaml
# traefik.yml
global:
  checkNewVersion: true
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false  # false в production

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true

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

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /certs/acme.json
      httpChallenge:
        entryPoint: web
      # DNS-challenge (для wildcard)
      # dnsChallenge:
      #   provider: cloudflare
      #   resolvers:
      #     - "1.1.1.1:53"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-net
  file:
    directory: /etc/traefik/config
    watch: true

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

accessLog:
  filePath: /var/log/traefik/access.log
  bufferingSize: 100

Автоматическая маршрутизация с Docker-провайдером

Автоматически регистрируйте сервисы в Traefik с помощью меток Docker:

hljs yaml
# Пример приложения
services:
  webapp:
    image: nginx:alpine
    networks:
      - traefik-net
    labels:
      # Включить Traefik
      - "traefik.enable=true"

      # HTTP-роутер
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"

      # Порт сервиса
      - "traefik.http.services.webapp.loadbalancer.server.port=80"

      # Применить middleware
      - "traefik.http.routers.webapp.middlewares=security-headers,rate-limit"

networks:
  traefik-net:
    external: true

Пример с несколькими сервисами

hljs yaml
services:
  api:
    image: myapi:latest
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      # Проверка работоспособности
      - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.api.loadbalancer.healthcheck.interval=30s"

  frontend:
    image: myfrontend:latest
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`example.com`) || Host(`www.example.com`)"
      - "traefik.http.routers.frontend.entrypoints=websecure"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

networks:
  traefik-net:
    external: true

Конфигурация Middleware

Статический Middleware (traefik.yml или файл конфигурации)

hljs yaml
# config/middlewares.yml
http:
  middlewares:
    # Заголовки безопасности
    security-headers:
      headers:
        stsSeconds: 31536000
        stsIncludeSubdomains: true
        stsPreload: true
        forceSTSHeader: true
        contentTypeNosniff: true
        frameDeny: true
        referrerPolicy: "strict-origin-when-cross-origin"
        customResponseHeaders:
          X-Powered-By: ""
          Server: ""

    # Ограничение скорости
    rate-limit:
      rateLimit:
        average: 100
        burst: 50
        period: 1m
        sourceCriterion:
          ipStrategy:
            depth: 1

    # Basic auth
    basic-auth:
      basicAuth:
        users:
          - "admin:$apr1$xyz$hashedpassword"
        removeHeader: true

    # Белый список IP
    ip-whitelist:
      ipAllowList:
        sourceRange:
          - "192.168.1.0/24"
          - "10.0.0.0/8"

    # Перенаправление www на non-www
    www-redirect:
      redirectRegex:
        regex: "^https://www\\.(.*)"
        replacement: "https://${1}"
        permanent: true

Dashboard

hljs yaml
# Безопасная конфигурация dashboard
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
  - "traefik.http.routers.traefik-dashboard.service=api@internal"
  - "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
  - "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
  - "traefik.http.routers.traefik-dashboard.middlewares=dashboard-auth"
  - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$xyz$$hash"

Генерация пароля basic auth:

hljs bash
# Генерация пароля с htpasswd
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g

# Или с openssl
echo "admin:$(openssl passwd -apr1 'вашпароль')" | sed -e 's/\$/\$\$/g'

Kubernetes Ingress Controller

Установка с Helm

hljs bash
# Добавить Helm-репозиторий Traefik
helm repo add traefik https://traefik.github.io/charts
helm repo update

# Установить Traefik
helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  --set deployment.replicas=2 \
  --set ports.web.redirectTo.port=websecure \
  --set ingressRoute.dashboard.enabled=true

IngressRoute (Traefik CRD)

hljs yaml
# ingressroute.yml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: webapp-ingress
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: webapp-service
          port: 80
      middlewares:
        - name: security-headers
  tls:
    certResolver: letsencrypt

Middleware CRD

hljs yaml
# middleware.yml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-headers
  namespace: default
spec:
  headers:
    stsSeconds: 31536000
    stsIncludeSubdomains: true
    contentTypeNosniff: true
    frameDeny: true

TCP/UDP-маршрутизация

hljs yaml
# traefik.yml - TCP-точка входа
entryPoints:
  mysql:
    address: ":3306"
  redis:
    address: ":6379"
hljs yaml
# config/tcp.yml
tcp:
  routers:
    mysql-router:
      entryPoints:
        - mysql
      rule: "HostSNI(`*`)"
      service: mysql-service

  services:
    mysql-service:
      loadBalancer:
        servers:
          - address: "mysql:3306"

Балансировка нагрузки

hljs yaml
# Балансировка нагрузки с несколькими экземплярами
services:
  api:
    image: myapi:latest
    deploy:
      replicas: 3
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      # Sticky sessions
      - "traefik.http.services.api.loadbalancer.sticky.cookie=true"
      - "traefik.http.services.api.loadbalancer.sticky.cookie.name=traefik_session"
      - "traefik.http.services.api.loadbalancer.sticky.cookie.secure=true"
      # Проверка работоспособности
      - "traefik.http.services.api.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.api.loadbalancer.healthcheck.interval=10s"
      - "traefik.http.services.api.loadbalancer.healthcheck.timeout=3s"

Заключение

Traefik — мощное решение обратного прокси и балансировщика нагрузки для современных микросервисных инфраструктур. Благодаря глубокой интеграции с Docker и Kubernetes, автоматическому управлению SSL и богатой экосистеме middleware, это надёжный выбор для production-окружений. Конфигурация на основе меток позволяет каждому сервису определять собственные правила маршрутизации.