TL;DR
Traefik 是现代云原生反向代理和负载均衡器,自动从 Docker、Kubernetes 等编排器发现服务。与 Nginx 不同,Traefik 通过监控基础设施动态配置——容器启动时自动通过标签路由流量。提供 Let's Encrypt 自动 HTTPS、内置中间件和实时仪表板。Traefik v3 新增 WASM 插件、OpenTelemetry 和 HTTP/3。
Key Takeaways
- Traefik 自动从 Docker、Kubernetes、Consul 等发现服务 — 无需手动更新配置
- Docker 标签直接在容器上定义路由规则
- 通过 Let's Encrypt 自动 HTTPS,支持通配符证书
- 内置中间件:速率限制、认证、IP 白名单、熔断器、请求头
- Kubernetes IngressRoute CRD 提供完整 Traefik 功能
- Traefik v3 带来 HTTP/3、OpenTelemetry、WASM 插件和性能改进
Traefik(发音 "traffic")是为云原生环境设计的开源边缘路由器和反向代理,拥有超过 53,000 GitHub 星标。核心创新是自动服务发现:监控 Docker、Kubernetes API 并动态生成路由配置。本指南涵盖从基础 Docker 设置到生产级 Kubernetes Ingress。
什么是 Traefik
Traefik 是现代 HTTP 反向代理和负载均衡器,与容器编排器原生集成。与 Nginx 手动配置不同,Traefik 直接连接基础设施 API 自动创建路由。
当 Docker 容器启动时 Traefik 立即检测并路由流量——无需重载。容器停止时移除路由。非常适合服务不断扩展的环境。
- 从 Docker、Kubernetes、Consul 等自动发现服务
- 动态配置 — 路由实时更新
- 通过 Let's Encrypt 自动 HTTPS
- 内置负载均衡:轮询、加权、粘性会话
- 丰富中间件:速率限制、认证、请求头、熔断器
- TCP/UDP 路由支持非 HTTP 协议
- 实时仪表板和 Prometheus/OpenTelemetry 指标
Traefik vs Nginx vs Caddy vs HAProxy
每个反向代理都有适合不同架构的优势。
| 特性 | Traefik | Nginx | Caddy | HAProxy |
|---|---|---|---|---|
| 自动服务发现 | 原生 | 手动 | 有限 | 手动 |
| 自动 HTTPS | 内置(ACME) | 手动 | 内置(零配置) | 手动 |
| 配置方式 | YAML/TOML + 标签 | nginx.conf | Caddyfile | haproxy.cfg |
| Docker 集成 | 优秀 | 手动 | 良好 | 手动 |
| Kubernetes | IngressRoute CRD | Ingress 控制器 | 基本 | Ingress 控制器 |
| 负载均衡 | 轮询、加权、粘性 | 轮询、加权、IP 哈希 | 轮询、随机 | 高级 |
| 中间件 | 内置(20+) | 模块 | 指令+插件 | ACL |
| 内置仪表板 | 是 | 否 | 否 | 是 |
| HTTP/3 | 实验性 | 实验性 | 原生 | 不支持 |
| 语言 | Go | C | Go | C |
安装
Traefik 可通过 Docker、Helm chart、二进制下载或包管理器部署。
Docker(最常见)
# Pull official Traefik v3 image
docker pull traefik:v3.2
# Run Traefik with Docker provider
docker run -d --name traefik \
-p 80:80 -p 443:443 -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ./traefik.yml:/etc/traefik/traefik.yml \
-v ./acme.json:/acme.json \
traefik:v3.2Kubernetes 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 \
-f traefik-values.yml二进制下载
# Download from GitHub releases (Linux amd64)
curl -LO https://github.com/traefik/traefik/releases/download/v3.2.0/traefik_v3.2.0_linux_amd64.tar.gz
tar xzf traefik_v3.2.0_linux_amd64.tar.gz
sudo mv traefik /usr/local/bin/ && traefik version
# macOS: brew install traefik
# Windows: choco install traefik核心概念:入口点、路由器、服务、中间件、提供者
Traefik 有五个核心概念协同路由流量。
# Traefik Architecture Flow:
# Internet → [Entrypoints] → [Routers] → [Middlewares] → [Services] → Backend
# [Providers] watch Docker/K8s/Consul and auto-configure the above- Entrypoints: 入口点是 Traefik 监听流量的端口(如 80、443)。
- Routers: 路由器分析请求并确定由哪个服务处理,可附加中间件。
- Services: 服务代表后端应用,定义负载均衡策略。
- Middlewares: 中间件在请求到达服务前修改请求或响应。
- Providers: 提供者是 Traefik 监控的基础设施组件(Docker、K8s、Consul、文件)。
Docker 提供者:通过标签自动发现
Traefik 连接 Docker socket,监控容器事件,根据标签自动创建路由。
# traefik.yml — static configuration
api:
dashboard: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik-public
# Docker labels for a container:
# - "traefik.enable=true"
# - "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
# - "traefik.http.routers.myapp.entrypoints=websecure"
# - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
# - "traefik.http.services.myapp.loadbalancer.server.port=3000"
# - "traefik.http.routers.myapp.middlewares=my-ratelimit,my-headers"Docker Compose 示例
Docker Compose 是运行 Traefik 最常见的方式。
Traefik HTTPS 配置
# docker-compose.yml — Traefik with automatic HTTPS
services:
traefik:
image: traefik:v3.2
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=/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json
networks:
- traefik-public
labels:
- "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\$\$xyz\$\$hash"
networks:
traefik-public:
external: true多服务栈
# docker-compose.yml — Multi-service stack with Traefik
services:
frontend:
image: node:20-alpine
networks: [traefik-public]
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`app.example.com`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
api:
image: golang:1.23-alpine
networks: [traefik-public, backend]
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=8080"
- "traefik.http.routers.api.middlewares=api-ratelimit"
- "traefik.http.middlewares.api-ratelimit.ratelimit.average=100"
db:
image: postgres:16-alpine
volumes: [db-data:/var/lib/postgresql/data]
networks: [backend] # Not exposed to Traefik
volumes:
db-data:
networks:
traefik-public:
external: true
backend:通过 Let's Encrypt 自动 HTTPS
Traefik 使用 ACME 协议自动获取和续期证书。
HTTP 挑战
# traefik.yml — HTTP challenge (most common)
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /acme.json
httpChallenge:
entryPoint: web
# IMPORTANT: touch acme.json && chmod 600 acme.jsonDNS 挑战(通配符证书)
# traefik.yml — DNS challenge (wildcard certs)
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /acme.json
dnsChallenge:
provider: cloudflare
resolvers: ["1.1.1.1:53", "8.8.8.8:53"]
# Env: CF_API_EMAIL + CF_DNS_API_TOKEN
# Label: traefik.http.routers.app.tls.domains[0].main=example.com
# Label: traefik.http.routers.app.tls.domains[0].sans=*.example.com负载均衡策略
Traefik 支持多种负载均衡策略。
# File provider — weighted load balancing + sticky sessions
http:
services:
my-service:
weighted:
services:
- name: v1
weight: 80
- name: v2
weight: 20
v1:
loadBalancer:
servers:
- url: "http://v1-app:8080"
v2:
loadBalancer:
servers:
- url: "http://v2-app:8080"
# Sticky sessions via Docker labels:
# traefik.http.services.myapp.loadbalancer.sticky.cookie=true
# traefik.http.services.myapp.loadbalancer.sticky.cookie.name=server_id中间件:速率限制、认证、请求头等
中间件在路由器和服务之间拦截修改请求/响应。
速率限制
# Rate limiting — Docker labels
- "traefik.http.middlewares.my-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.my-ratelimit.ratelimit.burst=50"
- "traefik.http.middlewares.my-ratelimit.ratelimit.period=1m"基本认证
# Basic auth: htpasswd -nb admin secure-password
# Docker label (double $$ to escape in compose):
- "traefik.http.middlewares.my-auth.basicauth.users=admin:\$\$apr1\$\$xyz\$\$hash"
# File provider:
http:
middlewares:
my-auth:
basicAuth:
users: ["admin:$apr1$xyz$hash"]
removeHeader: true安全请求头
# Security headers middleware
http:
middlewares:
secure-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true路径前缀剥离
# Strip prefix — /api/v1/* becomes /* at backend
- "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api/v1"
- "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api/v1`)"熔断器
# Circuit breaker — stop routing to failing backends
http:
middlewares:
my-cb:
circuitBreaker:
expression: "NetworkErrorRatio() > 0.30 || ResponseCodeRatio(500, 600, 0, 600) > 0.25"
checkPeriod: 10s
fallbackDuration: 30sKubernetes Ingress 控制器和 IngressRoute CRD
Traefik 支持标准 Ingress 和自有 IngressRoute CRD。
IngressRoute CRD
# Traefik IngressRoute CRD
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app-route
spec:
entryPoints: [websecure]
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
middlewares:
- name: my-ratelimit
- match: Host(`api.example.com`) && PathPrefix(`/v1`)
kind: Rule
services:
- name: my-api
port: 8080
tls:
certResolver: letsencryptMiddleware CRD
# Kubernetes Middleware CRD
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-ratelimit
spec:
rateLimit:
average: 100
burst: 50
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
spec:
headers:
stsSeconds: 31536000
frameDeny: true
contentTypeNosniff: true文件提供者
文件提供者用于非 Docker/Kubernetes 管理的外部服务路由配置。
# traefik.yml — enable file provider
providers:
file:
filename: /etc/traefik/dynamic.yml
watch: true
# dynamic.yml — external service routing
http:
routers:
external-app:
rule: "Host(`external.example.com`)"
service: external-app
entryPoints: [websecure]
tls:
certResolver: letsencrypt
services:
external-app:
loadBalancer:
servers:
- url: "http://192.168.1.100:8080"
healthCheck:
path: /health
interval: 10sTraefik 仪表板
内置仪表板实时显示路由器、服务、中间件和健康状态。生产环境务必加认证。
# Secure dashboard via Docker labels
- "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=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:\$\$apr1\$\$hash"健康检查和熔断器
Traefik 支持主动健康检查验证后端,结合熔断器提供弹性路由。
# Health checks in file provider
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://app1:8080"
- url: "http://app2:8080"
healthCheck:
path: /health
interval: 10s
timeout: 3sTCP/UDP 路由
Traefik 可路由非 HTTP 流量,适用于数据库、消息队列、DNS 等。
# TCP/UDP routing in traefik.yml + dynamic.yml
entryPoints:
postgres:
address: ":5432"
dns-udp:
address: ":53/udp"
# dynamic.yml
tcp:
routers:
postgres-route:
entryPoints: [postgres]
rule: "HostSNI(`db.example.com`)"
service: postgres-svc
tls: { passthrough: true }
services:
postgres-svc:
loadBalancer:
servers:
- address: "db-primary:5432"
udp:
routers:
dns-route:
entryPoints: [dns-udp]
service: dns-svc
services:
dns-svc:
loadBalancer:
servers:
- address: "coredns:53"Traefik v3 特性
Traefik v3(自 2024 年起稳定)相比 v2 有重大改进。
- HTTP/3 (QUIC) 支持
- 原生 OpenTelemetry 分布式追踪
- WASM 插件支持
- Kubernetes Gateway API
- 改进的连接池和 HTTP/2 后端
- 破坏性变更:入口点重命名、移除弃用选项
# Traefik v3 — HTTP/3 + OpenTelemetry
entryPoints:
websecure:
address: ":443"
http3: {}
tracing:
otlp:
grpc:
endpoint: "otel-collector:4317"
insecure: true
experimental:
plugins:
my-plugin:
moduleName: "github.com/user/traefik-plugin"
version: "v1.0.0"指标和监控
Traefik 通过 Prometheus 指标、结构化访问日志和分布式追踪提供可观测性。
# Prometheus metrics + structured access logs
metrics:
prometheus:
entryPoint: metrics
addRoutersLabels: true
addServicesLabels: true
entryPoints:
metrics:
address: ":8082"
accessLog:
filePath: "/var/log/traefik/access.log"
format: json
bufferingSize: 100
filters:
statusCodes: ["400-599"]
# Grafana: Import dashboard ID 17346 or 4475高可用设置
Docker Swarm 中将 Traefik 部署为全局服务,使用分布式证书存储。
Kubernetes 中 Helm chart 默认部署多个 Pod,通过 cert-manager 或共享存储处理证书。
# Kubernetes HA — Helm values
deployment:
replicas: 3
resources:
requests: { cpu: 200m, memory: 128Mi }
limits: { cpu: 1000m, memory: 512Mi }
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: traefik
topologyKey: kubernetes.io/hostname性能调优
高流量部署可通过调优获益。
- 增加优雅关闭超时
- 启用 HTTP/2 后端多路复用
- 配置连接保活超时
- 设置 maxIdleConnsPerHost
- 使用访问日志缓冲
- 部署在专用节点
# Performance tuning
entryPoints:
websecure:
address: ":443"
transport:
lifeCycle: { graceTimeOut: 30s }
respondingTimeouts:
readTimeout: 60s
writeTimeout: 60s
idleTimeout: 180s
serversTransport:
maxIdleConnsPerHost: 200
forwardingTimeouts:
dialTimeout: 5s
responseHeaderTimeout: 30s安全最佳实践
Traefik 位于网络边缘,安全至关重要。
- 仪表板必须加认证
- Docker socket 只读挂载或用代理
- 设置安全请求头
- TLS 1.2+ 最低版本
- 启用访问日志审计
- 公共路由启用速率限制
# TLS options — strong cipher suites
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
sniStrict: true常见模式:金丝雀、蓝绿、A/B 测试
Traefik 的加权负载均衡和中间件支持高级部署模式:金丝雀(小比例流量到新版本)、蓝绿(双环境即时切换)和 A/B 测试(基于请求头路由)。
# Canary deployment — 90% stable, 10% canary
http:
services:
my-app-canary:
weighted:
services:
- name: stable
weight: 90
- name: canary
weight: 10
stable:
loadBalancer:
servers:
- url: "http://app-v1:8080"
canary:
loadBalancer:
servers:
- url: "http://app-v2:8080"
# Blue-green — switch by changing weights to 0/100
blue-green:
weighted:
services:
- name: blue
weight: 100
- name: green
weight: 0 # Change to 100 to switch
# A/B testing — route based on headers
routers:
app-v2:
rule: "Host(`app.example.com`) && HeadersRegexp(`X-AB-Test`, `v2`)"
service: app-v2
priority: 100
app-default:
rule: "Host(`app.example.com`)"
service: app-v1
priority: 50故障排除
- 404:检查标签、Docker 网络和 Host 规则。
- 502:后端不可达,验证容器和端口。
- 证书未签发:确保端口可访问,启用 DEBUG 日志。
- 仪表板不加载:检查 api.dashboard=true。
- 中间件无效:名称区分大小写。
- Docker 标签未检测:确保 socket 访问和网络。
- 响应慢:检查后端和连接池。
- WebSocket 失败:确保 Upgrade 头未被剥离。
# Debug Traefik
log:
level: DEBUG
# docker logs -f traefik
# curl http://localhost:8080/api/rawdata | jq .
# cat acme.json | jq ".letsencrypt.Certificates"
# docker network inspect traefik-public常见问题
何时选择 Traefik 而非 Nginx?
Docker/Kubernetes 工作负载且服务频繁变更时选 Traefik。静态基础设施或需要最大性能时选 Nginx。
Traefik 可用于生产吗?
可以。数千家公司在生产中使用,v3 提供成熟的自动 HTTPS、健康检查和监控。
Traefik 如何自动 HTTPS?
使用 ACME 协议从 Let's Encrypt 获取证书,支持 HTTP 和 DNS 挑战,证书存于 acme.json 自动续期。
Traefik 能替代 HAProxy 吗?
大多数容器工作负载可以。但 HAProxy 在极端规模下提供更高级的 L4 负载均衡。
如何保护仪表板?
使用 basicAuth 或 forwardAuth 中间件,永远不要不加认证暴露仪表板。
支持 gRPC 吗?
支持,原生支持 HTTP/2 上的 gRPC 负载均衡和健康检查。
v2 和 v3 区别?
v3 新增 HTTP/3、OpenTelemetry、WASM 插件、Gateway API。包含破坏性变更。
Traefik vs Caddy?
两者都是 Go 反向代理,支持自动 HTTPS。Docker/K8s 选 Traefik,简单部署选 Caddy。