582_Traefik反向代理
一句话概述:Traefik 是云原生反向代理和负载均衡器,能自动发现 Docker 容器并配置路由,自动申请和续期 Let's Encrypt SSL 证书,无需手动配置 Nginx。
核心知识点表
| 概念 | 白话解释 |
|---|
| 反向代理 | 站在用户和服务之间的"中间人",把请求转发到正确的服务 |
| EntryPoint | Traefik 监听的端口,通常是 80(HTTP)和 443(HTTPS) |
| Router | 路由规则,根据域名/路径决定请求发到哪个服务 |
| Service | 后端的实际服务(你的应用容器) |
| Middleware | 中间件,在请求到达服务前做处理(如认证、限流、重定向) |
| Provider | 配置来源,Traefik 从 Docker/K8s/文件中自动发现服务 |
| ACME | Let's Encrypt 自动证书管理协议,免费 SSL |
安装配置
Docker Compose 基础配置
# docker-compose.yml
services:
traefik:
image: traefik:v3.7 # 最新稳定版(2026年5月)
container_name: traefik # 容器名
restart: unless-stopped # 自动重启
command:
- "--api.dashboard=true" # 启用管理面板
- "--providers.docker=true" # 启用 Docker 自动发现
- "--providers.docker.exposedbydefault=false" # 默认不暴露容器
- "--entrypoints.web.address=:80" # HTTP 入口
- "--entrypoints.websecure.address=:443" # HTTPS 入口
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" # TLS 验证
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com" # 邮箱
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" # 证书存储
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro" # Docker socket(只读)
- "./letsencrypt:/letsencrypt" # 证书持久化目录
labels:
- "traefik.enable=true" # 允许 Traefik 管理自己
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)" # 面板域名
- "traefik.http.routers.dashboard.service=api@internal" # 内置面板服务
- "traefik.http.routers.dashboard.entrypoints=websecure" # 只允许 HTTPS
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" # 自动SSL
启动 Traefik
mkdir letsencrypt # 创建证书目录
docker compose up -d # 启动
docker compose logs -f traefik # 查看日志
基本使用
用 Label 暴露应用
# 在同一个 docker-compose.yml 中添加应用:
services:
traefik:
# ... Traefik 配置同上 ...
myapp:
image: nginx:alpine # 你的应用镜像
labels:
- "traefik.enable=true" # 告诉 Traefik 管理这个容器
- "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)" # 域名规则
- "traefik.http.routers.myapp.entrypoints=websecure" # 使用 HTTPS
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt" # 自动 SSL
# Traefik 自动发现容器端口,如果有多个端口需要指定:
# - "traefik.http.services.myapp.loadbalancer.server.port=3000"
blog:
image: ghost:latest # 另一个应用
labels:
- "traefik.enable=true"
- "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
- "traefik.http.routers.blog.entrypoints=websecure"
- "traefik.http.routers.blog.tls.certresolver=letsencrypt"
HTTP 自动跳转 HTTPS
# 在 Traefik 的 command 中添加:
command:
# ... 其他配置 ...
- "--entrypoints.web.http.redirections.entryPoint.to=websecure" # HTTP → HTTPS
- "--entrypoints.web.http.redirections.entryPoint.scheme=https" # 使用 HTTPS
基于路径的路由
# 同一域名下,不同路径转发到不同服务
labels:
- "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
- "traefik.http.routers.frontend.rule=Host(`example.com`) && PathPrefix(`/`)"
高级用法
中间件(Middleware)
# 1. Basic Auth(基本认证)
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz$$hash"
# 生成密码哈希:htpasswd -nb admin your-password
- "traefik.http.routers.myapp.middlewares=auth" # 应用中间件
# 2. 限流(Rate Limiting)
labels:
- "traefik.http.middlewares.ratelimit.ratelimit.average=100" # 每秒100请求
- "traefik.http.middlewares.ratelimit.ratelimit.burst=50" # 突发50请求
- "traefik.http.routers.myapp.middlewares=ratelimit"
# 3. IP 白名单
labels:
- "traefik.http.middlewares.ipallow.ipallowlist.sourcerange=192.168.1.0/24"
- "traefik.http.routers.myapp.middlewares=ipallow"
# 4. 压缩(Compress)
labels:
- "traefik.http.middlewares.compress.compress=true"
- "traefik.http.routers.myapp.middlewares=compress"
# 5. 重定向
labels:
- "traefik.http.middlewares.redirect.redirectregex.regex=^https://old.example.com/(.*)"
- "traefik.http.middlewares.redirect.redirectregex.replacement=https://new.example.com/$${1}"
文件配置(适合静态服务)
# traefik.yml(静态配置)
entryPoints:
web:
address: ":80" # HTTP 入口
websecure:
address: ":443" # HTTPS 入口
providers:
docker:
exposedByDefault: false # 默认不暴露容器
file:
directory: /etc/traefik/dynamic # 动态配置目录
watch: true # 监听文件变化
certificatesResolvers:
letsencrypt:
acme:
email: you@example.com
storage: /letsencrypt/acme.json
tlsChallenge: {}
# /etc/traefik/dynamic/services.yml(动态配置)
http:
routers:
external-app:
rule: "Host(`app.example.com`)" # 域名规则
entryPoints: ["websecure"] # HTTPS
service: external-app # 对应的服务
tls:
certResolver: letsencrypt # SSL 证书
services:
external-app:
loadBalancer:
servers:
- url: "http://192.168.1.100:8080" # 后端服务地址
负载均衡
# 多个后端实例自动负载均衡
services:
app:
image: myapp:latest
deploy:
replicas: 3 # 启动 3 个实例
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
# Traefik 自动在 3 个实例之间做负载均衡
安全加固
# 1. Docker Socket 代理(推荐)
# 不直接暴露 Docker socket,使用 socket-proxy:
# docker-compose.yml 中添加:
services:
socket-proxy:
image: tecnativa/docker-socket-proxy # socket 代理
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: 1 # 只允许读取容器信息
SERVICES: 1
TASKS: 1
traefik:
# ...
# 把 docker.sock 换成 socket-proxy:
# - "--providers.docker.endpoint=tcp://socket-proxy:2375"
常见报错
| 报错信息 | 原因 | 解决方案 |
|---|
404 page not found | 路由规则不匹配 | 检查 Host 规则和 DNS 解析 |
SSL certificate error | ACME 验证失败 | 确保 80/443 端口可从外网访问 |
Gateway Timeout | 后端服务没响应 | 检查后端容器是否正常运行 |
Bad Gateway 502 | 后端端口配置错误 | 添加 loadbalancer.server.port 标签 |
Too many certificates | Let's Encrypt 频率限制 | 测试时用 staging CA |
No routers found | 容器未加 traefik.enable 标签 | 添加 traefik.enable=true |
速查表
# === Label 速查 ===
traefik.enable=true # 启用 Traefik 管理
traefik.http.routers.NAME.rule=Host(`domain.com`) # 域名路由
traefik.http.routers.NAME.entrypoints=websecure # HTTPS 入口
traefik.http.routers.NAME.tls.certresolver=le # SSL 证书
traefik.http.routers.NAME.middlewares=auth # 中间件
traefik.http.services.NAME.loadbalancer.server.port=3000 # 后端端口
# === 路由规则 ===
Host(`example.com`) # 匹配域名
PathPrefix(`/api`) # 匹配路径前缀
Host(`a.com`) && PathPrefix(`/v1`) # 组合规则
Headers(`X-Custom`, `value`) # 匹配请求头
# === 中间件类型 ===
basicauth # 基本认证
ratelimit # 限流
ipallowlist # IP 白名单
compress # 压缩
redirectregex # 正则重定向
stripprefix # 去除路径前缀
headers # 自定义头
同类对比
| 特性 | Traefik | Nginx | Caddy | HAProxy |
|---|
| 自动发现 | Docker/K8s原生 | 需手动配置 | 需插件 | 需手动配置 |
| 自动 SSL | 内置 ACME | 需 certbot | 内置 ACME | 需外部工具 |
| 配置方式 | Label/YAML | 配置文件 | Caddyfile | 配置文件 |
| 热重载 | 自动 | reload | 自动 | reload |
| Dashboard | 内置 | 需额外工具 | 不支持 | Stats页面 |
| K8s Ingress | 原生支持 | 需安装 | 需插件 | 需安装 |
| 学习曲线 | 中等 | 低 | 低 | 高 |
| 性能 | 优秀 | 极佳 | 良好 | 极佳 |
选型建议:Docker/K8s 环境首选 Traefik(自动发现太方便);传统服务器或追求极致性能选 Nginx;想要最简单的自动 HTTPS 选 Caddy。