Traefik — это современный HTTP-реверс-прокси и балансировщик нагрузки, который автоматически интегрируется с вашими существующими компонентами инфраструктуры, такими как Docker, Kubernetes, Swarm и Mesos, для динамического обнаружения и маршрутизации сервисов.
Что такое Traefik?
Traefik (ранее известный как Træfik) разработан для упрощения маршрутизации входящих запросов к микросервисам. Он автоматически обнаруживает новые сервисы, контейнеры или поды, обновляет свою конфигурацию и начинает маршрутизировать трафик без необходимости ручного вмешательства или перезапуска. Основное преимущество Traefik заключается в его способности динамически адаптироваться к изменяющейся инфраструктуре, что делает его идеальным решением для облачных сред и контейнеризированных приложений.
Ключевые особенности
- Автоматическое обнаружение сервисов: Traefik подключается к API вашей оркестрационной платформы (Docker, Kubernetes, Swarm, Rancher, Mesos, Consul, Etcd) и автоматически обнаруживает запущенные сервисы, их IP-адреса и порты.
- Динамическая конфигурация: При изменении состояния сервисов (запуск, остановка, масштабирование) Traefik обновляет свои правила маршрутизации в реальном времени, не требуя перезапуска.
- Балансировка нагрузки: Встроенный балансировщик нагрузки распределяет запросы между несколькими экземплярами одного сервиса, обеспечивая высокую доступность и масштабируемость.
- SSL/TLS (Let's Encrypt): Traefik имеет встроенную поддержку Let's Encrypt, автоматически генерируя и продлевая SSL/TLS-сертификаты для ваших доменов.
- Мидлвары (Middlewares): Функциональность Traefik расширяется за счет мидлваров, которые позволяют добавлять аутентификацию, сжатие, ограничение скорости, перенаправления, изменение заголовков и другие преобразования трафика.
- Метрики и дашборд: Traefik предоставляет метрики в форматах Prometheus, Datadog, InfluxDB, а также имеет встроенный дашборд для визуального мониторинга состояния маршрутов, сервисов и мидлваров.
Основные концепции Traefik
Для понимания работы Traefik необходимо разобраться в его основных компонентах:
- EntryPoints: Точки входа, определяющие порты, которые Traefik прослушивает для входящего трафика. Например,
webдля HTTP (порт 80) иwebsecureдля HTTPS (порт 443). - Routers: Маршрутизаторы анализируют входящие запросы (по домену, пути, заголовкам) и определяют, какой сервис должен их обрабатывать. Они связывают EntryPoints с Services.
- Services: Сервисы представляют собой целевые приложения, к которым Traefik маршрутизирует трафик. Каждый сервис может иметь несколько экземпляров (бэкендов) для балансировки нагрузки.
- Middlewares: Промежуточное ПО, которое применяется к запросам между маршрутизатором и сервисом. Мидлвары выполняют такие функции, как аутентификация, ограничение скорости, модификация заголовков.
- Providers: Поставщики конфигурации (Docker, Kubernetes, file, Consul Catalog и др.) — это компоненты, которые Traefik использует для обнаружения сервисов и получения их конфигурации.
Traefik с Docker
При работе с Docker Traefik использует метки (labels) контейнеров для автоматического обнаружения и настройки маршрутизации.
Использование меток Docker
Для включения Traefik в Docker-окружение необходимо запустить сам Traefik-контейнер и настроить его провайдер Docker. Затем для каждого контейнера, который должен быть доступен через Traefik, добавляются специальные метки.
Пример docker-compose.yml для Traefik
Ниже представлен базовый docker-compose.yml для запуска Traefik и простого веб-сервиса.
version: '3.8'
services:
traefik:
image: traefik:v2.10
container_name: traefik
command:
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.email=your-email@example.com
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
- "8080:8080" # Порт для дашборда Traefik
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt # Для хранения сертификатов Let's Encrypt
labels:
# Метки для доступа к дашборду Traefik
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
- "traefik.http.routers.traefik-dashboard.middlewares=traefik-auth@docker" # Используем мидлвар для аутентификации
- "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
- "traefik.http.routers.traefik-dashboard.tls.certresolver=myresolver"
# Мидлвар для базовой HTTP-аутентификации на дашборде
- "traefik.http.middlewares.traefik-auth.basicauth.users=user:$$apr1$$XqP58w0u$$5vM5hO.T.X/oF5iT.lBq.1" # user:password (password - bcrypt хэш)
networks:
- web
whoami:
image: containous/whoami
container_name: whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
- web
networks:
web:
external: true # или создайте сеть, если она не существует
В этом примере:
* Traefik прослушивает порты 80, 443 и 8080.
* providers.docker.exposedbydefault=false отключает автоматическую маршрутизацию для всех контейнеров; сервисы должны быть явно включены меткой traefik.enable=true.
* certificatesresolvers.myresolver настраивает Let's Encrypt с использованием TLS-challenge.
* Контейнер whoami доступен по домену whoami.yourdomain.com через HTTPS.
* Дашборд Traefik доступен по домену traefik.yourdomain.com и защищен базовой HTTP-аутентификацией.
Traefik с Kubernetes
В Kubernetes Traefik обычно развертывается как Ingress Controller, используя Custom Resource Definitions (CRD) для определения правил маршрутизации.
Модель Ingress и CRD
Traefik может работать с нативным ресурсом Ingress Kubernetes, но для полного использования его возможностей рекомендуется использовать CRD, такие как IngressRoute, Middleware, TLSOption. Эти CRD предоставляют более гибкий и мощный способ настройки маршрутизации, балансировки нагрузки и обработки TLS.
Развертывание Traefik в Kubernetes
Развертывание Traefik в Kubernetes включает создание следующих ресурсов:
- Deployment: Для запуска подов Traefik.
- Service: Для доступа к Traefik извне кластера (обычно
LoadBalancerилиNodePort). - RBAC (Role-Based Access Control): Для предоставления Traefik необходимых разрешений на чтение ресурсов Kubernetes (поды, сервисы, ингрессы, CRD).
- CRD: Определение пользовательских ресурсов Traefik (
IngressRoute,Middlewareи др.).
# traefik-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
namespace: kube-system # Или другой системный неймспейс
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.10
args:
- --api.dashboard=true
- --providers.kubernetesingress
- --providers.kubernetescrd
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.email=your-email@example.com
- --certificatesresolvers.myresolver.acme.storage=/data/acme.json
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- name: dashboard
containerPort: 8080
volumeMounts:
- name: acme-storage
mountPath: /data
volumes:
- name: acme-storage
persistentVolumeClaim:
claimName: traefik-acme-pvc # PVC для хранения сертификатов
---
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
type: LoadBalancer # Или NodePort
selector:
app: traefik
ports:
- protocol: TCP
name: web
port: 80
targetPort: web
- protocol: TCP
name: websecure
port: 443
targetPort: websecure
- protocol: TCP
name: dashboard
port: 8080
targetPort: dashboard
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: traefik-acme-pvc
namespace: kube-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
Для полной установки Traefik в Kubernetes требуется больше ресурсов (ServiceAccount, ClusterRole, ClusterRoleBinding, CRD). Рекомендуется использовать официальные Helm-чарты Traefik для упрощения развертывания.
Пример IngressRoute
После развертывания Traefik и его CRD можно определять правила маршрутизации.
# my-app-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: my-app-route
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`my-app.yourdomain.com`)
kind: Rule
services:
- name: my-app-service
port: 80
tls:
certResolver: myresolver
---
apiVersion: v1
kind: Service
metadata:
name: my-app-service
namespace: default
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: containous/whoami
ports:
- containerPort: 80
Этот IngressRoute направляет HTTPS-трафик для my-app.yourdomain.com на сервис my-app-service в порту 80, используя сертификаты, полученные через myresolver.
Сравнение Traefik с другими прокси-серверами
| Критерий | Traefik | Nginx | Nginx Ingress Controller (Kubernetes) |
|---|---|---|---|
| Основной принцип | Динамический, автоматическое обнаружение | Статический, конфигурация файлами | Динамический, на основе ресурсов Ingress Kubernetes |
| Интеграция с оркестраторами | Встроенная (Docker, K8s, Swarm и др.) | Нет, требует внешней автоматизации | Встроенная с Kubernetes |
| Динамическая конфигурация | Да, без перезапусков | Нет, требует перезагрузки/перезапуска | Да, на основе изменений в Kubernetes |
| SSL/TLS (Let's Encrypt) | Встроенная автоматизация | Требует внешнего клиента (certbot) и ручной настройки | Встроенная (через cert-manager или аналоги) |
| Мидлвары | Встроенные, расширяемые | Модули, Lua-скрипты | Частично через аннотации, но менее гибко |
| Простота настройки | Высокая, особенно в Docker/K8s | Средняя, для сложных сценариев требует опыта | Средняя, зависит от сложности Ingress-ресурсов |
| Производительность | Высокая | Очень высокая | Высокая |
| Применимость | Микросервисы, облачные окружения | Монолиты, статические сайты, высоконагруженные API | Kubernetes-кластеры |
Расширенные возможности и лучшие практики
Настройка SSL/TLS с Let's Encrypt
Traefik упрощает получение и обновление SSL/TLS-сертификатов. Для этого необходимо указать certificatesresolvers, например, с помощью acme.tlschallenge или acme.httpchallenge.
Пример конфигурации ACME с TLS Challenge:
# traefik.yml (статическая конфигурация)
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
api:
dashboard: true
providers:
docker:
exposedByDefault: false
network: web # Указываем сеть Docker
file:
filename: /etc/traefik/dynamic_conf.yml # Для динамической конфигурации через файл
watch: true
certificatesResolvers:
myresolver:
acme:
email: your-email@example.com
storage: /etc/traefik/acme.json
tlsChallenge: {}
# httpChallenge:
# entryPoint: web # Для HTTP Challenge требуется EntryPoint web
Использование мидлваров
Мидлвары позволяют модифицировать запросы и ответы. Их можно прикреплять к маршрутизаторам.
Пример BasicAuth
Для защиты дашборда Traefik или любого другого сервиса можно использовать мидлвар basicAuth.
# В docker-compose.yml или dynamic_conf.yml
# В Docker labels:
# - "traefik.http.middlewares.my-auth.basicauth.users=test:$$apr1$$H6usA//v$$p0f6gKz6w/b21eGf0C5wL." # user:password (password - хэш)
# - "traefik.http.routers.my-app.middlewares=my-auth@docker"
# В Kubernetes IngressRoute/Middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-auth
namespace: default
spec:
basicAuth:
users:
- "test:$apr1$H6usA//v$p0f6gKz6w/b21eGf0C5wL." # user:password
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: protected-app-route
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`protected.yourdomain.com`)
kind: Rule
services:
- name: protected-app-service
port: 80
middlewares:
- name: test-auth@kubernetescrd # Ссылка на мидлвар
tls:
certResolver: myresolver
Генерация bcrypt-хэша для пароля может быть выполнена с помощью утилиты htpasswd (htpasswd -nb user password).
Пример RateLimit
Ограничение скорости запросов для предотвращения атак или перегрузки сервиса:
# В Docker labels:
# - "traefik.http.middlewares.my-ratelimit.ratelimit.average=100" # 100 запросов в секунду
# - "traefik.http.middlewares.my-ratelimit.ratelimit.burst=50" # Максимальный "всплеск"
# - "traefik.http.routers.my-app.middlewares=my-ratelimit@docker"
# В Kubernetes IngressRoute/Middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ratelimit
namespace: default
spec:
rateLimit:
average: 100
burst: 50
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ratelimited-app-route
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`ratelimited.yourdomain.com`)
kind: Rule
services:
- name: ratelimited-app-service
port: 80
middlewares:
- name: test-ratelimit@kubernetescrd
tls:
certResolver: myresolver
Доступ к дашборду Traefik
Дашборд Traefik (порт 8080 по умолчанию) предоставляет обзор текущей конфигурации, маршрутов, сервисов и мидлваров. Доступ к дашборду рекомендуется защищать, как показано в примере Docker Compose, с помощью BasicAuth или других методов аутентификации.
Интеграция с Prometheus
Для мониторинга Traefik может экспортировать метрики в формате Prometheus. Это включается в статической конфигурации:
# traefik.yml
metrics:
prometheus:
entryPoint: metrics # Отдельный EntryPoint для метрик
addEntryPointsLabels: true
addServicesLabels: true
Затем в Kubernetes или Docker Compose необходимо создать отдельный EntryPoint для метрик (например, на порту 9000) и настроить Prometheus для сбора данных с этого EntryPoint.